From afbbf6737707b39841a13c7a92c3d14f1fb4aa53 Mon Sep 17 00:00:00 2001 From: secretr Date: Tue, 6 Dec 2011 16:28:20 +0000 Subject: [PATCH] core URL config refactoring --- e107_core/url/news/rewrite/e_url.php | 267 ------------------ e107_core/url/news/rewrite_extended/e_url.php | 194 ------------- e107_core/url/search/rewrite/e_url.php | 47 --- e107_core/url/system/rewrite/e_url.php | 49 ---- e107_core/url/user/rewrite/e_url.php | 98 ------- 5 files changed, 655 deletions(-) delete mode 100644 e107_core/url/news/rewrite/e_url.php delete mode 100644 e107_core/url/news/rewrite_extended/e_url.php delete mode 100644 e107_core/url/search/rewrite/e_url.php delete mode 100644 e107_core/url/system/rewrite/e_url.php delete mode 100644 e107_core/url/user/rewrite/e_url.php diff --git a/e107_core/url/news/rewrite/e_url.php b/e107_core/url/news/rewrite/e_url.php deleted file mode 100644 index b39f67a5a..000000000 --- a/e107_core/url/news/rewrite/e_url.php +++ /dev/null @@ -1,267 +0,0 @@ - array( - 'allowMain' => true, - 'noSingleEntry' => false, // [optional] default false; disallow this module to be shown via single entry point when this config is used - 'legacy' => '{e_BASE}news.php', // [optional] default empty; if it's a legacy module (no single entry point support) - URL to the entry point script - 'format' => 'path', // get|path - notify core for the current URL format, if set to 'get' rules will be ignored - 'selfParse' => true, // [optional] default false; use only this->parse() method, no core routine URL parsing - 'selfCreate' => true, // [optional] default false; use only this->create() method, no core routine URL creating - 'defaultRoute' => 'list/items', // [optional] default empty; route (no leading module) used when module is found with no additional controller/action information e.g. /news/ - 'urlSuffix' => '.html', // [optional] default empty; string to append to the URL (e.g. .html) - ), - ); - } - - /** - * When returning array, module or it's corresponding alias will be prefixed - * Create link so that it can be mapped by the parse() method - * - view/item?id=xxx -> news/xxx - * - list/items[?page=xxx] -> news[?page=xxx] - * - list/category?id=xxx[&page=xxx] -> news/Category/xxx?page=xxx - * - list/category?id=0[&page=xxx] -> news?page=xxx - * - list/short?id=xxx[&page=xxx] -> news/Short/xxx?page=xxx - * - list/category?id=xxx[&page=xxx] -> news?page=xxx - * - list/day?id=xxx -> news/Day-id - * - list/month?id=xxx -> news/Month-id - * - list/year?id=xxx -> news/Year-id - * - list/nextprev?route=xxx -> PARSED_ROUTE?page=[FROM] (recursive parse() call) - */ - public function create($route, $params = array(), $options = array()) - { - - if('--FROM--' != vartrue($params['page'])) $page = varset($params['page']) ? intval($params['page']) : '0'; - else $page = '--FROM--'; - if(!$route) $route = 'list/items'; - - if(is_string($route)) $route = explode('/', $route, 2); - $r = array(); - $parm = array(); - - if($route[0] == 'view') - { - ## news are passing array as it is retrieved from the DB, map vars to proper values - if(isset($params['news_id']) && !empty($params['news_id'])) $params['id'] = $params['news_id']; - if(isset($params['news_title']) && !empty($params['news_title'])) $params['id'] = $params['news_title']; // TODO - news_sef - - switch ($route[1]) - { - case 'item': - $r[0] = $params['id']; // news/ID - break; - - default: - - break; - } - } - elseif($route[0] == 'list') - { - ## news are passing array as it is retrieved from the DB, map vars to proper values - if(isset($params['category_id']) && !empty($params['category_id'])) $params['id'] = $params['category_id']; - if(isset($params['category_name']) && !empty($params['category_name'])) $params['name'] = $params['category_name']; // TODO - news_sef - - switch ($route[1]) - { - - case 'items': - $r[0] = ''; - if($page) $parm = array('page' => $page); // news?page=xxx - break; - - case 'category': - case 'short': - if(!vartrue($params['id'])) - { - $r[0] = ''; - if($page) $parm = array('page' => $page); // news?page=xxx - } - else - { - // news/Category/Category-Name?page=xxx - // news/Short/Category-Name?page=xxx - $r[0] = $route[1] == 'category' ? 'Category' : 'Short'; - $r[1] = $params['name'] ? $params['name'] : $params['id']; - if($page) $parm = array('page' => $page); - } - break; - - case 'day': - case 'month': - case 'year': - $r = array($route[1], intval($params['id'])); - if($page) $parm = array('page' => $page); - break; - - default: - - break; - } - } - - if(empty($r)) return false; - - return array($r, $parm); - } - - /** - * Manually parse request - * Pathinfo DOESN'T contain leading 'module' (e.g news or alias 'Blog') - * Retruned route shouldn't contain module as well, unless you manipulate $request directly and set $request->routed to true - * Mapped URLs: - * - news/News-Item -> extend.xxx - * - news/Category/Category-Name?page=10 -> list.xxx.10 - * - news/Day|Month-xxx -> day|month-xxx - */ - public function parse($pathInfo, $params, $request, $router, $config) - { - $page = $params['page'] ? intval($params['page']) : '0'; - if(!$pathInfo) - { - ## this var is used by default from legacy() method - ## you may override legacy() method - ## Keep in mind legacy() is not triggered at all if parse() returns false or $request->routed is set to true - $this->legacyQueryString = $page ? 'default.0.'.$page : ''; - return $config['defaultRoute']; - } - - ## no controller/action pair - news item view - map to extend.xxx - if(strpos($pathInfo, '/') === false) - { - $route = 'view/item'; - $id = is_numeric($pathInfo) ? intval($pathInfo) : $this->itemIdByTitle($pathInfo); - if(!$id) - { - ## let news.php handle missing news item - $this->legacyQueryString = 'extend.0'; - return $route; - } - $this->legacyQueryString = 'extend.'.$id; - return $route; - } - - $parts = explode('/', $pathInfo, 2); - - switch (strtolower($parts[0])) - { - # map to list.xxx.xxx - case 'short': - case 'category': - # Hardcoded leading string for categories, could be pref or LAN constant - if(!vartrue($parts[1])) - { - ## force not found as we don't want to have duplicated content (default.0.xxx) - return false; - } - else - { - if(!is_numeric($parts[1])) $id = $this->categoryIdByTitle($parts[1]); - else $id = intval($parts[1]); - } - if(!$id) - { - # let news.php handle it - $id = 0; - } - $action = $parts[0] == 'short' ? 'cat' : 'list'; - $this->legacyQueryString = $action.'.'.$id.'.'.$page; - return 'item/list'; - break; - - # could be pref or LAN constant - case 'day': - if(!vartrue($parts[1])) $id = 0; - else $id = intval($parts[1]); - - $this->legacyQueryString = 'day.'.$id.'.'.$page; - return 'list/day'; - break; - - # could be pref or LAN constant - case 'month': - if(!vartrue($parts[1])) $id = 0; - else $id = intval($parts[1]); - - $this->legacyQueryString = 'month.'.$id.'.'.$page; - return 'list/month'; - break; - - # could be pref or LAN constant - not supported yet - case 'year': - if(!vartrue($parts[1])) $id = 0; - else $id = intval($parts[1]); - - $this->legacyQueryString = 'year.'.$id.'.'.$page; - //return 'list/year'; - break; - - # force not found - default: - return false; - break; - } - - return false; - } - - /** - * Admin callback - * Language file not loaded as all language data is inside the lan_eurl.php (loaded by default on administration URL page) - */ - public function admin() - { - // static may be used for performance - static $admin = array( - 'labels' => array( - 'name' => LAN_EURL_CORE_NEWS, // Module name - 'label' => LAN_EURL_NEWS_REWRITE_LABEL, // Current profile name - 'description' => LAN_EURL_NEWS_REWRITE_DESCR, // - ), - 'form' => array(), // Under construction - additional configuration options - 'callbacks' => array(), // Under construction - could be used for e.g. URL generator functionallity - ); - - return $admin; - } - - ### CUSTOM METHODS ### - - //retrieve news_id by Title (XXX - news_sef column, equals to news_title if not set explicit) - public function itemIdByTitle($id) - { - $sql = e107::getDb('url'); - $tp = e107::getParser(); - $id = $tp->toDB($id); - if($sql->db_Select('news', 'news_id', "news_title='{$id}'")) // TODO - it'll be news_url (new) field - { - $id = $sql->db_Fetch(); - return $id['news_id']; - } - return false; - } - - //retrieve category_id by Title (XXX - category_sef column, equals to category_name if not set explicit) - public function categoryIdByTitle($id) - { - $sql = e107::getDb('url'); - $tp = e107::getParser(); - $id = $tp->toDB($id); - if($sql->db_Select('news_category', 'category_id', "category_name='{$id}'")) // TODO - it'll be category_url (new) field - { - $id = $sql->db_Fetch(); - return $id['category_id']; - } - return false; - } -} diff --git a/e107_core/url/news/rewrite_extended/e_url.php b/e107_core/url/news/rewrite_extended/e_url.php deleted file mode 100644 index ab5607fd2..000000000 --- a/e107_core/url/news/rewrite_extended/e_url.php +++ /dev/null @@ -1,194 +0,0 @@ - array( - 'legacy' => '{e_BASE}news.php', // [optional] default empty; if it's a legacy module (no single entry point support) - URL to the entry point script; override per rule is allowed - 'format' => 'path', // get|path - notify core for the current URL format, if set to 'get' rules will be ignored - 'defaultRoute' => 'list/items', // [optional] default empty; route (no leading module) used when module is found with no additional controller/action information e.g. /news/ - 'urlSuffix' => '', - 'allowMain' => true, - - ### default vars mapping (create URL), override per rule is allowed - 'mapVars' => array( - 'news_id' => 'id', - 'news_title' => 'name', - ), - - ### Numerical array containing allowed vars by default (create URL, used for legacyQuery parsing in parse routine as well), - ### false means - disallow all vars beside those required by the rules - ### Override per rule is allowed - 'allowVars' => false, - - ### Best news - you don't need to write one and the same - ### regex over and over again. Even better news - you might avoid - ### writing regex at all! Just use the core regex templates, they - ### should fit almost every case. - ### Here is a test custom regex template: - 'varTemplates' => array('testIt' => '[\d]+'), - - /* Predefined Core regex templates, see usage below - 'az' => '[A-Za-z]+', // NOTE - it won't match non-latin word characters! - 'alphanum' => '[\w\pL]+', - 'sefsecure' => '[\w\pL.\-\s!,]+', - 'secure' => '[^\/\'"\\<%]+', - 'number' => '[\d]+', - 'username' => '[\w\pL.\-\s!,]+', - 'azOptional' => '[A-Za-z]{0,}', - 'alphanumOptional' => '[\w\pL]{0,}', - 'sefsecureOptional' => '[\w\pL.\-\s!,]{0,}', - 'secureOptional' => '[^\/\'"\\<%]{0,}', - 'numberOptional' => '[\d]{0,}', - 'usernameOptional' => '[\w\pL.\-\s!,]{0,}', - */ - ), - - 'rules' => array( - ### simple matches first - PERFORMANCE - '' => array('list/items', 'allowVars' => array('page'), 'legacyQuery' => 'default.0.{page}', ), - 'Category' => array('list/items', 'allowVars' => array('page'), 'legacyQuery' => 'default.0.{page}', ), - - ## URL with ID and Title - no DB call, balanced performance, name optional - ## Demonstrating the usage of custom user defined regex template defined above - 'testIt' - 'Category//' => array('list/category', 'allowVars' => array('page'), 'mapVars' => array('category_id' => 'id', 'category_name' => 'name'), 'legacyQuery' => 'list.{id}.{page}'), - - ## URL with Title only - prettiest and slowest! Example with direct regex - no templates - //'Category/' => array('list/category', 'allowVars' => array('page'), 'mapVars' => array('category_name' => 'name'), 'legacyQuery' => 'list.{name}.{page}', 'parseCallback' => 'categoryIdByTitle'), - - ## URL with ID only - best performance, fallback when no sef name provided - 'Category/' => array('list/category', 'allowVars' => array('page'), 'legacyQuery' => 'list.{id}.{page}', 'mapVars' => array('category_id' => 'id')), - - ### View item requested by id or string, if you remove the catch ALL example, uncomment at least on row from this block - ### leading category name example - could be enabled together with the next example to handle creating of URLs without knowing the category title - // 'View//' => array('view/item', 'mapVars' => array('news_title' => 'name', 'category_name' => 'category'), 'legacyQuery' => 'extend.{name}', 'parseCallback' => 'itemIdByTitle'), - // to be noted here - value 'name' is replaced by item id within the callback method; TODO replace news_title with news_sef field - // 'View/' => array('view/item', 'mapVars' => array('news_title' => 'name', 'news_id' => 'id'), 'legacyQuery' => 'extend.{name}', 'parseCallback' => 'itemIdByTitle'), - // 'View/' => array('view/item', 'mapVars' => array('news_id' => 'id'), 'legacyQuery' => 'extend.{id}'), - - ## URL with ID and Title - no DB call, balanced performance! - 'Short//' => array('list/short', 'allowVars' => array('page'), 'mapVars' => array('category_id' => 'id', 'category_name' => 'name'), 'legacyQuery' => 'cat.{id}.{page}'), - ## fallback when name is not provided - 'Short/' => array('list/short', 'allowVars' => array('page'), 'mapVars' => array('category_id' => 'id'), 'legacyQuery' => 'cat.{id}.{page}'), - - // less used after - //'Brief/' => array('list/short', 'allowVars' => array('page'), 'legacyQuery' => 'cat.{id}.{page}', 'mapVars' => array('category_id' => 'id')), - 'Day/' => array('list/day', 'allowVars' => array('page'), 'legacyQuery' => 'day.{id}.{page}'), - 'Month/' => array('list/month', 'allowVars' => array('page'), 'legacyQuery' => 'month.{id}.{page}'), - //'Year/' => array('list/year', 'allowVars' => array('page'), 'legacyQuery' => 'year.{id}.{page}'), not supported yet - - ### View news item - kinda catch all - very bad performance when News is chosen as default namespace - two additional DB queries on every site call! - ## Leading category name - uncomment to enable - '/' => array('view/item', 'mapVars' => array('news_title' => 'name', 'mapVars' => array('category_name' => 'category', 'news_title' => 'name', 'news_id' => 'id'), 'category_name' => 'category'), 'legacyQuery' => 'extend.{name}', 'parseCallback' => 'itemIdByTitle'), - // Base location as item view - fallback if category sef is missing - '' => array('view/item', 'mapVars' => array('news_title' => 'name'), 'mapVars' => array('news_id' => 'id', 'news_title' => 'name'), 'legacyQuery' => 'extend.{name}', 'parseCallback' => 'itemIdByTitle'), - // fallback if news sef is missing - 'View/' => array('view/item', 'mapVars' => array('news_id' => 'id'), 'legacyQuery' => 'extend.{id}'), - - ) - ); - } - - /** - * Query mapping in format route?params: - * - item/vew?id=xxx -> ?extend.id - * - list/items[?page=xxx] -> default.0.page - * - list/category?id=xxx[&page=xxx] -> list.id.page - * - list/category?id=0[&page=xxx] -> default.0.page - * - list/short?id=xxx[&page=xxx] -> cat.id.page - * - list/day?id=xxx -> ?day-id - * - list/month?id=xxx -> ?month-id - * - list/year?id=xxx -> ?year-id - * - list/nextprev?route=xxx -> PARSED_ROUTE.[FROM] (recursive parse() call) - */ - - - /** - * Admin callback - * Language file not loaded as all language data is inside the lan_eurl.php (loaded by default on administration URL page) - */ - public function admin() - { - // static may be used for performance - static $admin = array( - 'labels' => array( - 'name' => LAN_EURL_CORE_NEWS, // Module name - 'label' => LAN_EURL_NEWS_REWRITEX_LABEL, // Current profile name - 'description' => LAN_EURL_NEWS_REWRITEX_DESCR, // - ), - 'form' => array(), // Under construction - additional configuration options - 'callbacks' => array(), // Under construction - could be used for e.g. URL generator functionallity - ); - - return $admin; - } - - ### CUSTOM METHODS ### - - /** - * view/item by name callback - * @param eRequest $request - */ - public function itemIdByTitle(eRequest $request) - { - $name = $request->getRequestParam('name'); - if(($id = $request->getRequestParam('id'))) - { - $request->setRequestParam('name', $id); - return; - } - elseif(!$name) return; - elseif(is_numeric($name)) - { - return; - } - - $sql = e107::getDb('url'); - $name = e107::getParser()->toDB($name); - if($sql->db_Select('news', 'news_id', "news_title='{$name}'")) // TODO - it'll be news_sef (new) field - { - $name = $sql->db_Fetch(); - $request->setRequestParam('name', $name['news_id']); - } - else $request->setRequestParam('name', 0); - } - - /** - * list/items by name callback - * @param eRequest $request - */ - public function categoryIdByTitle(eRequest $request) - { - $name = $request->getRequestParam('name'); - if(($id = $request->getRequestParam('id'))) - { - $request->setRequestParam('name', $id); - return; - } - elseif(!$name) return; - elseif(is_numeric($name)) - { - return; - } - - $sql = e107::getDb('url'); - $id = e107::getParser()->toDB($name); - if($sql->db_Select('news_category', 'category_id', "category_name='{$name}'")) // TODO - it'll be category_sef (new) field - { - $name = $sql->db_Fetch(); - $request->setRequestParam('name', $name['category_id']); - } - else $request->setRequestParam('name', 0); - } -} \ No newline at end of file diff --git a/e107_core/url/search/rewrite/e_url.php b/e107_core/url/search/rewrite/e_url.php deleted file mode 100644 index 29e373744..000000000 --- a/e107_core/url/search/rewrite/e_url.php +++ /dev/null @@ -1,47 +0,0 @@ - array( - 'legacy' => '{e_BASE}search.php', // [optional] default empty; if it's a legacy module (no single entry point support) - URL to the entry point script to be included - 'format' => 'path', // get|path - notify core for the current URL format, if set to 'get' rules will be ignored - 'defaultRoute' => 'index/index', // [optional] default empty; route (no leading module) used when module is found with no additional controller/action information e.g. /news/ - - ), - - // rule set array - 'rules' => array( - '' => array('index/index', 'defaultVars' => array('id' => 0)), - ) - ); - } - - /** - * Admin callback - * Language file not loaded as all language data is inside the lan_eurl.php (loaded by default on administration URL page) - */ - public function admin() - { - // static may be used for performance - static $admin = array( - 'labels' => array( - 'name' => LAN_EURL_CORE_SEARCH, // Module name - 'label' => LAN_EURL_SEARCH_REWRITE_LABEL, // Current profile name - 'description' => LAN_EURL_SEARCH_REWRITE_DESCR, // - ), - 'form' => array(), // Under construction - additional configuration options - 'callbacks' => array(), // Under construction - could be used for e.g. URL generator functionallity - ); - - return $admin; - } -} diff --git a/e107_core/url/system/rewrite/e_url.php b/e107_core/url/system/rewrite/e_url.php deleted file mode 100644 index df9e44111..000000000 --- a/e107_core/url/system/rewrite/e_url.php +++ /dev/null @@ -1,49 +0,0 @@ - array( - 'allowMain' => true, - 'format' => 'path', - 'defaultRoute' => 'error/notfound', - 'errorRoute' => 'error/notfound', - - ), - - // rule set array - 'rules' => array( - 'error404' => 'error/notfound', - 'hello' => 'error/hello-world', - ) - ); - } - - /** - * Admin callback - * Language file not loaded as all language data is inside the lan_eurl.php (loaded by default on administration URL page) - */ - public function admin() - { - // static may be used for performance - static $admin = array( - 'labels' => array( - 'name' => LAN_EURL_CORE_SYSTEM, // Module name - 'label' => LAN_EURL_SYSTEM_REWRITE_LABEL, // Current profile name - 'description' => LAN_EURL_SYSTEM_REWRITE_DESCR, // - ), - 'form' => array(), // Under construction - additional configuration options - 'callbacks' => array(), // Under construction - could be used for e.g. URL generator functionallity - ); - - return $admin; - } -} diff --git a/e107_core/url/user/rewrite/e_url.php b/e107_core/url/user/rewrite/e_url.php deleted file mode 100644 index 7262b8426..000000000 --- a/e107_core/url/user/rewrite/e_url.php +++ /dev/null @@ -1,98 +0,0 @@ - array( - 'noSingleEntry' => false, // [optional] default false; disallow this module to be shown via single entry point when this config is used - 'legacy' => '{e_BASE}user.php', // [optional] default empty; if it's a legacy module (no single entry point support) - URL to the entry point script to be included - 'format' => 'path', // get|path - notify core for the current URL format, if set to 'get' rules will be ignored - 'selfParse' => false, // [optional] default false; use only this->parse() method, no core routine URL parsing - 'selfCreate' => false, // [optional] default false; use only this->create() method, no core routine URL creating - 'defaultRoute' => 'myprofile/view', // [optional] default empty; route (no leading module) used when module is found with no additional controller/action information e.g. /news/ - 'errorRoute' => '', // [optional] default empty; route (no leading module) used when module is found but no inner route is matched, leave empty to force error 404 page - 'urlSuffix' => '', // [optional] default empty; string to append to the URL (e.g. .html) - 'mapVars' => array( // vars mapping (create URL) - 'user_id' => 'id', - 'user_name' => 'name', - ), - 'allowVars' => false, // allowed vars (create URL, used for legacyQuery parsing in parse routine as well), false means - disallow all vars beside those required by the rules - 'legacyQuery' => '' // default legacy query string template, null to disable, override possible by rule - ), - - // rule set array - 'rules' => array( - // simple matches first - PERFORMANCE - '' => array('myprofile/view', 'defaultVars' => array('id' => 0)), - 'Settings' => array('myprofile/edit', 'defaultVars' => array('id' => 0), 'legacy' => '{e_BASE}usersettings.php'), - 'List' => array('profile/list', 'allowVars' => array('page'), 'legacyQuery' => '{page}'), - 'Login' => array('login/index', 'legacy' => '{e_BASE}login.php'), - 'Register' => array('register/index', 'legacy' => '{e_BASE}signup.php'), - - // Regex involved next - //'' => array('profile/view', 'legacyQuery' => 'id.{id}'), - 'Edit/' => array('profile/edit', 'legacy' => '{e_BASE}usersettings.php', 'legacyQuery' => '{id}'), - - // Named requests - important to be in the end in this order! - 'Edit/' => array('profile/edit', 'legacy' => '{e_BASE}usersettings.php', 'legacyQuery' => '{id}', 'parseCallback' => 'idByName'), - // Last one - close to catch all! - '' => array('profile/view', 'legacyQuery' => 'id.{id}', 'parseCallback' => 'idByName'), - ) - ); - } - - /** - * Admin callback - * Language file not loaded as all language data is inside the lan_eurl.php (loaded by default on administration URL page) - */ - public function admin() - { - // static may be used for performance - static $admin = array( - 'labels' => array( - 'name' => LAN_EURL_CORE_USER, // Module name - 'label' => LAN_EURL_USER_REWRITE_LABEL, // Current profile name - 'description' => LAN_EURL_USER_REWRITE_DESCR, // - ), - 'form' => array(), // Under construction - additional configuration options - 'callbacks' => array(), // Under construction - could be used for e.g. URL generator functionallity - ); - - return $admin; - } - - ### CUSTOM METHODS ### - - /** - * profile/edit & profile/view callback - * @param eRequest $request - */ - public function idByName(eRequest $request) - { - $name = $request->getRequestParam('name'); - if(!$name) return; - - // if id only is passed, don't do DB query - if(is_numeric($name)) - { - $request->setRequestParam('id', $name)->setRequestParam('name', null); - return; - } - - $sql = e107::getDb('url'); - $name = e107::getParser()->toDB($name); - if($sql->db_Select('user', 'user_id', "user_name='{$name}'")) // XXX - new user_sef field? Discuss. - { - $name = $sql->db_Fetch(); - $request->setRequestParam('id', $name['user_id']); - } - } -}