diff --git a/.htaccess b/.htaccess index 89ecf951f..43536f5e9 100644 --- a/.htaccess +++ b/.htaccess @@ -15,37 +15,7 @@ RewriteRule ^(.+)/files/(member_extra_info|attach|cache|faceOff)/(.*) ./files/$2 RewriteCond %{SCRIPT_FILENAME} !-f RewriteRule ^(.+)/(files|modules|widgets|widgetstyles|layouts|m.layouts|addons)/(.*) ./$2/$3 [L] -# rss , blogAPI -RewriteRule ^(rss|atom)$ ./index.php?module=rss&act=$1 [L] -RewriteRule ^([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?mid=$1&act=$2 [L] -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)$ ./index.php?vid=$1&mid=$2&act=$3 [L] - -# trackback -RewriteRule ^([0-9]+)/(.+)/trackback$ ./index.php?document_srl=$1&key=$2&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?mid=$1&document_srl=$2&key=$3&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&document_srl=$2&key=$3&act=trackback [L] -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback$ ./index.php?vid=$1&mid=$2&document_srl=$3&key=$4&act=trackback [L] - -# document permanent link -RewriteRule ^([0-9]+)$ ./index.php?document_srl=$1 [L,QSA] - -# mid link -RewriteCond %{SCRIPT_FILENAME} !-d -RewriteRule ^([a-zA-Z0-9_]+)/?$ ./index.php?mid=$1 [L,QSA] -# mid + document link -RewriteRule ^([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?mid=$1&document_srl=$2 [L,QSA] - -# vid + mid link -RewriteCond %{SCRIPT_FILENAME} !-d -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/?$ ./index.php?vid=$1&mid=$2 [L,QSA] -# vid + mid + document link -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)$ ./index.php?vid=$1&mid=$2&document_srl=$3 [L,QSA] - -# mid + entry title -RewriteRule ^([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?mid=$1&entry=$2 [L,QSA] -# vid + mid + entry title -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)$ ./index.php?vid=$1&mid=$2&entry=$3 [L,QSA] - -#shop / vid / [category|product] / identifier +# router RewriteCond %{SCRIPT_FILENAME} !-f -RewriteRule ^([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9_\.-]+)$ ./index.php?act=route&vid=$1&type=$2&identifier=$3 [L,QSA] +RewriteCond %{SCRIPT_FILENAME} !-d +RewriteRule ^(.*)$ ./index.php [L] diff --git a/classes/context/Context.class.php b/classes/context/Context.class.php index 2f8ca22e6..401e025b3 100644 --- a/classes/context/Context.class.php +++ b/classes/context/Context.class.php @@ -242,9 +242,18 @@ class Context } } + // check if using rewrite module + $this->allow_rewrite = ($this->db_info->use_rewrite == 'Y' ? TRUE : FALSE); + // If XE is installed, get virtual site information if(self::isInstalled()) { + // If using rewrite module, initializes router + if($this->allow_rewrite) + { + Router::proc(); + } + $oModuleModel = getModel('module'); $site_module_info = $oModuleModel->getDefaultMid(); @@ -363,9 +372,6 @@ class Context $this->lang = &$GLOBALS['lang']; $this->loadLang(_XE_PATH_ . 'common/lang/'); - // check if using rewrite module - $this->allow_rewrite = ($this->db_info->use_rewrite == 'Y' ? TRUE : FALSE); - // set locations for javascript use $url = array(); $current_url = self::getRequestUri(); @@ -1640,7 +1646,9 @@ class Context 'act.document_srl.key.mid.vid' => ($act == 'trackback') ? "$vid/$mid/$srl/$key/$act" : '' ); - $query = $target_map[$target]; + Router::setMap($target_map); + + $query = Router::makePrettyUrl($target); } if(!$query) diff --git a/classes/router/Router.class.php b/classes/router/Router.class.php new file mode 100644 index 000000000..8b95c2275 --- /dev/null +++ b/classes/router/Router.class.php @@ -0,0 +1,253 @@ + array('module' => 'rss', 'act' => '$1', '[L]' => TRUE), + '([a-zA-Z0-9_]+)/(rss|atom|api)' => array('mid' => '$1', 'act' => '$2', '[L]' => TRUE), + '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/(rss|atom|api)' => array('vid' => '$1', 'mid' => '$2', 'act' => '$3', '[L]' => TRUE), + // trackback + '([0-9]+)/(.+)/trackback' => array('document_srl' => '$1', 'key' => '$2', 'act' => 'trackback', '[L]' => TRUE), + '([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback' => array('mid' => '$1', 'document_srl' => '$2', 'key' => '$3', 'act' => 'trackback', '[L]' => TRUE), + '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)/(.+)/trackback' => array('vid' => '$1', 'mid' => '$2', 'document_srl' => '$3' , 'key' => '$4', 'act' => 'trackback', '[L]' => TRUE), + // document_srl + '([0-9]+)' => array('document_srl' => '$1', '[L]' => TRUE), + // mid + '([a-zA-Z0-9_]+)/?' => array('mid' => '$1', '[L]' => TRUE), + // mid + document_srl + '([a-zA-Z0-9_]+)/([0-9]+)' => array('mid' => '$1', 'document_srl' => '$2', '[L]' => TRUE), + // vid + mid + '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/' => array('vid' => '$1', 'mid' => '$2', '[L]' => TRUE), + // vid + mid + document_srl + '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([0-9]+)?' => array('vid' => '$1', 'mid' => '$2', 'document_srl' => '$3', '[L]' => TRUE), + // mid + entry title + '([a-zA-Z0-9_]+)/entry/(.+)' => array('mid' => '$1', 'entry' => '$2', '[L]' => TRUE), + // vid + mid + entry title + '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/entry/(.+)' => array('vid' => '$1', 'mid' => '$2', 'entry' => '$3', '[L]' => TRUE), + // shop / vid / [category|product] / identifier + '([a-zA-Z0-9_]+)/([a-zA-Z0-9_]+)/([a-zA-Z0-9_\.-]+)' => array('act' => 'route', 'vid' => '$1', 'type' => '$2', 'identifier'=> '$3', '[L]' => TRUE) + ); + + /** + * Rewrite map + * @var array + */ + private static $rewrite_map = array(); + + /** + * @brief Applys routes. + * @see This function should be called only once + * @return void + */ + public static function proc() + { + $uri = $_SERVER['REQUEST_URI']; + + if (stripos($uri, $_SERVER['SCRIPT_NAME']) === 0) + { + $uri = substr($uri, strlen($_SERVER['SCRIPT_NAME'])); + } + elseif (strpos($uri, dirname($_SERVER['SCRIPT_NAME'])) === 0) + { + $uri = substr($uri, strlen(dirname($_SERVER['SCRIPT_NAME']))); + } + + if ($uri == '/' || empty($uri)) + { + return; + } + + // Get relative path from request uri + $path = parse_url($uri, PHP_URL_PATH); + + // Do some final cleaning of the URI and return it + $path = str_replace(array('//', '../'), '/', trim($path, '/')); + + if(strlen($path) > 0) + { + self::$segments = explode('/', $path); + } + + if(isset(self::$routes[$path])) + { + foreach(self::$routes[$path] as $key => $val) + { + if(strlen($val) > 0) + { + if(substr_compare($val, '$', 0, 1) == 0) + { + $segment_index = (int) substr($val, 1) - 1; + if($segment_index < 0) + { + continue; + } + + Context::set($key, self::$segments[$segment_index], TRUE); + } + else + { + Context::set($key, $val, TRUE); + } + } + else + { + Context::set($key, '', TRUE); + } + } + + return; + } + + $break = FALSE; + + // Apply routes + foreach(self::$routes as $regex => $query) + { + // Stop the routing proccess + if($break) + { + break; + } + if(preg_match('#^' . $regex . '$#', $path, $matches)) + { + foreach($query as $key => $val) + { + // If [L] keyword is defined + if($key == '[L]') + { + // Stop the routing process and don't apply any more rules + $break = TRUE; + continue; + } + + if(strlen($val) > 0) + { + if(substr($val, 0, 1) == '$') + { + $segment_index = (int) substr($val, 1) - 1; + if($segment_index < 0) + { + continue; + } + Context::set($key, self::$segments[$segment_index], TRUE); + } + else + { + Context::set($key, $val, TRUE); + } + } + else + { + Context::set($key, '', TRUE); + } + } + } + } + } + + /** + * @brief Add a rewrite map(s) + * @param array $map + * @return void + */ + public static function setMap($map) + { + self::$rewrite_map = array_merge(self::$rewrite_map, $map); + } + + /** + * @brief Add a route + * @param string $target + * @param array $query + * @return void + */ + public static function add($target, $query) + { + self::$routes[$target] = $query; + } + + /** + * @brief Add multiple routes + * @param array $routes + * @return void + */ + public function adds($routes) + { + self::$routes = array_merge(self::$routes, $routes); + } + + /** + * @brief Get segment from request uri + * @param int $index + * @return string + */ + public static function getSegment($index) + { + return self::$segments[$index - 1]; + } + + + /** + * @brief Get segment from request uri + * @param int $index + * @return string + */ + public static function getSegments() + { + return self::$segments; + } + + /** + * @brief Get route info + * @param string $regex + * @return array + */ + public static function getRoute($regex) + { + return self::$routes[$regex]; + } + + /** + * @brief Get routes list + * @return array + */ + public static function getRoutes() + { + return self::$routes; + } + + /** + * @brief Get routes list + * @param string $regex + * @return boolean + */ + public static function isExistsRoute($regex) + { + return isset(self::$routes[$regex]); + } + + /** + * @brief Makes shortten url + * @param string $regex + * @return string + */ + public static function makePrettyUrl($regex) + { + return self::$rewrite_map[$regex]; + } +} \ No newline at end of file diff --git a/config/config.inc.php b/config/config.inc.php index b27624c4a..2f6ab7f2a 100644 --- a/config/config.inc.php +++ b/config/config.inc.php @@ -299,6 +299,7 @@ if(!defined('__XE_LOADED_CLASS__')) require(_XE_PATH_ . 'classes/xml/XmlJsFilter.class.php'); require(_XE_PATH_ . 'classes/xml/XmlLangParser.class.php'); require(_XE_PATH_ . 'classes/cache/CacheHandler.class.php'); + require(_XE_PATH_ . 'classes/router/Router.class.php'); require(_XE_PATH_ . 'classes/context/Context.class.php'); require(_XE_PATH_ . 'classes/db/DB.class.php'); require(_XE_PATH_ . 'classes/file/FileHandler.class.php');