/**
  * 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();
     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('generic', 'positional', 'assoc', 'flag'));
     });
     $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) {
         $current_prompt = $key + 1 . '/' . count($spec) . ' ';
         $default = $spec_arg['optional'] ? '' : false;
         // '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 = $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 = $this->prompt($value_prompt, $default);
                     if (false === $value) {
                         return array($args, $assoc_args);
                     }
                     $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 = $this->prompt($prompt, $default);
             if (false === $response) {
                 return array($args, $assoc_args);
             }
             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;
                 }
             }
         }
     }
     return array($args, $assoc_args);
 }
示例#2
0
 function testAllowedValueCharacters()
 {
     $r = SynopsisParser::parse('--capitals=<VALUE> --hyphen=<val-ue> --combined=<VAL-ue> --disallowed=<wrong:char>');
     $this->assertCount(4, $r);
     $param = $r[0];
     $this->assertEquals('assoc', $param['type']);
     $this->assertFalse($param['optional']);
     $param = $r[1];
     $this->assertEquals('assoc', $param['type']);
     $this->assertFalse($param['optional']);
     $param = $r[2];
     $this->assertEquals('assoc', $param['type']);
     $this->assertFalse($param['optional']);
     $this->assertEquals('unknown', $r[3]['type']);
 }
示例#3
0
 /**
  * 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)
 {
     $synopsis = $this->get_synopsis();
     if (!$synopsis) {
         return array(array(), $args, $assoc_args, $extra_args);
     }
     $validator = new \WP_CLI\SynopsisValidator($synopsis);
     $cmd_path = implode(' ', get_path($this));
     foreach ($validator->get_unknown() as $token) {
         \WP_CLI::warning(sprintf("The `%s` command has an invalid synopsis part: %s", $cmd_path, $token));
     }
     if (!$validator->enough_positionals($args)) {
         $this->show_usage();
         exit(1);
     }
     $unknown_positionals = $validator->unknown_positionals($args);
     if (!empty($unknown_positionals)) {
         \WP_CLI::error('Too many positional arguments: ' . implode(' ', $unknown_positionals));
     }
     $synopsis_spec = \WP_CLI\SynopsisParser::parse($synopsis);
     $i = 0;
     $errors = array('fatal' => array(), 'warning' => array());
     foreach ($synopsis_spec as $spec) {
         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($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++;
         } 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) {
             $errors['fatal'][] = "unknown --{$key} parameter";
         }
     }
     if (!empty($errors['fatal'])) {
         $out = 'Parameter errors:';
         foreach ($errors['fatal'] as $key => $error) {
             $out .= "\n {$error}";
             if ($desc = $this->docparser->get_param_desc($key)) {
                 $out .= " ({$desc})";
             }
         }
         \WP_CLI::error($out);
     }
     array_map('\\WP_CLI::warning', $errors['warning']);
     return array($to_unset, $args, $assoc_args, $extra_args);
 }
示例#4
0
 function testParseThenRender()
 {
     $o = '<positional> --assoc=<assoc> --<field>=<value> [--flag]';
     $a = SynopsisParser::parse($o);
     $r = SynopsisParser::render($a);
     $this->assertEquals($o, $r);
 }