Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2040,7 +2040,7 @@ wp post create [--post_author=<post_author>] [--post_date=<post_date>] [--post_d
Array of taxonomy terms keyed by their taxonomy name. Default empty.

[--meta_input=<meta_input>]
Array of post meta values keyed by their post meta key. Default empty.
Array in JSON format of post meta values keyed by their post meta key. Default empty.

[<file>]
Read post content from <file>. If this value is present, the
Expand Down Expand Up @@ -2072,6 +2072,10 @@ wp post create [--post_author=<post_author>] [--post_date=<post_date>] [--post_d
$ wp post create ./post-content.txt --post_category=201,345 --post_title='Post from file'
Success: Created post 1922.

# Create a post with multiple meta values.
$ wp post create --post_title='A post' --post_content='Just a small post.' --meta_input='{"key1":"value1","key2":"value2"}
Success: Created post 1923.



### wp post delete
Expand Down Expand Up @@ -2106,8 +2110,8 @@ wp post delete <id>... [--force] [--defer-term-counting]

# 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.
Success: Deleted post 1268.
Success: Deleted post 1294.



Expand Down Expand Up @@ -2839,7 +2843,7 @@ wp post update <id>... [--post_author=<post_author>] [--post_date=<post_date>] [
Array of taxonomy terms keyed by their taxonomy name. Default empty.

[--meta_input=<meta_input>]
Array of post meta values keyed by their post meta key. Default empty.
Array in JSON format of post meta values keyed by their post meta key. Default empty.

[<file>]
Read post content from <file>. If this value is present, the
Expand All @@ -2859,6 +2863,10 @@ wp post update <id>... [--post_author=<post_author>] [--post_date=<post_date>] [
$ wp post update 123 --post_name=something --post_status=draft
Success: Updated post 123.

# Update a post with multiple meta values.
$ wp post update 123 --meta_input='{"key1":"value1","key2":"value2"}
Success: Updated post 123.



### wp post-type
Expand Down Expand Up @@ -4960,6 +4968,12 @@ wp user remove-cap <user> <cap>
$ wp user remove-cap 11 publish_newsletters
Success: Removed 'publish_newsletters' cap for supervisor (11).

$ wp user remove-cap 11 publish_posts
Error: The 'publish_posts' cap for supervisor (11) is inherited from a role.

$ wp user remove-cap 11 nonexistent_cap
Error: No such 'nonexistent_cap' cap for supervisor (11).



### wp user remove-role
Expand Down
59 changes: 49 additions & 10 deletions features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,9 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface {
private $running_procs = array();

/**
* Array of variables available as {VARIABLE_NAME}. Some are always set: CORE_CONFIG_SETTINGS, SRC_DIR, CACHE_DIR, WP_VERSION-version-latest. Some are step-dependent:
* RUN_DIR, SUITE_CACHE_DIR, COMPOSER_LOCAL_REPOSITORY, PHAR_PATH. Scenarios can define their own variables using "Given save" steps. Variables are reset for each scenario.
* Array of variables available as {VARIABLE_NAME}. Some are always set: CORE_CONFIG_SETTINGS, SRC_DIR, CACHE_DIR, WP_VERSION-version-latest.
* Some are step-dependent: RUN_DIR, SUITE_CACHE_DIR, COMPOSER_LOCAL_REPOSITORY, PHAR_PATH. One is set on use: INVOKE_WP_CLI_WITH_PHP_ARGS-args.
* Scenarios can define their own variables using "Given save" steps. Variables are reset for each scenario.
*/
public $variables = array();

Expand Down Expand Up @@ -117,8 +118,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' );
$vendor_dir = realpath( __DIR__ . '/../../vendor/bin' );
$path_separator = Utils\is_windows() ? ';' : ':';
$env = array(
'PATH' => $bin_dir . ':' . $vendor_dir . ':' . getenv( 'PATH' ),
'PATH' => $bin_dir . $path_separator . $vendor_dir . $path_separator . getenv( 'PATH' ),
'BEHAT_RUN' => 1,
'HOME' => sys_get_temp_dir() . '/wp-cli-home',
);
Expand Down Expand Up @@ -328,20 +330,57 @@ public function getHookDefinitionResources() {
}

/**
* Replace {VARIABLE_NAME}. Note that variable names can only contain uppercase letters and underscores (no numbers).
* Replace standard {VARIABLE_NAME} variables and the special {INVOKE_WP_CLI_WITH_PHP_ARGS-args} and {WP_VERSION-version-latest} variables.
* Note that standard variable names can only contain uppercase letters, digits and underscores and cannot begin with a digit.
*/
public function replace_variables( $str ) {
$ret = preg_replace_callback( '/\{([A-Z_]+)\}/', array( $this, '_replace_var' ), $str );
if ( false !== strpos( $str, '{INVOKE_WP_CLI_WITH_PHP_ARGS-' ) ) {
$str = $this->replace_invoke_wp_cli_with_php_args( $str );
}
$str = preg_replace_callback( '/\{([A-Z_][A-Z_0-9]*)\}/', array( $this, 'replace_var' ), $str );
if ( false !== strpos( $str, '{WP_VERSION-' ) ) {
$ret = $this->_replace_wp_versions( $ret );
$str = $this->replace_wp_versions( $str );
}
return $str;
}

/**
* Substitute {INVOKE_WP_CLI_WITH_PHP_ARGS-args} variables.
*/
private function replace_invoke_wp_cli_with_php_args( $str ) {
static $phar_path = null, $shell_path = null;

if ( null === $phar_path ) {
$phar_path = false;
$phar_begin = '#!/usr/bin/env php';
$phar_begin_len = strlen( $phar_begin );
if ( ( $bin_dir = getenv( 'WP_CLI_BIN_DIR' ) ) && file_exists( $bin_dir . '/wp' ) && $phar_begin === file_get_contents( $bin_dir . '/wp', false, null, 0, $phar_begin_len ) ) {
$phar_path = $bin_dir . '/wp';
} else {
$src_dir = dirname( dirname( __DIR__ ) );
$bin_path = $src_dir . '/bin/wp';
$vendor_bin_path = $src_dir . '/vendor/bin/wp';
if ( file_exists( $bin_path ) && is_executable( $bin_path ) ) {
$shell_path = $bin_path;
} elseif ( file_exists( $vendor_bin_path ) && is_executable( $vendor_bin_path ) ) {
$shell_path = $vendor_bin_path;
} else {
$shell_path = 'wp';
}
}
}
return $ret;

$str = preg_replace_callback( '/{INVOKE_WP_CLI_WITH_PHP_ARGS-([^}]*)}/', function ( $matches ) use ( $phar_path, $shell_path ) {
return $phar_path ? "php {$matches[1]} {$phar_path}" : ( 'WP_CLI_PHP_ARGS=' . escapeshellarg( $matches[1] ) . ' ' . $shell_path );
}, $str );

return $str;
}

/**
* Replace variables callback.
*/
private function _replace_var( $matches ) {
private function replace_var( $matches ) {
$cmd = $matches[0];

foreach ( array_slice( $matches, 1 ) as $key ) {
Expand All @@ -352,9 +391,9 @@ private function _replace_var( $matches ) {
}

/**
* Substitute "{WP_VERSION-version-latest}" variables.
* Substitute {WP_VERSION-version-latest} variables.
*/
private function _replace_wp_versions( $str ) {
private function replace_wp_versions( $str ) {
static $wp_versions = null;
if ( null === $wp_versions ) {
$wp_versions = array();
Expand Down
4 changes: 3 additions & 1 deletion features/bootstrap/Process.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace WP_CLI;

use WP_CLI\Utils;

/**
* Run a system process, and learn what happened.
*/
Expand Down Expand Up @@ -67,7 +69,7 @@ private function __construct() {}
public function run() {
$start_time = microtime( true );

$proc = proc_open( $this->command, self::$descriptors, $pipes, $this->cwd, $this->env );
$proc = Utils\proc_open_compat( $this->command, self::$descriptors, $pipes, $this->cwd, $this->env );

$stdout = stream_get_contents( $pipes[1] );
fclose( $pipes[1] );
Expand Down
Loading