public function testIsExtending() { $this->assertTrue(Debugger::isExtending(new Exception(), 'Exception')); $this->assertTrue(Debugger::isExtending('MD\\Foundation\\Exceptions\\Exception', 'Exception')); $this->assertTrue(Debugger::isExtending(new Collection(), 'MD\\Foundation\\Tests\\TestFixtures\\Collection', true)); $this->assertTrue(Debugger::isExtending('MD\\Foundation\\Tests\\TestFixtures\\Collection', 'MD\\Foundation\\Tests\\TestFixtures\\Collection', true)); $this->assertFalse(Debugger::isExtending(new Collection(), 'MD\\Foundation\\Tests\\TestFixtures\\Collection')); $this->assertFalse(Debugger::isExtending('MD\\Foundation\\Tests\\TestFixtures\\Collection', 'MD\\Foundation\\Tests\\TestFixtures\\Collection')); $this->assertFalse(Debugger::isExtending(new Collection(), 'Countable')); }
/** * When the found controller method wants to have the request injected, * this method will do it. * * @param ControllerWillRespond $event Event triggered before execution of controller. */ public function injectRequest(ControllerWillRespond $event) { $route = $this->router->getRoute($event->getControllerName()); // find the method's meta data $methods = $route->getMethods(); $i = ArrayUtils::search($methods, 'method', $event->getMethod()); if ($i === false) { return; } $method = $methods[$i]; $arguments = $event->getArguments(); foreach ($method['params'] as $i => $param) { if ($param['class'] && Debugger::isExtending($param['class'], Request::class, true) && !$arguments[$i] instanceof Request) { $arguments[$i] = $this->request; } } $event->setArguments($arguments); }
/** * Registers a command. * * @param string $name Name of the command. * @param string $commandClass Class name of the command. */ public function addCommand($name, $commandClass) { // must extend AbstractCommand $abstractCommandClass = AbstractCommand::class; if (!Debugger::isExtending($commandClass, $abstractCommandClass)) { throw new InvalidCommandException('Command "' . $commandClass . '" must extend "' . $abstractCommandClass . '".'); } // name cannot be empty $name = trim($name); if (empty($name)) { throw new InvalidArgumentException('Command name cannot be empty for "' . $commandClass . '"!'); } // configure the command $console = $this; $consoleCommand = new ConsoleCommand($name); $consoleCommand->setDescription($commandClass::getDescription()); $consoleCommand->setHelp($commandClass::getHelp()); $consoleCommand->setCode(function (InputInterface $input, OutputInterface $output) use($console, $name) { $console->exec($name, $input, $output); }); // read some meta info about the command $commandReflection = new \ReflectionClass($commandClass); $arguments = array(); $argumentsDescriptions = $commandClass::getArguments(); try { $methodReflection = $commandReflection->getMethod('execute'); if (!$methodReflection->isPublic() || $methodReflection->isStatic()) { throw new InvalidCommandException('The "execute()" method for ommand "' . $commandClass . '" must be public and non-static.'); } // get the execute() method's arguments so we can translate them to CLI arguments $parametersReflection = $methodReflection->getParameters(); foreach ($parametersReflection as $param) { $optional = $param->isDefaultValueAvailable(); $paramName = $param->getName(); $arguments[] = array('name' => $paramName, 'optional' => $optional, 'default' => $optional ? $param->getDefaultValue() : null, 'description' => isset($argumentsDescriptions[$paramName]) ? $argumentsDescriptions[$paramName] : ''); } } catch (\ReflectionException $e) { throw new InvalidCommandException('Command "' . $commandClass . '" must implement public function "execute()"!'); } foreach ($arguments as $argument) { $consoleCommand->addArgument($argument['name'], $argument['optional'] ? InputArgument::OPTIONAL : InputArgument::REQUIRED, $argument['description'], $argument['default']); } // also register command's options $options = $commandClass::getOptions(); foreach ($options as $option => $optionInfo) { $value = isset($optionInfo['required']) && $optionInfo['required'] ? InputOption::VALUE_REQUIRED : (!isset($optionInfo['default']) || empty($optionInfo['default']) || $optionInfo['default'] === null ? InputOption::VALUE_NONE : InputOption::VALUE_OPTIONAL); $consoleCommand->addOption($option, isset($optionInfo['shortcut']) ? $optionInfo['shortcut'] : null, $value, isset($optionInfo['description']) ? $optionInfo['description'] : '', $value === InputOption::VALUE_REQUIRED || $value === InputOption::VALUE_NONE ? null : (isset($optionInfo['default']) ? $optionInfo['default'] : null)); } // register the command $this->commands[$name] = array('name' => $name, 'class' => $commandClass, 'command' => $consoleCommand, 'arguments' => $arguments, 'options' => $options); $this->consoleApplication->add($consoleCommand); }
/** * Attempts to find and verify a repository class for the given object class. * * @param string $objectClass Object class. * @param string $repositoryClass [optional] Suggested repository class, if any. * * @return string */ protected function findRepositoryClass($objectClass, $repositoryClass = null) { // figure out a repository class if none given if ($repositoryClass === null) { $repositoryClass = $objectClass . 'Repository'; if (!class_exists($repositoryClass)) { // return already and don't bother checking, as we know it return Repository::class; } } // verify the repository class if (!Debugger::isExtending($repositoryClass, Repository::class, true)) { throw new \RuntimeException(sprintf('An object repository class must extend %s, but %s given.', Repository::class, $repositoryClass)); } return $repositoryClass; }