@@ -383,15 +383,11 @@ function launch_editor_for_input( $input, $filename = 'WP-CLI' ) {
383
383
384
384
$ editor = getenv ( 'EDITOR ' );
385
385
if ( ! $ editor ) {
386
- $ editor = 'vi ' ;
387
-
388
- if ( isset ( $ _SERVER ['OS ' ] ) && false !== strpos ( $ _SERVER ['OS ' ], 'indows ' ) ) {
389
- $ editor = 'notepad ' ;
390
- }
386
+ $ editor = is_windows () ? 'notepad ' : 'vi ' ;
391
387
}
392
388
393
389
$ descriptorspec = array ( STDIN , STDOUT , STDERR );
394
- $ process = proc_open ( "$ editor " . escapeshellarg ( $ tmpfile ), $ descriptorspec , $ pipes );
390
+ $ process = proc_open_compat ( "$ editor " . escapeshellarg ( $ tmpfile ), $ descriptorspec , $ pipes );
395
391
$ r = proc_close ( $ process );
396
392
if ( $ r ) {
397
393
exit ( $ r );
@@ -453,7 +449,7 @@ function run_mysql_command( $cmd, $assoc_args, $descriptors = null ) {
453
449
454
450
$ final_cmd = force_env_on_nix_systems ( $ cmd ) . assoc_args_to_str ( $ assoc_args );
455
451
456
- $ proc = proc_open ( $ final_cmd , $ descriptors , $ pipes );
452
+ $ proc = proc_open_compat ( $ final_cmd , $ descriptors , $ pipes );
457
453
if ( ! $ proc ) {
458
454
exit ( 1 );
459
455
}
@@ -515,14 +511,15 @@ function mustache_render( $template_name, $data = array() ) {
515
511
*
516
512
* @param string $message Text to display before the progress bar.
517
513
* @param integer $count Total number of ticks to be performed.
514
+ * @param int $interval Optional. The interval in milliseconds between updates. Default 100.
518
515
* @return cli\progress\Bar|WP_CLI\NoOp
519
516
*/
520
- function make_progress_bar ( $ message , $ count ) {
517
+ function make_progress_bar ( $ message , $ count, $ interval = 100 ) {
521
518
if ( \cli \Shell::isPiped () ) {
522
519
return new \WP_CLI \NoOp ;
523
520
}
524
521
525
- return new \cli \progress \Bar ( $ message , $ count );
522
+ return new \cli \progress \Bar ( $ message , $ count, $ interval );
526
523
}
527
524
528
525
function parse_url ( $ url ) {
@@ -775,6 +772,16 @@ function trailingslashit( $string ) {
775
772
return rtrim ( $ string , '/ \\' ) . '/ ' ;
776
773
}
777
774
775
+ /**
776
+ * Convert Windows EOLs to *nix.
777
+ *
778
+ * @param string $str String to convert.
779
+ * @return string String with carriage return / newline pairs reduced to newlines.
780
+ */
781
+ function normalize_eols ( $ str ) {
782
+ return str_replace ( "\r\n" , "\n" , $ str );
783
+ }
784
+
778
785
/**
779
786
* Get the system's temp directory. Warns user if it isn't writable.
780
787
*
@@ -790,14 +797,8 @@ function get_temp_dir() {
790
797
return $ temp ;
791
798
}
792
799
793
- $ temp = '/tmp/ ' ;
794
-
795
- // `sys_get_temp_dir()` introduced PHP 5.2.1.
796
- if ( $ try = sys_get_temp_dir () ) {
797
- $ temp = trailingslashit ( $ try );
798
- } elseif ( $ try = ini_get ( 'upload_tmp_dir ' ) ) {
799
- $ temp = trailingslashit ( $ try );
800
- }
800
+ // `sys_get_temp_dir()` introduced PHP 5.2.1. Will always return something.
801
+ $ temp = trailingslashit ( sys_get_temp_dir () );
801
802
802
803
if ( ! is_writable ( $ temp ) ) {
803
804
\WP_CLI ::warning ( "Temp directory isn't writable: {$ temp }" );
@@ -1110,7 +1111,9 @@ function glob_brace( $pattern, $dummy_flags = null ) {
1110
1111
function get_suggestion ( $ target , array $ options , $ threshold = 2 ) {
1111
1112
1112
1113
$ suggestion_map = array (
1114
+ 'add ' => 'create ' ,
1113
1115
'check ' => 'check-update ' ,
1116
+ 'capability ' => 'cap ' ,
1114
1117
'clear ' => 'flush ' ,
1115
1118
'decrement ' => 'decr ' ,
1116
1119
'del ' => 'delete ' ,
@@ -1126,10 +1129,11 @@ function get_suggestion( $target, array $options, $threshold = 2 ) {
1126
1129
'regen ' => 'regenerate ' ,
1127
1130
'rep ' => 'replace ' ,
1128
1131
'repl ' => 'replace ' ,
1132
+ 'trash ' => 'delete ' ,
1129
1133
'v ' => 'version ' ,
1130
1134
);
1131
1135
1132
- if ( array_key_exists ( $ target , $ suggestion_map ) ) {
1136
+ if ( array_key_exists ( $ target , $ suggestion_map ) && in_array ( $ suggestion_map [ $ target ], $ options , true ) ) {
1133
1137
return $ suggestion_map [ $ target ];
1134
1138
}
1135
1139
@@ -1318,3 +1322,132 @@ function get_php_binary() {
1318
1322
1319
1323
return 'php ' ;
1320
1324
}
1325
+
1326
+ /**
1327
+ * Windows compatible `proc_open()`.
1328
+ * Works around bug in PHP, and also deals with *nix-like `ENV_VAR=blah cmd` environment variable prefixes.
1329
+ *
1330
+ * @access public
1331
+ *
1332
+ * @param string $command Command to execute.
1333
+ * @param array $descriptorspec Indexed array of descriptor numbers and their values.
1334
+ * @param array &$pipes Indexed array of file pointers that correspond to PHP's end of any pipes that are created.
1335
+ * @param string $cwd Initial working directory for the command.
1336
+ * @param array $env Array of environment variables.
1337
+ * @param array $other_options Array of additional options (Windows only).
1338
+ *
1339
+ * @return string Command stripped of any environment variable settings.
1340
+ */
1341
+ function proc_open_compat ( $ cmd , $ descriptorspec , &$ pipes , $ cwd = null , $ env = null , $ other_options = null ) {
1342
+ if ( is_windows () ) {
1343
+ // Need to encompass the whole command in double quotes - PHP bug https://bugs.php.net/bug.php?id=49139
1344
+ $ cmd = '" ' . _proc_open_compat_win_env ( $ cmd , $ env ) . '" ' ;
1345
+ }
1346
+ return proc_open ( $ cmd , $ descriptorspec , $ pipes , $ cwd , $ env , $ other_options );
1347
+ }
1348
+
1349
+ /**
1350
+ * For use by `proc_open_compat()` only. Separated out for ease of testing. Windows only.
1351
+ * Turns *nix-like `ENV_VAR=blah command` environment variable prefixes into stripped `cmd` with prefixed environment variables added to passed in environment array.
1352
+ *
1353
+ * @access private
1354
+ *
1355
+ * @param string $command Command to execute.
1356
+ * @param array &$env Array of existing environment variables. Will be modified if any settings in command.
1357
+ *
1358
+ * @return string Command stripped of any environment variable settings.
1359
+ */
1360
+ function _proc_open_compat_win_env ( $ cmd , &$ env ) {
1361
+ if ( false !== strpos ( $ cmd , '= ' ) ) {
1362
+ while ( preg_match ( '/^([A-Za-z_][A-Za-z0-9_]*)=("[^"]*"|[^ ]*) / ' , $ cmd , $ matches ) ) {
1363
+ $ cmd = substr ( $ cmd , strlen ( $ matches [0 ] ) );
1364
+ if ( null === $ env ) {
1365
+ $ env = array ();
1366
+ }
1367
+ $ env [ $ matches [1 ] ] = isset ( $ matches [2 ][0 ] ) && '" ' === $ matches [2 ][0 ] ? substr ( $ matches [2 ], 1 , -1 ) : $ matches [2 ];
1368
+ }
1369
+ }
1370
+ return $ cmd ;
1371
+ }
1372
+
1373
+ /**
1374
+ * First half of escaping for LIKE special characters % and _ before preparing for MySQL.
1375
+ *
1376
+ * Use this only before wpdb::prepare() or esc_sql(). Reversing the order is very bad for security.
1377
+ *
1378
+ * Copied from core "wp-includes/wp-db.php". Avoids dependency on WP 4.4 wpdb.
1379
+ *
1380
+ * @access public
1381
+ *
1382
+ * @param string $text The raw text to be escaped. The input typed by the user should have no
1383
+ * extra or deleted slashes.
1384
+ * @return string Text in the form of a LIKE phrase. The output is not SQL safe. Call $wpdb::prepare()
1385
+ * or real_escape next.
1386
+ */
1387
+ function esc_like ( $ text ) {
1388
+ return addcslashes ( $ text , '_% \\' );
1389
+ }
1390
+
1391
+ /**
1392
+ * Escapes (backticks) MySQL identifiers (aka schema object names) - i.e. column names, table names, and database/index/alias/view etc names.
1393
+ * See https://dev.mysql.com/doc/refman/5.5/en/identifiers.html
1394
+ *
1395
+ * @param string|array $idents A single identifier or an array of identifiers.
1396
+ * @return string|array An escaped string if given a string, or an array of escaped strings if given an array of strings.
1397
+ */
1398
+ function esc_sql_ident ( $ idents ) {
1399
+ $ backtick = function ( $ v ) {
1400
+ // Escape any backticks in the identifier by doubling.
1401
+ return '` ' . str_replace ( '` ' , '`` ' , $ v ) . '` ' ;
1402
+ };
1403
+ if ( is_string ( $ idents ) ) {
1404
+ return $ backtick ( $ idents );
1405
+ }
1406
+ return array_map ( $ backtick , $ idents );
1407
+ }
1408
+
1409
+ /**
1410
+ * Check whether a given string is a valid JSON representation.
1411
+ *
1412
+ * @param string $argument String to evaluate.
1413
+ * @param bool $ignore_scalars Optional. Whether to ignore scalar values.
1414
+ * Defaults to true.
1415
+ *
1416
+ * @return bool Whether the provided string is a valid JSON representation.
1417
+ */
1418
+ function is_json ( $ argument , $ ignore_scalars = true ) {
1419
+ if ( ! is_string ( $ argument ) || '' === $ argument ) {
1420
+ return false ;
1421
+ }
1422
+
1423
+ if ( $ ignore_scalars && ! in_array ( $ argument [0 ], array ( '{ ' , '[ ' ), true ) ) {
1424
+ return false ;
1425
+ }
1426
+
1427
+ json_decode ( $ argument , $ assoc = true );
1428
+
1429
+ return json_last_error () === JSON_ERROR_NONE ;
1430
+ }
1431
+
1432
+ /**
1433
+ * Parse known shell arrays included in the $assoc_args array.
1434
+ *
1435
+ * @param array $assoc_args Associative array of arguments.
1436
+ * @param array $array_arguments Array of argument keys that should receive an
1437
+ * array through the shell.
1438
+ *
1439
+ * @return array
1440
+ */
1441
+ function parse_shell_arrays ( $ assoc_args , $ array_arguments ) {
1442
+ if ( empty ( $ assoc_args ) || empty ( $ array_arguments ) ) {
1443
+ return $ assoc_args ;
1444
+ }
1445
+
1446
+ foreach ( $ array_arguments as $ key ) {
1447
+ if ( array_key_exists ( $ key , $ assoc_args ) && is_json ( $ assoc_args [ $ key ] ) ) {
1448
+ $ assoc_args [ $ key ] = json_decode ( $ assoc_args [ $ key ], $ assoc = true );
1449
+ }
1450
+ }
1451
+
1452
+ return $ assoc_args ;
1453
+ }
0 commit comments