diff --git a/administrator/components/com_contact/config.xml b/administrator/components/com_contact/config.xml index 51b8d06d33273..2d971a8f72a5b 100644 --- a/administrator/components/com_contact/config.xml +++ b/administrator/components/com_contact/config.xml @@ -983,6 +983,20 @@ + + + + + +
JGLOBAL_SEF_ADVANCED_LEGACY + + + + +
JGLOBAL_SEF_ADVANCED_LEGACY + + + + +
noIDs = (bool) $params->get('sef_ids'); $categories = new JComponentRouterViewconfiguration('categories'); $categories->setKey('id'); $this->registerView($categories); @@ -44,6 +48,7 @@ public function __construct($app = null, $menu = null) if ($params->get('sef_advanced', 0)) { $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); } else { @@ -66,7 +71,20 @@ public function getCategorySegment($id, $query) if ($category) { - return array_reverse($category->getPath()); + if ($this->noIDs) + { + $path = array_reverse($category->getPath(), true); + foreach ($path as &$segment) + { + list($id, $segment) = explode(':', $segment, 2); + } + + return $path; + } + else + { + return array_reverse($category->getPath(), true); + } } return array(); @@ -95,7 +113,28 @@ public function getCategoriesSegment($id, $query) */ public function getContactSegment($id, $query) { - return array($id); + if ($this->noIDs) + { + if (strpos($id, ':')) + { + list($void, $segment) = explode(':', $id, 2); + + return array($void => $segment); + } + else + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('alias')) + ->from($dbquery->qn('#__contact_details')) + ->where('id = ' . $dbquery->q((int) $id)); + $db->setQuery($dbquery); + + return array($id => $id . ':' . $db->loadResult()); + } + } + + return array((int) $id => $id); } /** @@ -114,9 +153,19 @@ public function getCategoryId($segment, $query) foreach ($category->getChildren() as $child) { - if ($child->id == (int) $segment) + if ($this->noIDs) { - return $child->id; + if ($child->alias == $segment) + { + return $child->id; + } + } + else + { + if ($child->id == (int) $segment) + { + return $child->id; + } } } } @@ -147,6 +196,19 @@ public function getCategoriesId($segment, $query) */ public function getContactId($segment, $query) { + if ($this->noIDs) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('id')) + ->from($dbquery->qn('#__contact_details')) + ->where('alias = ' . $dbquery->q($segment)) + ->where('catid = ' . $dbquery->q($query['id'])); + $db->setQuery($dbquery); + + return (int) $db->loadResult(); + } + return (int) $segment; } } diff --git a/components/com_content/router.php b/components/com_content/router.php index c25a607d6c707..351b14cc3668f 100644 --- a/components/com_content/router.php +++ b/components/com_content/router.php @@ -16,6 +16,8 @@ */ class ContentRouter extends JComponentRouterView { + protected $noIDs = false; + /** * Content Component router constructor * @@ -24,6 +26,8 @@ class ContentRouter extends JComponentRouterView */ public function __construct($app = null, $menu = null) { + $params = JComponentHelper::getParams('com_content'); + $this->noIDs = (bool) $params->get('sef_ids'); $categories = new JComponentRouterViewconfiguration('categories'); $categories->setKey('id'); $this->registerView($categories); @@ -46,6 +50,7 @@ public function __construct($app = null, $menu = null) if ($params->get('sef_advanced', 0)) { $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); } else { @@ -68,7 +73,20 @@ public function getCategorySegment($id, $query) if ($category) { - return array_reverse($category->getPath()); + if ($this->noIDs) + { + $path = array_reverse($category->getPath(), true); + foreach ($path as &$segment) + { + list($id, $segment) = explode(':', $segment, 2); + } + + return $path; + } + else + { + return array_reverse($category->getPath(), true); + } } return array(); @@ -97,7 +115,28 @@ public function getCategoriesSegment($id, $query) */ public function getArticleSegment($id, $query) { - return array($id); + if ($this->noIDs) + { + if (strpos($id, ':')) + { + list($void, $segment) = explode(':', $id, 2); + + return array($void => $segment); + } + else + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('alias')) + ->from($dbquery->qn('#__content')) + ->where('id = ' . $dbquery->q($id)); + $db->setQuery($dbquery); + + return array($id => $id . ':' . $db->loadResult()); + } + } + + return array((int) $id => $id); } /** @@ -116,9 +155,19 @@ public function getCategoryId($segment, $query) foreach ($category->getChildren() as $child) { - if ($child->id == (int) $segment) + if ($this->noIDs) { - return $child->id; + if ($child->alias == $segment) + { + return $child->id; + } + } + else + { + if ($child->id == (int) $segment) + { + return $child->id; + } } } } @@ -149,6 +198,19 @@ public function getCategoriesId($segment, $query) */ public function getArticleId($segment, $query) { + if ($this->noIDs) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('id')) + ->from($dbquery->qn('#__content')) + ->where('alias = ' . $dbquery->q($segment)) + ->where('catid = ' . $dbquery->q($query['id'])); + $db->setQuery($dbquery); + + return (int) $db->loadResult(); + } + return (int) $segment; } } diff --git a/components/com_newsfeeds/router.php b/components/com_newsfeeds/router.php index 5435e097474e7..81b1d0ed60f50 100644 --- a/components/com_newsfeeds/router.php +++ b/components/com_newsfeeds/router.php @@ -16,6 +16,8 @@ */ class NewsfeedsRouter extends JComponentRouterView { + protected $noIDs = false; + /** * Newsfeeds Component router constructor * @@ -24,6 +26,8 @@ class NewsfeedsRouter extends JComponentRouterView */ public function __construct($app = null, $menu = null) { + $params = JComponentHelper::getParams('com_newsfeeds'); + $this->noIDs = (bool) $params->get('sef_ids'); $categories = new JComponentRouterViewconfiguration('categories'); $categories->setKey('id'); $this->registerView($categories); @@ -43,6 +47,7 @@ public function __construct($app = null, $menu = null) if ($params->get('sef_advanced', 0)) { $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); } else { @@ -64,7 +69,20 @@ public function getCategorySegment($id, $query) $category = JCategories::getInstance($this->getName())->get($id); if ($category) { - return array_reverse($category->getPath()); + if ($this->noIDs) + { + $path = array_reverse($category->getPath(), true); + foreach ($path as &$segment) + { + list($id, $segment) = explode(':', $segment, 2); + } + + return $path; + } + else + { + return array_reverse($category->getPath(), true); + } } return array(); @@ -93,7 +111,28 @@ public function getCategoriesSegment($id, $query) */ public function getNewsfeedSegment($id, $query) { - return array($id); + if ($this->noIDs) + { + if (strpos($id, ':')) + { + list($void, $segment) = explode(':', $id, 2); + + return array($void => $segment); + } + else + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('alias')) + ->from($dbquery->qn('#__newsfeeds')) + ->where('id = ' . $dbquery->q((int) $id)); + $db->setQuery($dbquery); + + return array($id => $id . ':' . $db->loadResult()); + } + } + + return array((int) $id => $id); } /** @@ -112,9 +151,19 @@ public function getCategoryId($segment, $query) foreach ($category->getChildren() as $child) { - if ($child->id == (int) $segment) + if ($this->noIDs) { - return $child->id; + if ($child->alias == $segment) + { + return $child->id; + } + } + else + { + if ($child->id == (int) $segment) + { + return $child->id; + } } } } @@ -145,6 +194,19 @@ public function getCategoriesId($segment, $query) */ public function getNewsfeedId($segment, $query) { + if ($this->noIDs) + { + $db = JFactory::getDbo(); + $dbquery = $db->getQuery(true); + $dbquery->select($dbquery->qn('id')) + ->from($dbquery->qn('#__newsfeeds')) + ->where('alias = ' . $dbquery->q($segment)) + ->where('catid = ' . $dbquery->q($query['id'])); + $db->setQuery($dbquery); + + return (int) $db->loadResult(); + } + return (int) $segment; } } diff --git a/components/com_users/router.php b/components/com_users/router.php index 73fee2ac22bf3..61411937327d1 100644 --- a/components/com_users/router.php +++ b/components/com_users/router.php @@ -41,6 +41,7 @@ public function __construct($app = null, $menu = null) if ($params->get('sef_advanced', 0)) { $this->attachRule(new JComponentRouterRulesStandard($this)); + $this->attachRule(new JComponentRouterRulesNomenu($this)); } else { diff --git a/libraries/cms/component/router/rules/menu.php b/libraries/cms/component/router/rules/menu.php index b338ee23a2acb..7d7a9853087c4 100644 --- a/libraries/cms/component/router/rules/menu.php +++ b/libraries/cms/component/router/rules/menu.php @@ -97,7 +97,7 @@ public function preprocess(&$query) $query['Itemid'] = $this->lookup[$language][$view . $layout]; return; } - foreach ($ids as $id) + foreach ($ids as $id => $segment) { if (isset($this->lookup[$language][$view . $layout][(int) $id])) { diff --git a/libraries/cms/component/router/rules/nomenu.php b/libraries/cms/component/router/rules/nomenu.php index f0d269d23b2d7..eb33b17bf9797 100644 --- a/libraries/cms/component/router/rules/nomenu.php +++ b/libraries/cms/component/router/rules/nomenu.php @@ -90,17 +90,37 @@ public function parse(&$segments, &$vars) */ public function build(&$query, &$segments) { - if (!isset($query['Itemid']) && isset($query['view'])) + $menu_found = false; + + if (isset($query['Itemid'])) + { + $item = $this->router->menu->getItem($query['Itemid']); + + if (!isset($query['option']) || ($item && $item->query['option'] == $query['option'])) + { + $menu_found = true; + } + } + + if (!$menu_found && isset($query['view'])) { $views = $this->router->getViews(); if (isset($views[$query['view']])) { + $view = $views[$query['view']]; $segments[] = $query['view']; - if ($views[$query['view']]->key) + if ($view->key && isset($query[$view->key])) { - $key = $views[$query['view']]->key; - $segments[] = str_replace(':', '-', $query[$key]); + if (is_callable(array($this->router, 'get' . ucfirst($view->name) . 'Segment'))) + { + $result = call_user_func_array(array($this->router, 'get' . ucfirst($view->name) . 'Segment'), array($query[$view->key], $query)); + $segments[] = str_replace(':', '-', array_shift($result)); + } + else + { + $segments[] = str_replace(':', '-', $query[$view->key]); + } unset($query[$views[$query['view']]->key]); } unset($query['view']); diff --git a/libraries/cms/component/router/rules/standard.php b/libraries/cms/component/router/rules/standard.php index 6f47c09c50b4c..32f8848a2cfde 100644 --- a/libraries/cms/component/router/rules/standard.php +++ b/libraries/cms/component/router/rules/standard.php @@ -235,11 +235,11 @@ public function build(&$query, &$segments) $ids = array_shift($path); if ($views[$view]->nestable) { - foreach (array_reverse($ids, true) as $id) + foreach (array_reverse($ids, true) as $id => $segment) { if ($found2) { - $segments[] = str_replace(':', '-', $id); + $segments[] = str_replace(':', '-', $segment); } else { @@ -258,7 +258,7 @@ public function build(&$query, &$segments) } else { - $segments[] = str_replace(':', '-', $ids[0]); + $segments[] = str_replace(':', '-', array_shift($ids)); } } } @@ -284,8 +284,12 @@ public function build(&$query, &$segments) } unset($query[$views[$view]->parent_key]); } - unset($query['layout']); - unset($query[$views[$query['view']]->key]); - unset($query['view']); + + if ($found) + { + unset($query['layout']); + unset($query[$views[$query['view']]->key]); + unset($query['view']); + } } } diff --git a/libraries/legacy/categories/categories.php b/libraries/legacy/categories/categories.php index 6be38e9f30a10..19c7d944baf5f 100644 --- a/libraries/legacy/categories/categories.php +++ b/libraries/legacy/categories/categories.php @@ -732,7 +732,7 @@ public function setParent($parent) $this->_path = $parent->getPath(); } - $this->_path[] = $this->id . ':' . $this->alias; + $this->_path[$this->id] = $this->id . ':' . $this->alias; } if (count($parent->_children) > 1) diff --git a/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php index d1455804292a6..da232b4489788 100644 --- a/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php +++ b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php @@ -135,28 +135,28 @@ public function casesGetPath() $cases[] = array(array('view' => 'categories'), array('categories' => array())); // View with parent and children - $cases[] = array(array('view' => 'category', 'id' => '9'), array('category' => array('9:uncategorised'), 'categories' => array('9:uncategorised'))); + $cases[] = array(array('view' => 'category', 'id' => '9'), array('category' => array(9 => '9:uncategorised'), 'categories' => array(9 => '9:uncategorised'))); //View with parent, no children $cases[] = array(array('view' => 'article', 'id' => '42:question-for-everything', 'catid' => '9'), array( - 'article' => array('42:question-for-everything'), - 'category' => array('9:uncategorised'), - 'categories' => array('9:uncategorised') + 'article' => array(42 => '42:question-for-everything'), + 'category' => array(9 => '9:uncategorised'), + 'categories' => array(9 => '9:uncategorised') ) ); //View with parent, no children and nested view $cases[] = array(array('view' => 'article', 'id' => '42:question-for-everything', 'catid' => '20'), array( - 'article' => array('42:question-for-everything'), - 'category' => array('20:extensions', - '19:joomla', - '14:sample-data-articles' + 'article' => array(42 => '42:question-for-everything'), + 'category' => array(20 => '20:extensions', + 19 => '19:joomla', + 14 => '14:sample-data-articles' ), - 'categories' => array('20:extensions', - '19:joomla', - '14:sample-data-articles' + 'categories' => array(20 => '20:extensions', + 19 => '19:joomla', + 14 => '14:sample-data-articles' ) ) ); diff --git a/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php index 029d819fa4893..346e1626d370f 100644 --- a/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php +++ b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php @@ -133,10 +133,10 @@ public function testParse() public function testBuild() { // Test if the rule is properly skipped if an Itemid is set - $query = array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer', 'Itemid' => '23'); + $query = array('option' => 'com_test', 'view' => 'article', 'id' => '42:the-answer', 'Itemid' => '42'); $segments = array(); $this->object->build($query, $segments); - $this->assertEquals(array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer', 'Itemid' => '23'), $query); + $this->assertEquals(array('option' => 'com_test', 'view' => 'article', 'id' => '42:the-answer', 'Itemid' => '42'), $query); $this->assertEquals(array(), $segments); // Test if a false view is properly not treated diff --git a/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php b/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php index cb0e56ea398ba..6c23f77e9319f 100644 --- a/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php +++ b/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php @@ -60,7 +60,7 @@ public function getCategorySegment($id, $query) if ($category) { - return array_reverse($category->getPath()); + return array_reverse($category->getPath(), true); } return array(); @@ -91,7 +91,7 @@ public function getCategoriesSegment($id, $query) */ public function getArticleSegment($id, $query) { - return array($id); + return array((int) $id => $id); } }