public static function buildRoutes($controllers) { $compiled_routes = array(); // iterate all the controllers and make a tree of all the possible path foreach ($controllers as $controller) { $base_route = new Action(); // set the route defaults from the Controller annotations (if any) foreach ($controller['class']['annotations'] as $annotation) { $base_route->addAnnotation($annotation); } foreach ($controller['methods'] as $method) { $route = clone $base_route; // copy from the controller route if ($method['visibility'] == Wave\Reflector::VISIBILITY_PUBLIC) { foreach ($method['annotations'] as $annotation) { $route->addAnnotation($annotation); } foreach ($method['parameters'] as $parameter) { /** @var \ReflectionParameter $parameter */ $type = $parameter->getClass() !== null ? $parameter->getClass()->getName() : null; $route->addMethodParameter($parameter->getName(), $type); } } $route->setAction($controller['class']['name'] . '.' . $method['name']); if ($route->hasRoutes()) { if (isset($compiled_routes[$base_route->getProfile()][$route->getAction()])) { throw new \LogicException(sprintf("Action %s is declared twice", $route->getAction())); } $compiled_routes[$base_route->getProfile()][$route->getAction()] = $route; } } } return $compiled_routes; }
private function setAction(Action $action) { if ($this->action === null) { $this->action = $action; } else { throw new Exception($this->action->getAction() . ' shares a duplicate route with ' . $action->getAction()); } }
public static function handle($e, $send_response = true) { try { Hook::triggerAction('exception.handle', array(&$e)); $log_message = sprintf('%-4s %s', "({$e->getCode()})", $e->getMessage()); // get the channel manually so the introspection works properly. $level = Log::ERROR; if ($e instanceof ErrorException && isset(self::$levels[$e->getSeverity()])) { $level = self::$levels[$e->getSeverity()]; } Log::getChannel('exception')->addRecord($level, $log_message, array('exception' => $e)); $request = static::$request; if ($request === null) { $request = Request::createFromGlobals(); } $action = Action::getDefaultAction(self::$_controller); $action->setRespondsWith(array('*'), false); $response = Controller::invoke($action, $request, array('exception' => $e)); $response->prepare($request); if ($send_response) { $response->send(); } return $response; } catch (\Exception $_e) { $response = new Response(); $response->setStatusCode(500); if (Core::$_MODE === Core::MODE_PRODUCTION) { $response->setContent("Internal server error"); } else { $response->setContent($e->__toString() . "\n\n\nAdditionally, the following exception occurred while trying to handle the error:\n\n" . $_e->__toString()); } return $response; } }
public function apply(Action &$action) { $action->addBaseRoute($this->parameters[0]); }
public function apply(Action &$action) { $action->setValidationSchema($this->schema); }
public function apply(Action &$action) { $action->setRespondsWith($this->methods, $this->inherit); }
public function apply(Action &$action) { $action->addRoute($this->methods, $this->url); }
/** * @param Action $action * @param Request $request * @param array $data * @param int $invoke_type * * @throws Http\Exception\UnauthorizedException * @throws Http\Exception\NotFoundException * @throws Exception * @throws Http\Exception\ForbiddenException * @return Http\Response * @throws Http\Exception\ForbiddenException */ public static final function invoke(Action $action, Request $request, $data = array(), $invoke_type = self::INVOKE_NORMAL) { list($controller_class, $action_method) = explode('.', $action->getAction(), 2) + array(null, null); if (!isset($action_method)) { $action_method = Config::get('wave')->controller->default_method; } if (class_exists($controller_class, true) && method_exists($controller_class, $action_method)) { /** @var \Wave\Controller $controller */ $controller = new $controller_class(); $controller->_action = $action; $controller->_request = $request; $controller->_response_method = $request->getFormat(); $controller->_invoke_method = $invoke_type; switch ($controller->_request->getMethod()) { case Request::METHOD_GET: $controller->_is_get = true; break; case Request::METHOD_POST: $controller->_is_post = true; break; } $data = array_replace($controller->_request->getData(), $data); $controller->_data = $data; Hook::triggerAction('controller.before_init', array(&$controller)); $controller->init(); if ($invoke_type !== self::INVOKE_SUB_REQUEST && !$action->canRespondWith($request->getFormat())) { throw new NotFoundException('The requested action ' . $action->getAction() . ' can not respond with ' . $request->getFormat() . '. (Accepts: ' . implode(', ', $action->getRespondsWith()) . ')', $request); } else { if (!$action->checkRequiredLevel($request)) { throw new UnauthorizedException('You are not authorized to view this resource'); } else { if ($action->needsValidation() && !$controller->inputValid($action->getValidationSchema($data))) { return $controller->request(); } } } Hook::triggerAction('controller.before_dispatch', array(&$controller)); $parameters = array(); foreach ($action->getMethodParameters() as $parameter) { list($parameter_name, $parameter_type) = $parameter; if (isset($controller->_cleaned[$parameter_name])) { //Try first in validator output $parameters[] = $controller->_cleaned[$parameter_name]; } elseif (isset($controller->_data[$parameter_name])) { //Then if just using the passed data - there may be a legitimate use for this? $parameters[] = $controller->_data[$parameter_name]; } elseif ($parameter_type === 'Wave\\Validator\\Result') { //If the validator is requested, give it $parameters[] = $controller->_cleaned; } elseif ($parameter_type === get_class($request)) { //If the request is requested, give it $parameters[] = $request; } else { //Otherwise place hold. Could maybe get the default value during generation and pass that instead $parameters[] = null; } } try { $response = call_user_func_array(array($controller, $action_method), $parameters); } catch (InvalidInputException $e) { $controller->_input_errors = $e->getViolations(); $response = $controller->request(); } Hook::triggerAction('controller.after_dispatch', array(&$controller, &$response)); return $response; } else { throw new Exception('Could not invoke action ' . $action->getAction() . '. Method ' . $controller_class . '::' . $action_method . '() does not exist', Response::STATUS_SERVER_ERROR); } }
public function apply(Action &$action) { $action->setProfile($this->parameters[0]); }
public static function getDefaultAction($action_method) { $action = new Action(); $action->setAction($action_method); return $action; }