/**
* Builds a CLI request object from a command line.
*
* The given command line may be a string (e.g. "mypackage:foo do-that-thing --force") or
* an array consisting of the individual parts. The array must not include the script
* name (like in $argv) but start with command right away.
*
* @param mixed $commandLine The command line, either as a string or as an array
* @return Request The CLI request as an object
* @throws InvalidArgumentMixingException
* @throws InvalidArgumentNameException
*/
public function build($commandLine)
{
$request = new Request();
$request->setControllerObjectName(HelpCommandController::class);
if (is_array($commandLine) === true) {
$rawCommandLineArguments = $commandLine;
} else {
preg_match_all(self::ARGUMENT_MATCHING_EXPRESSION, $commandLine, $commandLineMatchings, PREG_SET_ORDER);
$rawCommandLineArguments = [];
foreach ($commandLineMatchings as $match) {
if (isset($match['NoQuotes'])) {
$rawCommandLineArguments[] = str_replace(['\\ ', '\\"', "\\'", '\\\\'], [' ', '"', "'", '\\'], $match['NoQuotes']);
} elseif (isset($match['DoubleQuotes'])) {
$rawCommandLineArguments[] = str_replace('\\"', '"', $match['DoubleQuotes']);
} elseif (isset($match['SingleQuotes'])) {
$rawCommandLineArguments[] = str_replace('\\\'', '\'', $match['SingleQuotes']);
} else {
throw new InvalidArgumentNameException(sprintf('Could not parse the command line "%s" - specifically the part "%s".', $commandLine, $match[0]));
}
}
}
if (count($rawCommandLineArguments) === 0) {
$request->setControllerCommandName('helpStub');
return $request;
}
$commandIdentifier = trim(array_shift($rawCommandLineArguments));
try {
$command = $this->commandManager->getCommandByIdentifier($commandIdentifier);
} catch (CommandException $exception) {
$request->setArgument('exception', $exception);
$request->setControllerCommandName('error');
return $request;
}
$controllerObjectName = $this->objectManager->getObjectNameByClassName($command->getControllerClassName());
$controllerCommandName = $command->getControllerCommandName();
$request->setControllerObjectName($controllerObjectName);
$request->setControllerCommandName($controllerCommandName);
list($commandLineArguments, $exceedingCommandLineArguments) = $this->parseRawCommandLineArguments($rawCommandLineArguments, $controllerObjectName, $controllerCommandName);
$request->setArguments($commandLineArguments);
$request->setExceedingArguments($exceedingCommandLineArguments);
return $request;
}