/**
  * Constructor.
  * 
  * @param string  $message  [optional] Exception message. Leave empty to autogenerate a message. Default: `""`.
  * @param integer $code     [optional] Exception code. Default: `0`.
  * @param Exception $previous [optional] Previous exception. Default: `null`.
  */
 public function __construct($message = '', $code = 0, Base_Exception $previous = null)
 {
     if (empty($message)) {
         $trace = Debugger::getPrettyTrace(debug_backtrace());
         if (isset($trace[1])) {
             $message = 'Function "' . $trace[1]['function'] . '" defined in "' . $trace[1]['file'] . '" has not been fully implemented yet.';
         }
     }
     parent::__construct($message, $code, $previous);
 }
 /**
  * Constructor.
  * 
  * @param string $expected Expected type.
  * @param mixed $actual Actual argument given.
  * @param int $number [optional] Argument number.
  * @param bool $hideCaller [optional] Should the function that has thrown this exception be hidden? Default: `false`.
  */
 public function __construct($expected, $actual, $number = 1, $hideCaller = false)
 {
     $trace = Debugger::getPrettyTrace(debug_backtrace());
     $type = Debugger::getType($actual);
     $type = $type === 'string' ? $type . ' ("' . StringUtils::truncate($actual, 50) . '")' : $type;
     if (!$hideCaller && isset($trace[1])) {
         $message = $trace[1]['function'] . ' expected argument ' . $number . ' to be ' . $expected . ', ' . $type . ' given.';
     } else {
         $message = 'Expected argument ' . $number . ' to be ' . $expected . ', ' . $type . ' given.';
     }
     parent::__construct($message);
 }
 /**
  * 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);
 }
Beispiel #4
0
 /**
  * Returns directory where this module is located.
  * 
  * @return string
  */
 public function getModuleDir()
 {
     if ($this->moduleDir) {
         return $this->moduleDir;
     }
     $this->moduleDir = dirname(Debugger::getClassFile($this));
     return $this->moduleDir;
 }
 public function testGetPrettyTrace()
 {
     $prettyTrace = Debugger::getPrettyTrace(debug_backtrace());
     $this->assertInternalType('array', $prettyTrace);
     if (!empty($prettyTrace)) {
         foreach ($prettyTrace as $item) {
             $this->assertArrayHasKey('function', $item);
             $this->assertArrayHasKey('file', $item);
             $this->assertArrayHasKey('arguments', $item);
         }
     }
 }
Beispiel #6
0
 /**
  * Returns all paretns of a class.
  *
  * @param  string $class Class name.
  *
  * @return array
  */
 public function getClassParents($class)
 {
     $class = (string) $class;
     return Debugger::getObjectAncestors($class);
 }
Beispiel #7
0
 /**
  * Handles invoking magic methods `::findBy*` and `::findOneBy*`.
  *
  * @param string $method    Called method name.
  * @param array  $arguments Array of arguments the method was called with.
  *
  * @return array|object|null
  *
  * @throws \InvalidArgumentException If any of the arguments is invalid.
  * @throws \BadMethodCallException When couldn't resolve to a valid method.
  */
 public function __call($method, array $arguments)
 {
     if (!isset($arguments[0])) {
         throw new \InvalidArgumentException(sprintf('Missing 1st argument for method ::%s', $method));
     }
     $params = [];
     if (isset($arguments[1])) {
         if (!is_array($arguments[1])) {
             throw new \InvalidArgumentException(sprintf('2nd argument for method ::%s must be an array, %s given.', $method, Debugger::getType($arguments[1])));
         }
         $params = $arguments[1];
     }
     if (strpos($method, 'findBy') === 0) {
         $property = StringUtils::toSeparated(substr($method, 6), '_');
         return $this->find([$property => $arguments[0]], $params);
     }
     if (strpos($method, 'findOneBy') === 0) {
         $property = StringUtils::toSeparated(substr($method, 9), '_');
         return $this->findOne([$property => $arguments[0]], $params);
     }
     throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s', __CLASS__, $method));
 }
Beispiel #8
0
 /**
  * Returns the name of this kernel - its class name by default.
  *
  * @return string
  */
 public function getName()
 {
     if (!$this->name) {
         $this->name = Debugger::getClass($this, true);
     }
     return $this->name;
 }
 /**
  * Parses arguments of a method call.
  *
  * @param  array  $arguments Arguments.
  *
  * @return array
  */
 private function parseCallArguments(array $arguments)
 {
     $args = [];
     foreach ($arguments as $argument) {
         if (is_object($argument)) {
             $args[] = '<comment>(object)</comment> ' . StringUtils::truncate(Debugger::getClass($argument), 32, '...', StringUtils::TRUNCATE_MIDDLE);
         } elseif (is_array($argument)) {
             $args[] = '<comment>(array)</comment> ' . StringUtils::truncate(json_encode($argument), 32, '...', StringUtils::TRUNCATE_MIDDLE);
         } elseif (is_string($argument)) {
             $args[] = sprintf("'%s'", StringUtils::truncate($argument, 32, '...', StringUtils::TRUNCATE_MIDDLE));
         } else {
             $args[] = $argument;
         }
     }
     return implode(', ', $args);
 }
Beispiel #10
0
 /**
  * Checks whether or not the data mapper supports the given class.
  *
  * All objects that can be managed by this data mapper MUST implement `ArraySerializableInterface`.
  *
  * @param string $class Class to be checked if it can be mapped with this data mapper.
  *
  * @return boolean
  */
 public function supports($class)
 {
     return Debugger::isImplementing($class, ArraySerializableInterface::class);
 }
Beispiel #11
0
 public function __construct($name, $object)
 {
     parent::__construct($name);
     $this->instance = $object;
     $this->class = Debugger::getType($object);
 }
Beispiel #12
0
 /**
  * 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);
 }
Beispiel #13
0
 /**
  * Returns (basic) information about all registered services.
  * 
  * @return array
  */
 public function dump()
 {
     $services = array();
     foreach ($this->services as $name => $definition) {
         $info = array('name' => $name);
         $class = $definition->getClass();
         if ($class) {
             $info['class'] = ltrim($this->parametersResolver->resolve($class), NS);
         }
         if ($definition instanceof ObjectService) {
             $info['class'] = Debugger::getClass($definition->getInstance());
         }
         $services[$name] = $info;
     }
     foreach ($this->aliases as $alias => $target) {
         $services[$alias] = array('name' => $alias, 'alias' => $this->resolveServiceName($target));
     }
     return $services;
 }
Beispiel #14
0
 /**
  * Execute the given controller.
  * 
  * @param string $name Name of the controller or route assigned to this controller.
  * @param string $class Class name of the controller.
  * @param string $method Method name to execute on the controller.
  * @param array $arguments [optional] Arguments to execute the controller with.
  * @return Response
  */
 protected function renderController($name, $class, $method, array $arguments = array(), Request $request = null)
 {
     $eventManager = $this->container->get('event_manager');
     $controller = new $class($this->container);
     $willRespondEvent = new ControllerWillRespond($name, $controller, $method, $arguments);
     $eventManager->trigger($willRespondEvent);
     $method = $willRespondEvent->getMethod();
     $arguments = $willRespondEvent->getArguments();
     $controllerResponse = new ControllerResponse(call_user_func_array(array($controller, $method), $arguments));
     $eventManager->trigger(new ControllerDidRespond($controllerResponse, $name, $controller, $method, $arguments, $request));
     $response = $controllerResponse->getResponse();
     $this->logger->debug('Executed controller: "{name}"', array('name' => $name, 'function' => $class . '::' . $method, 'arguments' => $arguments, '_timer' => $this->container->get('splot.timer')->step('Matched route')));
     // special case, if the response is a string then automatically convert it to HttpResponse
     if (is_string($response)) {
         $response = new Response($response);
     }
     if (!is_object($response) || !$response instanceof Response) {
         throw new InvalidReturnValueException('Executed controller method must return ' . Response::class . ' instance or a string, "' . Debugger::getType($response) . '" given.');
     }
     return $response;
 }
Beispiel #15
0
 /**
  * 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;
 }
Beispiel #16
0
 /**
  * Performs application and its dependency injection container configuration by loading appropriate files
  * into the config and the container from the application dir and all the modules.
  * 
  * @param  AbstractApplication $application Application to be ran.
  * @param  string              $env         [optional] Environment in which the application should be ran. Default: `dev`.
  * @param  boolean             $debug       [optional] Should application be ran in debug mode? Default: `true`.
  */
 protected function doConfigureApplication(AbstractApplication $application, $env = 'dev', $debug = true)
 {
     $container = $application->getContainer();
     // load framework parameters and services definition from YML file
     $container->loadFromFile(__DIR__ . '/framework.yml');
     // set parameters to be what the framework has been initialized with
     $container->setParameter('framework_dir', __DIR__);
     $container->setParameter('application_dir', dirname(Debugger::getClassFile($application)));
     $container->setParameter('env', $env);
     $container->setParameter('debug', $debug);
     $container->setParameter('not_debug', !$debug);
     // maybe application wants to provide some high-priority parameters as well?
     $container->loadFromArray(array('parameters' => $application->loadParameters($env, $debug)));
     // already register Whoops to handle errors, so it also works during config
     $container->get('whoops')->register();
     // we're gonna stick to the config dir defined at this point
     $configDir = rtrim($container->getParameter('config_dir'), DS);
     // prepare the config, but make it reusable in the cached container as well
     // so we're gonna modify the definition to include existing files when needed
     $configDefinition = $container->getDefinition('config');
     // doing it like this to make sure that env config file is loaded after the base
     $configFiles = array_merge(FilesystemUtils::glob($configDir . '/config.{yml,yaml,php}', GLOB_BRACE), FilesystemUtils::glob($configDir . '/config.' . $env . '.{yml,yaml,php}', GLOB_BRACE));
     foreach ($configFiles as $file) {
         $configDefinition->addMethodCall('loadFromFile', array($file));
     }
     // now that we have the config built, let's get it
     $config = $container->get('config');
     // pass some necessary parameters from the config
     $container->setParameter('log_file', $config->get('log_file'));
     $container->setParameter('log_level', $config->get('log_level'));
     // configure modules one by one
     foreach ($application->getModules() as $module) {
         $this->configureModule($module, $application, $env, $debug);
     }
     // configure the application
     $application->configure();
 }