*/ private array $packageHandlers = []; public function __construct( Options_Interface $defaultHandler, Options_Interface ...$packageHandlers ) { $this->defaultHandler = $defaultHandler; $this->packageHandlers = $packageHandlers; } /** * @return array */ private function handlerForOption(string $option): array { if (method_exists($this->defaultHandler, "option_{$option}")) { return [$this->defaultHandler, "option_{$option}"]; } $opt = explode('-', $option); $package = strtolower($opt[0]); if (isset($this->packageHandlers[$package])) { if (method_exists($this->packageHandlers[$package], "option_{$opt[1]}")) { return [$this->packageHandlers[$package], "option_{$opt[1]}"]; } } return []; } /** * @return array */ private function getLongOptions(): array { $defaultOptions = array_keys($this->defaultHandler->optionList()); $packageOptions = []; foreach ($this->packageHandlers as $package => $handler) { foreach ($handler->optionList() as $opt) { $packageOptions[] = $package . '-' . $opt; } } return array_merge($defaultOptions, $packageOptions); } private function getShortOptions(): string { $defaultOptions = array_values($this->defaultHandler->optionList()); $packageOptions = []; foreach ($this->packageHandlers as $handler) { foreach ($handler->optionList() as $opt) { $packageOptions[] = $opt; } } $options = array_merge($defaultOptions, $packageOptions); return implode('', array_values($options)); } /** * Checks if all options passed are valid. * * Fix Bug #54217 - Warn about nonexisting parameters */ private function validateOptions(): void { $argv = $_SERVER['argv']; $argc = $_SERVER['argc']; $short = str_split(str_replace(':', '', $this->getShortOptions())); $long = []; foreach ($this->getLongOptions() as $opt) { $long[] = str_replace(':', '', $opt); } for ($i=1; $i < $argc; $i++) { $checkArgv = explode('=', $argv[$i]); if (substr($checkArgv[0], 0, 2) === '--') { if (!in_array(substr($checkArgv[0], 2), $long)) { throw new \Error('Invalid long option ' . $argv[$i]); } } elseif (substr($checkArgv[0], 0, 1) === '-') { if (!in_array(substr($checkArgv[0], 1), $short)) { throw new \Error('Invalid short option ' . $argv[$i]); } } } } /** * @return array */ public function getopt(): array { $this->validateOptions(); $args = getopt($this->getShortOptions(), $this->getLongOptions()); if ($args === false) { throw new \Error('Something happend with getopt(), please report a bug'); } $parsedOptions = []; foreach ($args as $k => $v) { $handler = $this->handlerForOption($k); if (!is_callable($handler)) { throw new \Error("Hmh, something weird has happend, I don't know this option"); } $retVal = call_user_func($handler, $k, $v); if (is_array($retVal)) { $parsedOptions = array_merge($parsedOptions, $retVal); } } return $parsedOptions; } }