/**
  * Matches a user submitted path. Assigns and returns an array of variables
  * on a successful match.
  *
  * If a request object is registered, it uses its setModuleName(),
  * setControllerName(), and setActionName() accessors to set those values.
  * Always returns the values as an array.
  *
  * @param string $path Path used to match against this routing map
  * @return array An array of assigned values or a false on a mismatch
  */
 public function match($path, $partial = false)
 {
     $this->_setRequestKeys();
     $values = array();
     $params = array();
     if (!$partial) {
         $path = trim($path, self::URI_DELIMITER);
     } else {
         $matchedPath = $path;
     }
     if ($path != '') {
         $path = explode(self::URI_DELIMITER, $path);
         $adminKey = Fox::getAdminKey();
         $adminModule = 'admin';
         if ($path[0] == $adminKey) {
             $path[0] = $adminModule;
         } else {
             if ('admin' == $path[0]) {
                 $path[0] = FALSE;
             }
         }
         if ($this->_dispatcher && $this->_dispatcher->isValidModule($path[0])) {
             $values[$this->_moduleKey] = array_shift($path);
             $this->_moduleValid = true;
         }
         if (count($path) && !empty($path[0])) {
             $values[$this->_controllerKey] = array_shift($path);
         }
         if (count($path) && !empty($path[0])) {
             $values[$this->_actionKey] = array_shift($path);
         }
         if ($numSegs = count($path)) {
             for ($i = 0; $i < $numSegs; $i = $i + 2) {
                 $key = urldecode($path[$i]);
                 $val = isset($path[$i + 1]) ? urldecode($path[$i + 1]) : null;
                 $params[$key] = isset($params[$key]) ? array_merge((array) $params[$key], array($val)) : $val;
             }
         }
     }
     if ($partial) {
         $this->setMatchedPath($matchedPath);
     }
     $this->_values = $values + $params;
     return $this->_values + $this->_defaults;
 }
 /**
  * Forward to another controller/action.
  *
  * It is important to supply the unformatted names, i.e. "article"
  * rather than "ArticleController".  The dispatcher will do the
  * appropriate formatting when the request is received.
  * 
  * @param string $rout routing path in format of "module/controller/action"
  * if "*" provided in place of module, controller or action
  * then current module, controller or action will used to forward
  * @param array $params
  * @return void
  */
 protected function sendForward($rout = '*/*/*', array $params = array())
 {
     $request = $this->getRequest();
     $routInfo['admin'] = Fox::getAdminKey();
     $urlParts = explode('/', $rout);
     $module = isset($urlParts[0]) && $urlParts[0] != '*' ? $urlParts[0] : NULL;
     $controller = isset($urlParts[1]) && $urlParts[1] != '*' ? $urlParts[1] : NULL;
     $action = isset($urlParts[2]) && $urlParts[2] != '*' ? $urlParts[2] : NULL;
     if ($module == 'admin') {
         $module = $routInfo['admin'];
     }
     if (!empty($params)) {
         $request->setParams($params);
     }
     if (null !== $controller) {
         $request->setControllerName($controller);
         // Module should only be reset if controller has been specified
         if (null !== $module) {
             $request->setModuleName($module);
         }
     }
     $request->setActionName($action)->setDispatched(false);
 }