public static function loadClass(ReflectionClass $refl, Reader $reader, Router $router)
 {
     $annotation = $reader->getClassAnnotation($refl, 'Destiny\\Common\\Annotation\\Controller');
     if (empty($annotation)) {
         return;
     }
     $methods = $refl->getMethods(ReflectionMethod::IS_PUBLIC);
     foreach ($methods as $method) {
         /** @var Route[] $routes */
         $routes = array();
         $annotations = $reader->getMethodAnnotations($method);
         for ($i = 0; $i < count($annotations); ++$i) {
             /** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
             if ($annotations[$i] instanceof \Destiny\Common\Annotation\Route) {
                 $routes[] = $annotations[$i];
             }
         }
         if (count($routes) <= 0) {
             continue;
         }
         /** @var \Destiny\Common\Annotation\HttpMethod $feature */
         $httpMethod = $reader->getMethodAnnotation($method, 'Destiny\\Common\\Annotation\\HttpMethod');
         /** @var \Destiny\Common\Annotation\Secure $feature */
         $secure = $reader->getMethodAnnotation($method, 'Destiny\\Common\\Annotation\\Secure');
         for ($i = 0; $i < count($routes); ++$i) {
             $router->addRoute(new Route(array('path' => $routes[$i]->path, 'classMethod' => $method->name, 'class' => $refl->name, 'httpMethod' => $httpMethod ? $httpMethod->allow : null, 'secure' => $secure ? $secure->roles : null)));
         }
     }
 }
Exemple #2
0
 /**
  * Executes the action if a route is found
  */
 public function executeRequest(Request $request)
 {
     $route = $this->router->findRoute($request);
     $model = new ViewModel();
     $response = null;
     // No route found
     if (!$route) {
         $model->title = Http::$HEADER_STATUSES[Http::STATUS_NOT_FOUND];
         $response = new Response(Http::STATUS_NOT_FOUND);
         $response->setBody($this->template('errors/' . Http::STATUS_NOT_FOUND . '.php', $model));
         $this->handleResponse($response);
     }
     // Security checks
     if (!$this->hasRouteSecurity($route, Session::getCredentials())) {
         $model->title = Http::$HEADER_STATUSES[Http::STATUS_UNAUTHORIZED];
         $response = new Response(Http::STATUS_UNAUTHORIZED);
         $response->setBody($this->template('errors/' . Http::STATUS_UNAUTHORIZED . '.php', $model));
         $this->handleResponse($response);
     }
     try {
         // Parameters
         $params = array_merge($_GET, $_POST, $route->getPathParams($request->path()));
         // Get and init action class
         $className = $route->getClass();
         $classMethod = $route->getClassMethod();
         // Init the action class instance
         $classInstance = new $className();
         // Check for @Transactional annotation
         $annotationReader = $this->getAnnotationReader();
         $transactional = $annotationReader->getMethodAnnotation(new \ReflectionMethod($classInstance, $classMethod), 'Destiny\\Common\\Annotation\\Transactional');
         $transactional = empty($transactional) ? false : true;
         // If transactional begin a DB transaction before the action begins
         if ($transactional) {
             $conn = $this->getConnection();
             $conn->beginTransaction();
         }
         // Execute the class method
         $response = $classInstance->{$classMethod}($params, $model, $request);
         // Log any errors on the model
         // @TODO neaten this implementation up - better than logging everywhere else
         ///if (! empty ( $model->error ) && is_a ( $model->error, 'Exception' )) {
         /// $this->logger->error ( $model->error->getMessage () );
         //}
         // Check if the response is valid
         if (empty($response)) {
             throw new Exception('Invalid action response');
         }
         // Redirect response
         if (is_string($response) && substr($response, 0, 10) === 'redirect: ') {
             $redirect = substr($response, 10);
             $response = new Response(Http::STATUS_OK);
             $response->setLocation($redirect);
         }
         // Template response
         if (is_string($response)) {
             $tpl = $response . '.php';
             $response = new Response(Http::STATUS_OK);
             $response->setBody($this->template($tpl, $model));
         }
         // Check the response type
         if (!$response instanceof Response) {
             throw new Exception('Invalid response');
         }
         // Commit the DB transaction
         if ($transactional) {
             $conn->commit();
         }
     } catch (Exception $e) {
         // Destiny\Exceptions are caught and displayed
         $this->logger->error($e->getMessage());
         if ($transactional) {
             $conn->rollback();
         }
         $response = new Response(Http::STATUS_ERROR);
         $model->error = new Exception($e->getMessage());
         $model->code = Http::STATUS_ERROR;
         $model->title = 'Error';
         $response->setBody($this->template('errors/' . Http::STATUS_ERROR . '.php', $model));
     } catch (\Exception $e) {
         // \Exceptions are caught and generic message is shown
         $this->logger->critical($e->getMessage());
         if ($transactional) {
             $conn->rollback();
         }
         $response = new Response(Http::STATUS_ERROR);
         $model->error = new Exception('Maximum over-rustle has been achieved');
         $model->code = Http::STATUS_ERROR;
         $model->title = 'Error';
         $response->setBody($this->template('errors/' . Http::STATUS_ERROR . '.php', $model));
     }
     // Handle the request response
     $this->handleResponse($response);
 }
Exemple #3
0
 /**
  * @param Request $request
  */
 public function executeRequest(Request $request)
 {
     $route = $this->router->findRoute($request);
     $conn = $this->getConnection();
     $model = new ViewModel();
     if ($route == null) {
         $model->title = Http::$HEADER_STATUSES[Http::STATUS_NOT_FOUND];
         $response = new Response(Http::STATUS_NOT_FOUND);
         $response->setBody($this->template('errors/' . Http::STATUS_NOT_FOUND . '.php', $model));
         $this->handleResponse($response);
     }
     if ($route->isSecure()) {
         $creds = Session::getCredentials();
         if ($creds->isValid() && strcasecmp($creds->getUserStatus(), 'Active') !== 0) {
             $response = new Response(Http::STATUS_ERROR);
             $model->error = new Exception(sprintf('User status not active. Status: %s', $creds->getUserStatus()));
             $model->code = Http::STATUS_ERROR;
             $model->title = 'Inactive user';
             $response->setBody($this->template('errors/' . Http::STATUS_ERROR . '.php', $model));
             $this->handleResponse($response);
         }
         if (!$this->hasRouteSecurity($route, $creds)) {
             $response = new Response(Http::STATUS_UNAUTHORIZED);
             $model->title = Http::$HEADER_STATUSES[Http::STATUS_UNAUTHORIZED];
             $response->setBody($this->template('errors/' . Http::STATUS_UNAUTHORIZED . '.php', $model));
             $this->handleResponse($response);
         }
     }
     try {
         $className = $route->getClass();
         $classMethod = $route->getClassMethod();
         $classReflection = new \ReflectionClass($className);
         $classInstance = $classReflection->newInstance();
         // Order the controller arguments and invoke the controller
         $args = array();
         $methodReflection = $classReflection->getMethod($classMethod);
         $methodParams = $methodReflection->getParameters();
         foreach ($methodParams as $methodParam) {
             $paramType = $methodParam->getClass();
             if ($methodParam->isArray()) {
                 // the $params passed into the Controller classes. A merge of the _GET, _POST and variables generated from the route path (e.g. /dog/{id}/cat)
                 $args[] = array_merge($request->get(), $request->post(), $this->router->getRoutePathParams($route, $request->path()));
             } else {
                 if ($paramType->isInstance($model)) {
                     $args[] =& $model;
                 } else {
                     if ($paramType->isInstance($request)) {
                         $args[] =& $request;
                     }
                 }
             }
         }
         // Execute the controller
         $response = $methodReflection->invokeArgs($classInstance, $args);
         if (empty($response)) {
             throw new Exception('Invalid action response');
         }
         // Redirect response
         if (is_string($response) && substr($response, 0, 10) === 'redirect: ') {
             $redirect = substr($response, 10);
             $response = new Response(Http::STATUS_OK);
             $response->setLocation($redirect);
         }
         // Template response
         if (is_string($response)) {
             $tpl = $response . '.php';
             $response = new Response(Http::STATUS_OK);
             $response->setBody($this->template($tpl, $model));
         }
         if (!$response instanceof Response) {
             throw new Exception('Invalid response');
         }
     } catch (Exception $e) {
         $this->logger->error($e->getMessage() . PHP_EOL . $e->getTraceAsString());
         if ($conn->isTransactionActive()) {
             $conn->rollback();
         }
         $response = new Response(Http::STATUS_ERROR);
         $model->error = new Exception($e->getMessage());
         $model->code = Http::STATUS_ERROR;
         $model->title = 'Error';
         $response->setBody($this->template('errors/' . Http::STATUS_ERROR . '.php', $model));
     } catch (\Exception $e) {
         $this->logger->critical($e->getMessage() . PHP_EOL . $e->getTraceAsString());
         if ($conn->isTransactionActive()) {
             $conn->rollback();
         }
         $response = new Response(Http::STATUS_ERROR);
         $model->error = new Exception('Maximum over-rustle has been achieved');
         $model->code = Http::STATUS_ERROR;
         $model->title = 'Error';
         $response->setBody($this->template('errors/' . Http::STATUS_ERROR . '.php', $model));
     }
     $this->handleResponse($response);
 }