@@ -87,8 +87,9 @@ class FeatureContext extends BehatContext implements ClosuredContextInterface {
8787 private $ running_procs = array ();
8888
8989 /**
90- * 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:
91- * 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.
90+ * Array of variables available as {VARIABLE_NAME}. Some are always set: CORE_CONFIG_SETTINGS, SRC_DIR, CACHE_DIR, WP_VERSION-version-latest.
91+ * 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.
92+ * Scenarios can define their own variables using "Given save" steps. Variables are reset for each scenario.
9293 */
9394 public $ variables = array ();
9495
@@ -117,8 +118,9 @@ private static function get_process_env_variables() {
117118 // Ensure we're using the expected `wp` binary
118119 $ bin_dir = getenv ( 'WP_CLI_BIN_DIR ' ) ?: realpath ( __DIR__ . '/../../bin ' );
119120 $ vendor_dir = realpath ( __DIR__ . '/../../vendor/bin ' );
121+ $ path_separator = Utils \is_windows () ? '; ' : ': ' ;
120122 $ env = array (
121- 'PATH ' => $ bin_dir . ' : ' . $ vendor_dir . ' : ' . getenv ( 'PATH ' ),
123+ 'PATH ' => $ bin_dir . $ path_separator . $ vendor_dir . $ path_separator . getenv ( 'PATH ' ),
122124 'BEHAT_RUN ' => 1 ,
123125 'HOME ' => sys_get_temp_dir () . '/wp-cli-home ' ,
124126 );
@@ -328,20 +330,57 @@ public function getHookDefinitionResources() {
328330 }
329331
330332 /**
331- * Replace {VARIABLE_NAME}. Note that variable names can only contain uppercase letters and underscores (no numbers).
333+ * Replace standard {VARIABLE_NAME} variables and the special {INVOKE_WP_CLI_WITH_PHP_ARGS-args} and {WP_VERSION-version-latest} variables.
334+ * Note that standard variable names can only contain uppercase letters, digits and underscores and cannot begin with a digit.
332335 */
333336 public function replace_variables ( $ str ) {
334- $ ret = preg_replace_callback ( '/\{([A-Z_]+)\}/ ' , array ( $ this , '_replace_var ' ), $ str );
337+ if ( false !== strpos ( $ str , '{INVOKE_WP_CLI_WITH_PHP_ARGS- ' ) ) {
338+ $ str = $ this ->replace_invoke_wp_cli_with_php_args ( $ str );
339+ }
340+ $ str = preg_replace_callback ( '/\{([A-Z_][A-Z_0-9]*)\}/ ' , array ( $ this , 'replace_var ' ), $ str );
335341 if ( false !== strpos ( $ str , '{WP_VERSION- ' ) ) {
336- $ ret = $ this ->_replace_wp_versions ( $ ret );
342+ $ str = $ this ->replace_wp_versions ( $ str );
343+ }
344+ return $ str ;
345+ }
346+
347+ /**
348+ * Substitute {INVOKE_WP_CLI_WITH_PHP_ARGS-args} variables.
349+ */
350+ private function replace_invoke_wp_cli_with_php_args ( $ str ) {
351+ static $ phar_path = null , $ shell_path = null ;
352+
353+ if ( null === $ phar_path ) {
354+ $ phar_path = false ;
355+ $ phar_begin = '#!/usr/bin/env php ' ;
356+ $ phar_begin_len = strlen ( $ phar_begin );
357+ 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 ) ) {
358+ $ phar_path = $ bin_dir . '/wp ' ;
359+ } else {
360+ $ src_dir = dirname ( dirname ( __DIR__ ) );
361+ $ bin_path = $ src_dir . '/bin/wp ' ;
362+ $ vendor_bin_path = $ src_dir . '/vendor/bin/wp ' ;
363+ if ( file_exists ( $ bin_path ) && is_executable ( $ bin_path ) ) {
364+ $ shell_path = $ bin_path ;
365+ } elseif ( file_exists ( $ vendor_bin_path ) && is_executable ( $ vendor_bin_path ) ) {
366+ $ shell_path = $ vendor_bin_path ;
367+ } else {
368+ $ shell_path = 'wp ' ;
369+ }
370+ }
337371 }
338- return $ ret ;
372+
373+ $ str = preg_replace_callback ( '/{INVOKE_WP_CLI_WITH_PHP_ARGS-([^}]*)}/ ' , function ( $ matches ) use ( $ phar_path , $ shell_path ) {
374+ return $ phar_path ? "php {$ matches [1 ]} {$ phar_path }" : ( 'WP_CLI_PHP_ARGS= ' . escapeshellarg ( $ matches [1 ] ) . ' ' . $ shell_path );
375+ }, $ str );
376+
377+ return $ str ;
339378 }
340379
341380 /**
342381 * Replace variables callback.
343382 */
344- private function _replace_var ( $ matches ) {
383+ private function replace_var ( $ matches ) {
345384 $ cmd = $ matches [0 ];
346385
347386 foreach ( array_slice ( $ matches , 1 ) as $ key ) {
@@ -352,9 +391,9 @@ private function _replace_var( $matches ) {
352391 }
353392
354393 /**
355- * Substitute " {WP_VERSION-version-latest}" variables.
394+ * Substitute {WP_VERSION-version-latest} variables.
356395 */
357- private function _replace_wp_versions ( $ str ) {
396+ private function replace_wp_versions ( $ str ) {
358397 static $ wp_versions = null ;
359398 if ( null === $ wp_versions ) {
360399 $ wp_versions = array ();
0 commit comments