Beispiel #1
0
 /**
  * Returns a matching route if available for $pathInfo
  *
  * @param string $pathInfo
  * @param string $queryString
  * @return vB_Frontend_Route
  */
 public function getRoute($pathInfo, $queryString, $anchor = '')
 {
     static $closed;
     // clean the path if necessary
     $parsed = vB_String::parseUrl($pathInfo);
     $pathInfo = $parsed['path'];
     // check for any querystring to append
     if (!empty($parsed['query'])) {
         if (!empty($queryString)) {
             $queryString = $parsed['query'] . '&' . $queryString;
         } else {
             $queryString = $parsed['query'];
         }
     }
     if (empty($anchor) and !empty($parsed['anchor'])) {
         $anchor = $parsed['anchor'];
     }
     //Check for standard routes.
     if (is_string($pathInfo)) {
         $common = vB5_Route::fetchCommonRoutes();
         if (isset($common[$pathInfo])) {
             //See if we have a match
             // pattern matching is case-insensitive
             $pattern = '#^' . $common[$pathInfo]['regex'] . '(?:/)?$#i';
             if (preg_match($pattern, $pathInfo, $matches)) {
                 $className = (isset($common[$pathInfo]['class']) and !empty($common[$pathInfo]['class']) and class_exists($common[$pathInfo]['class'])) ? $common[$pathInfo]['class'] : self::DEFAULT_CLASS;
                 if (!empty($common[$pathInfo]['arguments'])) {
                     $common[$pathInfo]['arguments'] = unserialize($common[$pathInfo]['arguments']);
                 }
                 try {
                     $route = new $className($common[$pathInfo], $matches, $queryString, $anchor);
                 } catch (vB_Exception $ex) {
                     return $this->handleRouteExceptions($ex);
                 }
             }
         }
     }
     if (!isset($route)) {
         // calculate prefixes set
         $prefixes = vB5_Route::getPrefixSet($pathInfo);
         // get matching routes
         $result = vB::getDbAssertor()->assertQuery('routenew', array('prefix' => $prefixes));
         if (in_array($result->db()->errno, $result->db()->getCriticalErrors())) {
             throw new Exception('no_vb5_database');
         }
         $prefixMatches = array();
         foreach ($result as $route) {
             if (($unserialized = @unserialize($route['arguments'])) !== false) {
                 $route['arguments'] = $unserialized;
             } else {
                 $route['arguments'] = array();
             }
             $prefixMatches[$route['routeid']] = $route;
         }
         unset($route);
     }
     // check for banned
     $bannedInfo = vB_Library::instance('user')->fetchBannedInfo(false);
     // get best route
     try {
         if (!isset($route)) {
             $route = vB5_Route::selectBestRoute($pathInfo, $queryString, $anchor, $prefixMatches);
         }
         if ($route) {
             // Check if forum is closed
             $routeInfo = array('routeguid' => $route->getRouteGuid(), 'controller' => $route->getController(), 'action' => $route->getAction(), 'arguments' => $route->getArguments());
             $segments = $route->getRouteSegments();
             $cleanedRoute = implode('/', $segments);
             if (in_array($cleanedRoute, $this->GetSpecialRoutes())) {
                 return array('no_permission' => 1);
             }
             //Always allow login and access to the admincp, even if closed.
             if (!in_array($cleanedRoute, $this->whitelistRoute)) {
                 if (!isset($closed)) {
                     if (vB_Cache::instance(vB_Cache::CACHE_FAST)->isLoaded('vB_State_checkBeforeView')) {
                         $closed = vB_Cache::instance(vB_Cache::CACHE_FAST)->read('vB_State_checkBeforeView');
                     } else {
                         $closed = vB_Api::instanceInternal('state')->checkBeforeView($routeInfo);
                     }
                 }
                 if ($closed !== false) {
                     return array('forum_closed' => $closed['msg']);
                 }
             }
             if ($bannedInfo['isbanned']) {
                 return array('banned_info' => $bannedInfo);
             }
             if (!vB::getUserContext()->getChannelPermission('forumpermissions', 'canview', 1)) {
                 $prefix = $route->getCanonicalPrefix();
                 if (!in_array($prefix, $this->whitelistPrefix)) {
                     if ($route->getPrefix() == 'admincp' or $route->getPrefix() == 'modcp') {
                         // do nothing really, just allow passage
                     } else {
                         if ($route->getPrefix() == 'ajax') {
                             $arguments = $route->getArguments();
                             $allowedOptions = array('/api/contactus/sendMail', '/api/hv/generateToken');
                             if (!isset($arguments['route']) or !in_array($arguments['route'], $allowedOptions)) {
                                 return array('no_permission' => 1);
                             }
                         } else {
                             return array('no_permission' => 1);
                         }
                     }
                 }
             }
             if (is_array($route) and (isset($route['no_permission']) or isset($route['internal_error']))) {
                 return $route;
             }
             $canonicalUrl = $route->getCanonicalUrl();
             $canonicalUrl = str_replace('&', '&', $canonicalUrl);
             $canonicalPathInfo = $canonicalUrl ? vB_String::parseUrl($canonicalUrl, PHP_URL_PATH) : $pathInfo;
             $canonicalParam = $route->getCanonicalQueryParameters();
             if ($canonicalPathInfo and $canonicalPathInfo[0] == '/') {
                 $canonicalPathInfo = substr($canonicalPathInfo, 1);
             }
             $queryParams = $route->getQueryParameters();
             $routeId = $route->getRouteId();
             // return routeid even for 301 redirects. Certain callers expect
             // this function to return the routeid in order to write a cache record
             if ($redirectId = $route->getRedirect301()) {
                 return array('routeid' => $routeId, 'redirect' => vB5_Route::buildUrl($redirectId, $route->getArguments(), $queryParams, $route->getAnchor()), 'redirectRouteId' => $redirectId);
             } else {
                 if ($pathInfo != $canonicalPathInfo or $canonicalParam !== false and $queryParams != $canonicalParam) {
                     $hashtag = '';
                     if (isset($queryParams['p'])) {
                         $hashtag = '#post' . $queryParams['p'];
                         // some browers do not preserve fragment during redirects, VBV-10255
                     }
                     return array('routeid' => $routeId, 'redirect' => $canonicalUrl . $hashtag, 'redirectRouteId' => $routeId);
                 } else {
                     return array('routeid' => $routeId, 'routeguid' => $route->getRouteGuid(), 'controller' => $route->getController(), 'action' => $route->getAction(), 'template' => $route->getTemplate(), 'arguments' => $route->getArguments(), 'queryParameters' => $queryParams, 'pageKey' => $route->getPageKey(), 'userAction' => $route->getUserAction(), 'breadcrumbs' => $route->getBreadcrumbs(), 'headlinks' => $route->getHeadLinks());
                 }
             }
         } else {
             return false;
         }
     } catch (vB_Exception $ex) {
         return $this->handleRouteExceptions($ex);
     }
 }