/**
* Takes an array of unparsed command line arguments and options and converts it separated
* by named arguments, options and unnamed arguments.
*
* @param array $rawCommandLineArguments The unparsed command parts (such as "--foo") as an array
* @param string $controllerObjectName Object name of the designated command controller
* @param string $controllerCommandName Command name of the recognized command (ie. method name without "Command" suffix)
* @return array All and exceeding command line arguments
* @throws InvalidArgumentMixingException
*/
protected function parseRawCommandLineArguments(array $rawCommandLineArguments, $controllerObjectName, $controllerCommandName)
{
$commandLineArguments = [];
$exceedingArguments = [];
$commandMethodName = $controllerCommandName . 'Command';
$commandMethodParameters = $this->commandManager->getCommandMethodParameters($controllerObjectName, $commandMethodName);
$requiredArguments = [];
$optionalArguments = [];
$argumentNames = [];
foreach ($commandMethodParameters as $parameterName => $parameterInfo) {
$argumentNames[] = $parameterName;
if ($parameterInfo['optional'] === false) {
$requiredArguments[strtolower($parameterName)] = ['parameterName' => $parameterName, 'type' => $parameterInfo['type']];
} else {
$optionalArguments[strtolower($parameterName)] = ['parameterName' => $parameterName, 'type' => $parameterInfo['type']];
}
}
$decidedToUseNamedArguments = false;
$decidedToUseUnnamedArguments = false;
$argumentIndex = 0;
while (count($rawCommandLineArguments) > 0) {
$rawArgument = array_shift($rawCommandLineArguments);
if ($rawArgument !== '' && $rawArgument[0] === '-') {
if ($rawArgument[1] === '-') {
$rawArgument = substr($rawArgument, 2);
} else {
$rawArgument = substr($rawArgument, 1);
}
$argumentName = $this->extractArgumentNameFromCommandLinePart($rawArgument);
if (isset($optionalArguments[$argumentName])) {
$argumentValue = $this->getValueOfCurrentCommandLineOption($rawArgument, $rawCommandLineArguments, $optionalArguments[$argumentName]['type']);
$commandLineArguments[$optionalArguments[$argumentName]['parameterName']] = $argumentValue;
} elseif (isset($requiredArguments[$argumentName])) {
if ($decidedToUseUnnamedArguments) {
throw new InvalidArgumentMixingException(sprintf('Unexpected named argument "%s". If you use unnamed arguments, all required arguments must be passed without a name.', $argumentName), 1309971821);
}
$decidedToUseNamedArguments = true;
$argumentValue = $this->getValueOfCurrentCommandLineOption($rawArgument, $rawCommandLineArguments, $requiredArguments[$argumentName]['type']);
$commandLineArguments[$requiredArguments[$argumentName]['parameterName']] = $argumentValue;
unset($requiredArguments[$argumentName]);
}
} else {
if (count($requiredArguments) > 0) {
if ($decidedToUseNamedArguments) {
throw new InvalidArgumentMixingException(sprintf('Unexpected unnamed argument "%s". If you use named arguments, all required arguments must be passed named.', $rawArgument), 1309971820);
}
$argument = array_shift($requiredArguments);
$commandLineArguments[$argument['parameterName']] = $rawArgument;
$decidedToUseUnnamedArguments = true;
} else {
$exceedingArguments[] = $rawArgument;
}
}
$argumentIndex++;
}
return [$commandLineArguments, $exceedingArguments];
}