/** * @param string $type * @param \Closure $callback * @param bool $asSingleton * @param array $args * @throws \InvalidArgumentException */ public function register($type, \Closure $callback, $asSingleton = true, $args = []) { StringValidator::hasTo($type, 'type'); BooleanValidator::hasTo($asSingleton, 'asSingleton'); // remove first backslash if (strlen($type) > 0 && $type[0] == '\\') { $type = substr($type, 1); } $this->parameters[$type] = ['isSingleton' => $asSingleton, 'callback' => $callback, 'instance' => null, 'arg' => $args]; }
/** * @param string $name * @param mixed $default * @return mixed * @throws \InvalidArgumentException */ public function header($name, $default = null) { StringValidator::hasTo($name, 'name'); $name = sprintf('HTTP_%s', strtoupper($name)); $name = str_replace('-', '_', $name); if (isset($_SERVER[$name])) { return $_SERVER[$name]; } else { return $default; } }
/** * @param int $code * @param string|null $message * @param string $httpVersion * @return void * @throws \Hahns\Exception\StatusMessageCannotFindException * @throws \InvalidArgumentException */ public function status($code = Response::CODE_OK, $message = null, $httpVersion = '1.1') { IntegerValidator::hasTo($code, 'code'); StringValidator::hasToBeStringOrNull($message, 'message'); StringValidator::hasTo($httpVersion, 'httpVersion'); // get message if (is_null($message)) { $constantName = sprintf('\\Hahns\\Response::MSG_%d', $code); if (!defined($constantName)) { $message = sprintf('Status message for code `%d` cannot find', $code); throw new StatusMessageCannotFindException($message); } $message = constant($constantName); } header(sprintf('HTTP/%s %d %s', $httpVersion, $code, $message)); }
/** * @param string $name * @return object * @throws Exception\ServiceDoesNotExistException * @throws Exception\ServiceHasToBeAnObjectException * @throws \InvalidArgumentException */ public function get($name) { StringValidator::hasTo($name, 'name'); if (!isset($this->services[$name])) { $message = sprintf('Service `%s` does not exist', $name); throw new ServiceDoesNotExistException($message); } // get service $service =& $this->services[$name]; // initialize service if (!isset($service['instance'])) { $service['instance'] = call_user_func_array($service['callable'], $service['args']); if (!is_object($service['instance'])) { $message = sprintf('Service `%s` must be an object', $name); throw new ServiceHasToBeAnObjectException($message); } } return $service['instance']; }
/** * @throws \InvalidArgumentException */ public function run($route = null, $requestMethod = null) { $this->trigger(Hahns::EVENT_BEFORE_RUNNING, [$route, $this]); StringValidator::hasToBeStringOrNull($route, 'route'); StringValidator::hasToBeStringOrNull($requestMethod, 'requestMethod'); // get route if ($route !== null) { $route = $this->removeLastSlash($route); } elseif (isset($_SERVER['PATH_INFO'])) { $route = $this->removeLastSlash($_SERVER['PATH_INFO']); } else { $route = ''; } // save used route $usedRoute = $route; // get request method if (is_null($requestMethod)) { $requestMethod = $_SERVER['REQUEST_METHOD']; } // get method and concat with $route $route = strtolower($requestMethod) . '-' . $route; try { $this->trigger(Hahns::EVENT_BEFORE_ROUTING, [$usedRoute, $this]); $this->router()->dispatch($route); $this->trigger(Hahns::EVENT_AFTER_ROUTING, [$usedRoute, $this]); // get callback $callback = $this->router()->getCallback(); // get attributes for callback $attributes = []; $callbackReflection = new \ReflectionFunction($callback); foreach ($callbackReflection->getParameters() as $parameter) { $type = $parameter->getClass()->getName(); $attributes[] = $this->parameterHolder->get($type); } // call callback $this->trigger(Hahns::EVENT_BEFORE_EXECUTING_ROUTE, [$usedRoute, $callback, $attributes, $this]); echo call_user_func_array($callback, $attributes); $this->trigger(Hahns::EVENT_AFTER_EXECUTING_ROUTE, [$usedRoute, $callback, $attributes, $this]); } catch (NotFoundException $e) { $this->trigger(Hahns::EVENT_NOT_FOUND, [$usedRoute, $this, $e]); } catch (\Exception $e) { $this->trigger(Hahns::EVENT_ERROR, [$e, $this]); } $this->trigger(Hahns::EVENT_AFTER_RUNNING, [$usedRoute, $this]); }
/** * @param string $parsable * @throws Exception\NotFoundException * @throws \InvalidArgumentException */ public function dispatch($parsable) { StringValidator::hasTo($parsable, 'parsable'); // clear named parameters $this->namedParameters = []; // itereate routes $callback = null; foreach ($this->getRouteCandidates($parsable) as $route) { // get pattern and callback of parsable list($route, $callback) = $route; // split parsable and route $splittedRoute = explode('/', $route); $splittedParsable = explode('/', $parsable); $paramPattern = '/\\[(.+):(.+)\\]/U'; $namedParameter = []; foreach ($splittedRoute as $index => $routeSplit) { // leere element ueberspringen if (strlen($routeSplit) == 0) { continue; } // pruefen ob element einen parameter enthaelt preg_match($paramPattern, $routeSplit, $match); // wenn parameter enthaelt muss dieser geparst werden if (count($match) > 0) { // match aus route entfernen $strpos = strpos($splittedRoute[$index], $match[0]); $strlen = strlen($splittedRoute[$index]); $splittedRoute[$index] = substr_replace($splittedRoute[$index], '', $strpos, $strlen); if ($splittedRoute[$index] === false) { $splittedRoute[$index] = null; } // regex des parameter aufarbeiten $pattern = sprintf('/%s/', $match[1]); // name des parameter speichern $name = $match[2]; // regex auf gleiches element von parsable ausfuehren preg_match($pattern, $splittedParsable[$index], $match); if (count($match) > 0) { // match als wert speichern $namedParameter[$name] = $match[0]; // match aus parsable entfernen $strpos = strpos($splittedParsable[$index], $match[0]); $strlen = strlen($splittedParsable[$index]); $splittedParsable[$index] = substr_replace($splittedRoute[$index], '', $strpos, $strlen); if ($splittedParsable[$index] === false) { $splittedParsable[$index] = null; } } } } // route und parsable wieder zusammensetzen und vergleichen $strippedRoute = implode('/', $splittedRoute); $strippedParsable = implode('/', $splittedParsable); if ($strippedRoute != $strippedParsable) { continue; } // set named parameters and callback $this->namedParameters = $namedParameter; $this->callback = $callback; return; } throw new NotFoundException(); }