示例#1
0
 /**
  * Dispatches the Controller
  *
  * @param Next\Application\Application $application
  *   Application to Configure
  *
  * @param stdClass $data
  *   Data to Configure Application
  *
  * @return Next\HTTP\Response
  *   Response Object
  *
  * @throws Next\Controller\Dispatcher\DispatcherException
  *   ReflectionException was caught
  */
 public function dispatch(Application $application, \stdClass $data)
 {
     try {
         $this->setDispatched(TRUE);
         // Adding Request Params
         $application->getRequest()->setQuery($data->params);
         // Calling Action from Controller at defined Application
         $reflector = new \ReflectionMethod($data->class, $data->method);
         $reflector->invoke(new $data->class($application));
         return $application->getResponse();
     } catch (\ReflectionException $e) {
         throw DispatcherException::reflection($e);
     } catch (ControllerException $e) {
         /**
          * @internal
          * ControllerException's came from Application's Controllers
          * and, as part of Standardization Concept, should be thrown when
          * something is wrong
          *
          * E.g.: Database Query results in FALSE instead of a Recordset Object
          *
          * Doesn't matter the level of DEVELOPMENT MODE Constant, we'll
          * try to create a Template Variable and virtually re-send the Response,
          * by re-rendering the View
          *
          * Now, in Template View, a special variable will be available with
          * Exception Message
          *
          * If the assignment or rendering fails, the Production Handler
          * will be used as fallback
          */
         try {
             $application->getView()->assign('__EXCEPTION__', $e->getMessage())->render();
         } catch (ViewException $e) {
             Handlers::production($e);
         }
     } catch (ViewException $e) {
         /**
          * @internal
          * Catching ViewException grants a nice view for any sort of
          * errors triggered by Next View Class, specially when they come from Magic Methods
          * which is directly related to Template Variables usage.
          *
          * And by forcing a Development Handler we warn lazy
          * programmers they are doing the wrong thing, like trying to hide the error ^^
          */
         if (ob_get_length()) {
             // We want ONLY the Exception Template
             ob_end_clean();
         }
         Handlers::development($e);
     }
 }
示例#2
0
 /**
  * Find the Template View File from FileSpec
  *
  * @return string
  *   Template View FilePath from defined FileSpec
  *
  * @see
  *   Next\Controller\Router\Router::getController()
  *   Next\Controller\Router\Router::getAction()
  */
 private function findFileBySpec()
 {
     // Known Replacements
     $application = $this->_application->getApplicationDirectory();
     $controller = $this->_application->getRouter()->getController();
     $action = $this->_application->getRouter()->getAction();
     /**
      * @internal
      * Finding Default SubPath
      *
      * Default SubPath is built by removing:
      *
      * - Application Directory,
      * - 'Controller' Keyword
      * - Controller ClassName
      *
      * from Controllers Name
      */
     $subpath = str_replace(array($application, self::CONTROLLERS_KEYWORD, basename($controller)), '', $controller);
     // Windows, Windows, Windows... <_<
     $subpath = str_replace('\\\\', '\\', $subpath);
     $subpath = trim($subpath, '\\');
     // Cleaning Controller Class to find its "Real Name"
     $controller = str_replace('Controller', '', basename($controller));
     // Cleaning known Action suffixes
     $action = str_replace(array(self::ACTION_METHOD_SUFFIX_VIEW, self::ACTION_METHOD_SUFFIX_ACTION), '', $action);
     // Replacing known matches
     $spec = trim(str_replace(array(self::APPLICATION, self::CONTROLLER, self::ACTION, self::SUBPATH), array($application, $controller, $action, $subpath), $this->_fileSpec), '/');
     $spec = Tools::cleanAndInvertPath($spec);
     return sprintf('%s.%s', strtolower($spec), $this->_extension);
 }
示例#3
0
 /**
  * Finds a Route that matches to an Application AND current Request
  *
  * @param Next\Application\Application $application
  *   Application to iterate Controllers
  *
  * @return array|object|boolean
  *
  *   If a Route could be match against current Request URI an
  *   array or an object will be returned (depending on Connection
  *   Driver configuration).
  *
  *   If none could, FALSE will be returned
  */
 public function find(Application $application)
 {
     // Shortening Declarations
     $request = $application->getRequest();
     $URI = $request->getRequestUri();
     // Searching the Request in Routes Database
     $stmt = $this->dbh->prepare('SELECT `requestMethod`, `class`, `method`,
                                              `requiredParams`, `optionalParams`
                                         FROM `routes`
                                             WHERE `application` = ? AND
                                                 ( `requestMethod` = ? AND ? REGEXP `URI` )');
     $stmt->execute(array($application->getClass()->getName(), $request->getRequestMethod(), $URI));
     $data = $stmt->fetch();
     // Match found, let's prepare everything for a successful Dispatch
     if ($data !== FALSE) {
         /**
          * @internal
          * Setting Up Found Controller and its action to be used in View,
          * as part of findFilebySpec() method
          */
         $this->controller =& $data->class;
         $this->action =& $data->method;
         // Analyzing Params
         $requiredParams = unserialize($data->requiredParams);
         // Lookup for Required Params in URL
         if (count($requiredParams) > 0) {
             $this->lookup($requiredParams, $URI, $request->getQuery());
         }
         /**
          * @internal
          * Validating Required Params
          * Only Parameters with a [List|of|Possible|Values] will be validated
          */
         $token = self::LIST_OPEN_TOKEN;
         $this->validate(array_filter($requiredParams, function ($item) use($token) {
             return strpos($item, $token) !== FALSE;
         }), $URI);
         // Process Dynamic Params, in order to register them as Request Params
         $params = $this->process(array_merge($requiredParams, unserialize($data->optionalParams)), $URI);
         // Merging manually defined GET query
         $data->params = array_merge($params, $request->getQuery());
         // Discarding Unnecessary Information
         unset($data->requiredParams, $data->optionalParams);
         return $data;
     }
     return FALSE;
 }
示例#4
0
 /**
  * Retrieve a GET Param
  *
  * Grant access to a Request Dynamic Params using Property Notation instead Array Notation
  *
  * @param string $param
  *   Desired Param from Dynamic Params
  *
  * @return mixed Dynamic Param Value
  *
  * @throws Next\Controller\ControllerException
  *   Trying to access internal properties prefixed with an underscore
  *   without use their correct accessors
  *
  * @throws Next\Controller\ControllerException
  *   Trying to access non-existent param
  */
 public function __get($param)
 {
     $param = trim($param);
     try {
         return $this->_application->getRequest()->getQuery($param);
     } catch (RequestException $e) {
         // Standardizing Exception
         throw ControllerException::paramNotFound($e);
     }
 }
示例#5
0
 /**
  * Get Annotations Found
  *
  * @return array
  *   Found Annotations
  */
 public function getAnnotations()
 {
     $data = new \ArrayIterator();
     $domains = $this->matchDomainAnnotations($this->application);
     if (count($domains) > 0) {
         $data->offsetSet('Domains', $domains);
     }
     $data->offsetSet('Path', $this->matchPathAnnotation($this->application));
     // Listing Controllers Methods and reducing (or amplifying) the list to its Action Methods
     $actions = $this->application->getControllers()->getIterator();
     iterator_apply($actions, function (\Iterator $iterator) {
         $action = new Actions(new \ArrayIterator($iterator->current()->getClass()->getMethods()));
         $iterator->offsetSet($iterator->key(), $action->getAnnotations());
         return TRUE;
     }, array($actions));
     if ($actions->count() > 0) {
         $data->offsetSet('Routes', $actions->getArrayCopy());
     }
     return $data;
 }