diff --git a/administrator/components/com_contact/config.xml b/administrator/components/com_contact/config.xml index 6a571a8d529b2..b8938dbadccdd 100644 --- a/administrator/components/com_contact/config.xml +++ b/administrator/components/com_contact/config.xml @@ -815,6 +815,18 @@ + + + + +
JHIDE + + + + +
+
+ + + + + + +
+
+
+ + + + + + +
+
router = $router; + } + + /** + * Preprocess the route for the com_contact component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_contact component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_contact'); + $advanced = $params->get('sef_advanced_link', 0); + + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + } + + $mView = (empty($menuItem->query['view'])) ? null : $menuItem->query['view']; + $mId = (empty($menuItem->query['id'])) ? null : $menuItem->query['id']; + + if (isset($query['view'])) + { + $view = $query['view']; + + if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_contact') + { + $segments[] = $query['view']; + } + + unset($query['view']); + } + + // Are we dealing with a contact that is attached to a menu item? + if (isset($view) && ($mView == $view) and (isset($query['id'])) and ($mId == (int) $query['id'])) + { + unset($query['view']); + unset($query['catid']); + unset($query['id']); + return; + } + + if (isset($view) and ($view == 'category' or $view == 'contact')) + { + if ($mId != (int) $query['id'] || $mView != $view) + { + if ($view == 'contact' && isset($query['catid'])) + { + $catid = $query['catid']; + } + elseif (isset($query['id'])) + { + $catid = $query['id']; + } + + $menuCatid = $mId; + $categories = JCategories::getInstance('Contact'); + $category = $categories->get($catid); + + if ($category) + { + // TODO Throw error that the category either not exists or is unpublished + $path = array_reverse($category->getPath()); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id == (int) $menuCatid) + { + break; + } + + if ($advanced) + { + list($tmp, $id) = explode(':', $id, 2); + } + + $array[] = $id; + } + + $segments = array_merge($segments, array_reverse($array)); + } + + if ($view == 'contact') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + } + + unset($query['id']); + unset($query['catid']); + } + + if (isset($query['layout'])) + { + if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + + unset($query['layout']); + } + } + else + { + if ($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_contact'); + $advanced = $params->get('sef_advanced_link', 0); + + // Count route segments + $count = count($segments); + + // Standard routing for newsfeeds. + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + return; + } + + // From the categories view, we can only jump to a category. + $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; + + $contactCategory = JCategories::getInstance('Contact')->get($id); + + $categories = ($contactCategory) ? $contactCategory->getChildren() : array(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + + foreach ($categories as $category) + { + if ($category->slug == $segment || $category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__contact_details') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $nid = $db->loadResult(); + } + else + { + $nid = $segment; + } + + $vars['id'] = $nid; + $vars['view'] = 'contact'; + } + + $found = 0; + } + } +} diff --git a/components/com_contact/helpers/route.php b/components/com_contact/helpers/route.php index 40861e2376db3..b68a7f635c390 100644 --- a/components/com_contact/helpers/route.php +++ b/components/com_contact/helpers/route.php @@ -19,8 +19,6 @@ */ abstract class ContactHelperRoute { - protected static $lookup; - /** * Get the URL route for a contact from a contact ID, contact category ID and language * @@ -34,35 +32,17 @@ abstract class ContactHelperRoute */ public static function getContactRoute($id, $catid, $language = 0) { - $needles = array( - 'contact' => array((int) $id) - ); - // Create the link $link = 'index.php?option=com_contact&view=contact&id=' . $id; if ($catid > 1) { - $categories = JCategories::getInstance('Contact'); - $category = $categories->get($catid); - - if ($category) - { - $needles['category'] = array_reverse($category->getPath()); - $needles['categories'] = $needles['category']; - $link .= '&catid=' . $catid; - } + $link .= '&catid=' . $catid; } if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } return $link; @@ -82,131 +62,28 @@ public static function getCategoryRoute($catid, $language = 0) { if ($catid instanceof JCategoryNode) { - $id = $catid->id; - $category = $catid; + $id = $catid->id; } else { $id = (int) $catid; - $category = JCategories::getInstance('Contact')->get($id); } - if ($id < 1 || !($category instanceof JCategoryNode)) + if ($id < 1) { $link = ''; } else { - $needles = array(); - // Create the link $link = 'index.php?option=com_contact&view=category&id=' . $id; - $catids = array_reverse($category->getPath()); - $needles['category'] = $catids; - $needles['categories'] = $catids; - if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } } return $link; } - - /** - * Find an item ID. - * - * @param array $needles An array of language codes. - * - * @return mixed The ID found or null otherwise. - * - * @since 1.6 - */ - protected static function _findItem($needles = null) - { - $app = JFactory::getApplication(); - $menus = $app->getMenu('site'); - $language = isset($needles['language']) ? $needles['language'] : '*'; - - // Prepare the reverse lookup array. - if (!isset(self::$lookup[$language])) - { - self::$lookup[$language] = array(); - - $component = JComponentHelper::getComponent('com_contact'); - $attributes = array('component_id'); - $values = array($component->id); - - if ($language != '*') - { - $attributes[] = 'language'; - $values[] = array($needles['language'], '*'); - } - - $items = $menus->getItems($attributes, $values); - - foreach ($items as $item) - { - if (isset($item->query) && isset($item->query['view'])) - { - $view = $item->query['view']; - - if (!isset(self::$lookup[$language][$view])) - { - self::$lookup[$language][$view] = array(); - } - - if (isset($item->query['id'])) - { - /** - * Here it will become a bit tricky - * language != * can override existing entries - * language == * cannot override existing entries - */ - if (!isset(self::$lookup[$language][$view][$item->query['id']]) || $item->language != '*') - { - self::$lookup[$language][$view][$item->query['id']] = $item->id; - } - } - } - } - } - - if ($needles) - { - foreach ($needles as $view => $ids) - { - if (isset(self::$lookup[$language][$view])) - { - foreach ($ids as $id) - { - if (isset(self::$lookup[$language][$view][(int) $id])) - { - return self::$lookup[$language][$view][(int) $id]; - } - } - } - } - } - - // Check if the active menuitem matches the requested language - $active = $menus->getActive(); - if ($active && ($language == '*' || in_array($active->language, array('*', $language)) || !JLanguageMultilang::isEnabled())) - { - return $active->id; - } - - // If not found, return language specific home link - $default = $menus->getDefault($language); - - return !empty($default->id) ? $default->id : null; - } } diff --git a/components/com_contact/router.php b/components/com_contact/router.php index 3de9dc7910d1c..c13d25d6c6005 100644 --- a/components/com_contact/router.php +++ b/components/com_contact/router.php @@ -14,236 +14,140 @@ * * @since 3.3 */ -class ContactRouter extends JComponentRouterBase +class ContactRouter extends JComponentRouterView { /** - * Build the route for the com_contact component - * - * @param array &$query An array of URL arguments - * - * @return array The URL arguments to use to assemble the subsequent URL. - * - * @since 3.3 + * Search Component router constructor + * + * @param JApplicationCms $app The application object + * @param JMenu $menu The menu object to work with */ - public function build(&$query) + public function __construct($app = null, $menu = null) { - $segments = array(); - - // Get a menu item based on Itemid or currently active - $params = JComponentHelper::getParams('com_contact'); - $advanced = $params->get('sef_advanced_link', 0); - - if (empty($query['Itemid'])) - { - $menuItem = $this->menu->getActive(); - } - else - { - $menuItem = $this->menu->getItem($query['Itemid']); - } - - $mView = (empty($menuItem->query['view'])) ? null : $menuItem->query['view']; - $mId = (empty($menuItem->query['id'])) ? null : $menuItem->query['id']; + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable(); + $this->registerView($category); + $contact = new JComponentRouterViewconfiguration('contact'); + $contact->setKey('id')->setParent($category, 'catid'); + $this->registerView($contact); + $this->registerView(new JComponentRouterViewconfiguration('featured')); - if (isset($query['view'])) - { - $view = $query['view']; + parent::__construct($app, $menu); - if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_contact') - { - $segments[] = $query['view']; - } + $this->attachRule(new JComponentRouterRulesMenu($this)); - unset($query['view']); - } + $params = JComponentHelper::getParams('com_content'); - // Are we dealing with a contact that is attached to a menu item? - if (isset($view) && ($mView == $view) and (isset($query['id'])) and ($mId == (int) $query['id'])) + if ($params->get('sef_advanced', 0)) { - unset($query['view']); - unset($query['catid']); - unset($query['id']); - return $segments; + $this->attachRule(new JComponentRouterRulesStandard($this)); } - - if (isset($view) and ($view == 'category' or $view == 'contact')) - { - if ($mId != (int) $query['id'] || $mView != $view) - { - if ($view == 'contact' && isset($query['catid'])) - { - $catid = $query['catid']; - } - elseif (isset($query['id'])) - { - $catid = $query['id']; - } - - $menuCatid = $mId; - $categories = JCategories::getInstance('Contact'); - $category = $categories->get($catid); - - if ($category) - { - // TODO Throw error that the category either not exists or is unpublished - $path = array_reverse($category->getPath()); - - $array = array(); - - foreach ($path as $id) - { - if ((int) $id == (int) $menuCatid) - { - break; - } - - if ($advanced) - { - list($tmp, $id) = explode(':', $id, 2); - } - - $array[] = $id; - } - - $segments = array_merge($segments, array_reverse($array)); - } - - if ($view == 'contact') - { - if ($advanced) - { - list($tmp, $id) = explode(':', $query['id'], 2); - } - else - { - $id = $query['id']; - } - - $segments[] = $id; - } - } - - unset($query['id']); - unset($query['catid']); - } - - if (isset($query['layout'])) - { - if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) - { - if ($query['layout'] == $menuItem->query['layout']) - { - - unset($query['layout']); - } - } - else - { - if ($query['layout'] == 'default') - { - unset($query['layout']); - } - } - } - - $total = count($segments); - - for ($i = 0; $i < $total; $i++) + else { - $segments[$i] = str_replace(':', '-', $segments[$i]); + require_once JPATH_SITE . '/components/com_contact/helpers/legacyrouter.php'; + $this->attachRule(new ContactRouterRulesLegacy($this)); } - - return $segments; } /** - * Parse the segments of a URL. - * - * @param array &$segments The segments of the URL to parse. - * - * @return array The URL attributes to be used by the application. + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now * - * @since 3.3 + * @return array|string The segments of this item */ - public function parse(&$segments) + public function getCategorySegment($id, $query) { - $total = count($segments); - $vars = array(); + $category = JCategories::getInstance($this->getName())->get($id); - for ($i = 0; $i < $total; $i++) + if ($category) { - $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + return array_reverse($category->getPath()); } - // Get the active menu item. - $item = $this->menu->getActive(); - $params = JComponentHelper::getParams('com_contact'); - $advanced = $params->get('sef_advanced_link', 0); - - // Count route segments - $count = count($segments); - - // Standard routing for newsfeeds. - if (!isset($item)) - { - $vars['view'] = $segments[0]; - $vars['id'] = $segments[$count - 1]; - return $vars; - } - - // From the categories view, we can only jump to a category. - $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; + return array(); + } - $contactCategory = JCategories::getInstance('Contact')->get($id); + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } - $categories = ($contactCategory) ? $contactCategory->getChildren() : array(); - $vars['catid'] = $id; - $vars['id'] = $id; - $found = 0; + /** + * Method to get the segment(s) for a contact + * + * @param string $id ID of the contact to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getContactSegment($id, $query) + { + return array($id); + } - foreach ($segments as $segment) + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) { - $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + $category = JCategories::getInstance($this->getName())->get($query['id']); - foreach ($categories as $category) + foreach ($category->getChildren() as $child) { - if ($category->slug == $segment || $category->alias == $segment) + if ($child->id == (int) $segment) { - $vars['id'] = $category->id; - $vars['catid'] = $category->id; - $vars['view'] = 'category'; - $categories = $category->getChildren(); - $found = 1; - break; + return $child->id; } } + } - if ($found == 0) - { - if ($advanced) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from('#__contact_details') - ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) - ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); - $db->setQuery($query); - $nid = $db->loadResult(); - } - else - { - $nid = $segment; - } - - $vars['id'] = $nid; - $vars['view'] = 'contact'; - } + return false; + } - $found = 0; - } + /** + * Method to get the segment(s) for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } - return $vars; + /** + * Method to get the segment(s) for a contact + * + * @param string $segment Segment of the contact to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getContactId($segment, $query) + { + return (int) $segment; } } @@ -261,7 +165,8 @@ public function parse(&$segments) */ function ContactBuildRoute(&$query) { - $router = new ContactRouter; + $app = JFactory::getApplication(); + $router = new ContactRouter($app, $app->getMenu()); return $router->build($query); } @@ -280,7 +185,8 @@ function ContactBuildRoute(&$query) */ function ContactParseRoute($segments) { - $router = new ContactRouter; + $app = JFactory::getApplication(); + $router = new ContactRouter($app, $app->getMenu()); return $router->parse($segments); } diff --git a/components/com_content/helpers/legacyrouter.php b/components/com_content/helpers/legacyrouter.php new file mode 100644 index 0000000000000..dbd142376fdc6 --- /dev/null +++ b/components/com_content/helpers/legacyrouter.php @@ -0,0 +1,477 @@ +router = $router; + } + + /** + * Preprocess the route for the com_content component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_content component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_content'); + $advanced = $params->get('sef_advanced_link', 0); + + // We need a menu item. Either the one specified in the query, or the current active one if none specified + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + $menuItemGiven = false; + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + $menuItemGiven = true; + } + + // Check again + if ($menuItemGiven && isset($menuItem) && $menuItem->component != 'com_content') + { + $menuItemGiven = false; + unset($query['Itemid']); + } + + if (isset($query['view'])) + { + $view = $query['view']; + } + else + { + // We need to have a view in the query or it is an invalid URL + return; + } + + // Are we dealing with an article or category that is attached to a menu item? + if (($menuItem instanceof stdClass) + && $menuItem->query['view'] == $query['view'] + && isset($query['id']) + && $menuItem->query['id'] == (int) $query['id']) + { + unset($query['view']); + + if (isset($query['catid'])) + { + unset($query['catid']); + } + + if (isset($query['layout'])) + { + unset($query['layout']); + } + + unset($query['id']); + + return; + } + + if ($view == 'category' || $view == 'article') + { + if (!$menuItemGiven) + { + $segments[] = $view; + } + + unset($query['view']); + + if ($view == 'article') + { + if (isset($query['id']) && isset($query['catid']) && $query['catid']) + { + $catid = $query['catid']; + + // Make sure we have the id and the alias + if (strpos($query['id'], ':') === false) + { + $db = JFactory::getDbo(); + $dbQuery = $db->getQuery(true) + ->select('alias') + ->from('#__content') + ->where('id=' . (int) $query['id']); + $db->setQuery($dbQuery); + $alias = $db->loadResult(); + $query['id'] = $query['id'] . ':' . $alias; + } + } + else + { + // We should have these two set for this view. If we don't, it is an error + return; + } + } + else + { + if (isset($query['id'])) + { + $catid = $query['id']; + } + else + { + // We should have id set for this view. If we don't, it is an error + return; + } + } + + if ($menuItemGiven && isset($menuItem->query['id'])) + { + $mCatid = $menuItem->query['id']; + } + else + { + $mCatid = 0; + } + + $categories = JCategories::getInstance('Content'); + $category = $categories->get($catid); + + if (!$category) + { + // We couldn't find the category we were given. Bail. + return; + } + + $path = array_reverse($category->getPath()); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id == (int) $mCatid) + { + break; + } + + list($tmp, $id) = explode(':', $id, 2); + + $array[] = $id; + } + + $array = array_reverse($array); + + if (!$advanced && count($array)) + { + $array[0] = (int) $catid . ':' . $array[0]; + } + + $segments = array_merge($segments, $array); + + if ($view == 'article') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + + unset($query['id']); + unset($query['catid']); + } + + if ($view == 'archive') + { + if (!$menuItemGiven) + { + $segments[] = $view; + unset($query['view']); + } + + if (isset($query['year'])) + { + if ($menuItemGiven) + { + $segments[] = $query['year']; + unset($query['year']); + } + } + + if (isset($query['year']) && isset($query['month'])) + { + if ($menuItemGiven) + { + $segments[] = $query['month']; + unset($query['month']); + } + } + } + + if ($view == 'featured') + { + if (!$menuItemGiven) + { + $segments[] = $view; + } + + unset($query['view']); + } + + /* + * If the layout is specified and it is the same as the layout in the menu item, we + * unset it so it doesn't go into the query string. + */ + if (isset($query['layout'])) + { + if ($menuItemGiven && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + unset($query['layout']); + } + } + else + { + if ($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_content'); + $advanced = $params->get('sef_advanced_link', 0); + $db = JFactory::getDbo(); + + // Count route segments + $count = count($segments); + + /* + * Standard routing for articles. If we don't pick up an Itemid then we get the view from the segments + * the first segment is the view and the last segment is the id of the article or category. + */ + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + + return; + } + + /* + * If there is only one segment, then it points to either an article or a category. + * We test it first to see if it is a category. If the id and alias match a category, + * then we assume it is a category. If they don't we assume it is an article + */ + if ($count == 1) + { + // We check to see if an alias is given. If not, we assume it is an article + if (strpos($segments[0], ':') === false) + { + $vars['view'] = 'article'; + $vars['id'] = (int) $segments[0]; + + return; + } + + list($id, $alias) = explode(':', $segments[0], 2); + + // First we check if it is a category + $category = JCategories::getInstance('Content')->get($id); + + if ($category && $category->alias == $alias) + { + $vars['view'] = 'category'; + $vars['id'] = $id; + + return; + } + else + { + $query = $db->getQuery(true) + ->select($db->quoteName(array('alias', 'catid'))) + ->from($db->quoteName('#__content')) + ->where($db->quoteName('id') . ' = ' . (int) $id); + $db->setQuery($query); + $article = $db->loadObject(); + + if ($article) + { + if ($article->alias == $alias) + { + $vars['view'] = 'article'; + $vars['catid'] = (int) $article->catid; + $vars['id'] = (int) $id; + + return; + } + } + } + } + + /* + * If there was more than one segment, then we can determine where the URL points to + * because the first segment will have the target category id prepended to it. If the + * last segment has a number prepended, it is an article, otherwise, it is a category. + */ + if (!$advanced) + { + $cat_id = (int) $segments[0]; + + $article_id = (int) $segments[$count - 1]; + + if ($article_id > 0) + { + $vars['view'] = 'article'; + $vars['catid'] = $cat_id; + $vars['id'] = $article_id; + } + else + { + $vars['view'] = 'category'; + $vars['id'] = $cat_id; + } + + return; + } + + // We get the category id from the menu item and search from there + $id = $item->query['id']; + $category = JCategories::getInstance('Content')->get($id); + + if (!$category) + { + JError::raiseError(404, JText::_('COM_CONTENT_ERROR_PARENT_CATEGORY_NOT_FOUND')); + + return; + } + + $categories = $category->getChildren(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = str_replace(':', '-', $segment); + + foreach ($categories as $category) + { + if ($category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__content') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $cid = $db->loadResult(); + } + else + { + $cid = $segment; + } + + $vars['id'] = $cid; + + if ($item->query['view'] == 'archive' && $count != 1) + { + $vars['year'] = $count >= 2 ? $segments[$count - 2] : null; + $vars['month'] = $segments[$count - 1]; + $vars['view'] = 'archive'; + } + else + { + $vars['view'] = 'article'; + } + } + + $found = 0; + } + } +} diff --git a/components/com_content/helpers/route.php b/components/com_content/helpers/route.php index 5dece4143a292..835aa243d358e 100644 --- a/components/com_content/helpers/route.php +++ b/components/com_content/helpers/route.php @@ -16,8 +16,6 @@ */ abstract class ContentHelperRoute { - protected static $lookup = array(); - /** * Get the article route. * @@ -31,35 +29,17 @@ abstract class ContentHelperRoute */ public static function getArticleRoute($id, $catid = 0, $language = 0) { - $needles = array( - 'article' => array((int) $id) - ); - // Create the link $link = 'index.php?option=com_content&view=article&id=' . $id; if ((int) $catid > 1) { - $categories = JCategories::getInstance('Content'); - $category = $categories->get((int) $catid); - - if ($category) - { - $needles['category'] = array_reverse($category->getPath()); - $needles['categories'] = $needles['category']; - $link .= '&catid=' . $catid; - } + $link .= '&catid=' . $catid; } if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } return $link; @@ -79,36 +59,24 @@ public static function getCategoryRoute($catid, $language = 0) { if ($catid instanceof JCategoryNode) { - $id = $catid->id; - $category = $catid; + $id = $catid->id; } else { - $id = (int) $catid; - $category = JCategories::getInstance('Content')->get($id); + $id = (int) $catid; } - if ($id < 1 || !($category instanceof JCategoryNode)) + if ($id < 1) { $link = ''; } else { - $needles = array(); - $link = 'index.php?option=com_content&view=category&id=' . $id; - $catids = array_reverse($category->getPath()); - $needles['category'] = $catids; - $needles['categories'] = $catids; + $link = 'index.php?option=com_content&view=category&id=' . $id; if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } } @@ -126,109 +94,6 @@ public static function getCategoryRoute($catid, $language = 0) */ public static function getFormRoute($id) { - // Create the link - if ($id) - { - $link = 'index.php?option=com_content&task=article.edit&a_id=' . $id; - } - else - { - $link = 'index.php?option=com_content&task=article.edit&a_id=0'; - } - - return $link; - } - - /** - * Find an item ID. - * - * @param array $needles An array of language codes. - * - * @return mixed The ID found or null otherwise. - * - * @since 1.5 - */ - protected static function _findItem($needles = null) - { - $app = JFactory::getApplication(); - $menus = $app->getMenu('site'); - $language = isset($needles['language']) ? $needles['language'] : '*'; - - // Prepare the reverse lookup array. - if (!isset(self::$lookup[$language])) - { - self::$lookup[$language] = array(); - - $component = JComponentHelper::getComponent('com_content'); - - $attributes = array('component_id'); - $values = array($component->id); - - if ($language != '*') - { - $attributes[] = 'language'; - $values[] = array($needles['language'], '*'); - } - - $items = $menus->getItems($attributes, $values); - - foreach ($items as $item) - { - if (isset($item->query) && isset($item->query['view'])) - { - $view = $item->query['view']; - - if (!isset(self::$lookup[$language][$view])) - { - self::$lookup[$language][$view] = array(); - } - - if (isset($item->query['id'])) - { - /** - * Here it will become a bit tricky - * language != * can override existing entries - * language == * cannot override existing entries - */ - if (!isset(self::$lookup[$language][$view][$item->query['id']]) || $item->language != '*') - { - self::$lookup[$language][$view][$item->query['id']] = $item->id; - } - } - } - } - } - - if ($needles) - { - foreach ($needles as $view => $ids) - { - if (isset(self::$lookup[$language][$view])) - { - foreach ($ids as $id) - { - if (isset(self::$lookup[$language][$view][(int) $id])) - { - return self::$lookup[$language][$view][(int) $id]; - } - } - } - } - } - - // Check if the active menuitem matches the requested language - $active = $menus->getActive(); - - if ($active - && $active->component == 'com_content' - && ($language == '*' || in_array($active->language, array('*', $language)) || !JLanguageMultilang::isEnabled())) - { - return $active->id; - } - - // If not found, return language specific home link - $default = $menus->getDefault($language); - - return !empty($default->id) ? $default->id : null; + return 'index.php?option=com_content&task=article.edit&a_id=' . (int) $id; } } diff --git a/components/com_content/router.php b/components/com_content/router.php index f180678ccb72c..c25a607d6c707 100644 --- a/components/com_content/router.php +++ b/components/com_content/router.php @@ -3,468 +3,153 @@ * @package Joomla.Site * @subpackage com_content * - * @copyright Copyright (C) 2005 - 2016 Open Source Matters, Inc. All rights reserved. + * @copyright Copyright (C) 2005 - 2015 Open Source Matters, Inc. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; /** - * Routing class from com_content + * Routing class of com_content * * @since 3.3 */ -class ContentRouter extends JComponentRouterBase +class ContentRouter extends JComponentRouterView { /** - * Build the route for the com_content component - * - * @param array &$query An array of URL arguments - * - * @return array The URL arguments to use to assemble the subsequent URL. - * - * @since 3.3 + * Content Component router constructor + * + * @param JApplicationCms $app The application object + * @param JMenu $menu The menu object to work with */ - public function build(&$query) + public function __construct($app = null, $menu = null) { - $segments = array(); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable()->addLayout('blog'); + $this->registerView($category); + $article = new JComponentRouterViewconfiguration('article'); + $article->setKey('id')->setParent($category, 'catid'); + $this->registerView($article); + $this->registerView(new JComponentRouterViewconfiguration('archive')); + $this->registerView(new JComponentRouterViewconfiguration('featured')); + $this->registerView(new JComponentRouterViewconfiguration('form')); + + parent::__construct($app, $menu); + + $this->attachRule(new JComponentRouterRulesMenu($this)); - // Get a menu item based on Itemid or currently active $params = JComponentHelper::getParams('com_content'); - $advanced = $params->get('sef_advanced_link', 0); - // Unset limitstart=0 since it's pointless - if (isset($query['limitstart']) && $query['limitstart'] == 0) + if ($params->get('sef_advanced', 0)) { - unset($query['limitstart']); - } - - // We need a menu item. Either the one specified in the query, or the current active one if none specified - if (empty($query['Itemid'])) - { - $menuItem = $this->menu->getActive(); - $menuItemGiven = false; + $this->attachRule(new JComponentRouterRulesStandard($this)); } else { - $menuItem = $this->menu->getItem($query['Itemid']); - $menuItemGiven = true; - } - - // Check again - if ($menuItemGiven && isset($menuItem) && $menuItem->component != 'com_content') - { - $menuItemGiven = false; - unset($query['Itemid']); - } - - if (isset($query['view'])) - { - $view = $query['view']; - } - else - { - // We need to have a view in the query or it is an invalid URL - return $segments; - } - - // Are we dealing with an article or category that is attached to a menu item? - if (($menuItem instanceof stdClass) - && $menuItem->query['view'] == $query['view'] - && isset($query['id']) - && $menuItem->query['id'] == (int) $query['id']) - { - unset($query['view']); - - if (isset($query['catid'])) - { - unset($query['catid']); - } - - if (isset($query['layout'])) - { - unset($query['layout']); - } - - unset($query['id']); - - return $segments; - } - - if ($view == 'category' || $view == 'article') - { - if (!$menuItemGiven) - { - $segments[] = $view; - } - - unset($query['view']); - - if ($view == 'article') - { - if (isset($query['id']) && isset($query['catid']) && $query['catid']) - { - $catid = $query['catid']; - - // Make sure we have the id and the alias - if (strpos($query['id'], ':') === false) - { - $db = JFactory::getDbo(); - $dbQuery = $db->getQuery(true) - ->select('alias') - ->from('#__content') - ->where('id=' . (int) $query['id']); - $db->setQuery($dbQuery); - $alias = $db->loadResult(); - $query['id'] = $query['id'] . ':' . $alias; - } - } - else - { - // We should have these two set for this view. If we don't, it is an error - return $segments; - } - } - else - { - if (isset($query['id'])) - { - $catid = $query['id']; - } - else - { - // We should have id set for this view. If we don't, it is an error - return $segments; - } - } - - if ($menuItemGiven && isset($menuItem->query['id'])) - { - $mCatid = $menuItem->query['id']; - } - else - { - $mCatid = 0; - } - - $categories = JCategories::getInstance('Content'); - $category = $categories->get($catid); - - if (!$category) - { - // We couldn't find the category we were given. Bail. - return $segments; - } - - $path = array_reverse($category->getPath()); - - $array = array(); - - foreach ($path as $id) - { - if ((int) $id == (int) $mCatid) - { - break; - } - - list($tmp, $id) = explode(':', $id, 2); - - $array[] = $id; - } - - $array = array_reverse($array); - - if (!$advanced && count($array)) - { - $array[0] = (int) $catid . ':' . $array[0]; - } - - $segments = array_merge($segments, $array); - - if ($view == 'article') - { - if ($advanced) - { - list($tmp, $id) = explode(':', $query['id'], 2); - } - else - { - $id = $query['id']; - } - - $segments[] = $id; - } - - unset($query['id']); - unset($query['catid']); - } - - if ($view == 'archive') - { - if (!$menuItemGiven || $menuItem->query['view'] != 'archive') - { - // Did not work without removing Itemid - if (isset($menuItem)) - { - unset($query['Itemid']); - } - - $segments[] = $view; - } - - unset($query['view']); - - if (isset($query['year'])) - { - $segments[] = $query['year']; - unset($query['year']); - } - - if (isset($query['month'])) - { - $segments[] = $query['month']; - unset($query['month']); - } - } - - if ($view == 'featured') - { - if (!$menuItemGiven) - { - $segments[] = $view; - } - - unset($query['view']); - } - - /* - * If the layout is specified and it is the same as the layout in the menu item, we - * unset it so it doesn't go into the query string. - */ - if (isset($query['layout'])) - { - if ($menuItemGiven && isset($menuItem->query['layout'])) - { - if ($query['layout'] == $menuItem->query['layout']) - { - unset($query['layout']); - } - } - else - { - if ($query['layout'] == 'default') - { - unset($query['layout']); - } - } + require_once JPATH_SITE . '/components/com_content/helpers/legacyrouter.php'; + $this->attachRule(new ContentRouterRulesLegacy($this)); } - - $total = count($segments); - - for ($i = 0; $i < $total; $i++) - { - $segments[$i] = str_replace(':', '-', $segments[$i]); - } - - return $segments; } /** - * Parse the segments of a URL. - * - * @param array &$segments The segments of the URL to parse. + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now * - * @return array The URL attributes to be used by the application. - * - * @since 3.3 + * @return array|string The segments of this item */ - public function parse(&$segments) + public function getCategorySegment($id, $query) { - $total = count($segments); - $vars = array(); + $category = JCategories::getInstance($this->getName())->get($id); - for ($i = 0; $i < $total; $i++) + if ($category) { - $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + return array_reverse($category->getPath()); } - // Get the active menu item. - $item = $this->menu->getActive(); - $params = JComponentHelper::getParams('com_content'); - $advanced = $params->get('sef_advanced_link', 0); - $db = JFactory::getDbo(); - - // Count route segments - $count = count($segments); - - /* - * Standard routing for articles. If we don't pick up an Itemid then we get the view from the segments - * the first segment is the view and the last segment is the id of the article or category. - */ - if (!isset($item)) - { - $vars['view'] = $segments[0]; + return array(); + } - // Called if no menu item created - if ($vars['view'] == 'archive') - { - $vars['year'] = $count >= 2 ? $segments[$count - 2] : null; - $vars['month'] = $segments[$count - 1]; - } - else - { - $vars['id'] = $segments[$count - 1]; - } + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } - return $vars; - } + /** + * Method to get the segment(s) for an article + * + * @param string $id ID of the article to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getArticleSegment($id, $query) + { + return array($id); + } - // First handle archive view - if ($item->query['view'] == 'archive') + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) { - $vars['year'] = $count >= 2 ? $segments[$count - 2] : null; - $vars['month'] = $segments[$count - 1]; - $vars['view'] = 'archive'; - - return $vars; - } + $category = JCategories::getInstance($this->getName())->get($query['id']); - /* - * If there is only one segment, then it points to either an article or a category. - * We test it first to see if it is a category. If the id and alias match a category, - * then we assume it is a category. If they don't we assume it is an article - */ - if ($count == 1) - { - // We check to see if an alias is given. If not, we assume it is an article - if (strpos($segments[0], ':') === false) + foreach ($category->getChildren() as $child) { - $vars['view'] = 'article'; - $vars['id'] = (int) $segments[0]; - - return $vars; - } - - list($id, $alias) = explode(':', $segments[0], 2); - - // First we check if it is a category - $category = JCategories::getInstance('Content')->get($id); - - if ($category && $category->alias == $alias) - { - $vars['view'] = 'category'; - $vars['id'] = $id; - - return $vars; - } - else - { - $query = $db->getQuery(true) - ->select($db->quoteName(array('alias', 'catid'))) - ->from($db->quoteName('#__content')) - ->where($db->quoteName('id') . ' = ' . (int) $id); - $db->setQuery($query); - $article = $db->loadObject(); - - if ($article) + if ($child->id == (int) $segment) { - if ($article->alias == $alias) - { - $vars['view'] = 'article'; - $vars['catid'] = (int) $article->catid; - $vars['id'] = (int) $id; - - return $vars; - } + return $child->id; } } } - /* - * If there was more than one segment, then we can determine where the URL points to - * because the first segment will have the target category id prepended to it. If the - * last segment has a number prepended, it is an article, otherwise, it is a category. - */ - if (!$advanced) - { - $cat_id = (int) $segments[0]; - - $article_id = (int) $segments[$count - 1]; - - if ($article_id > 0) - { - $vars['view'] = 'article'; - $vars['catid'] = $cat_id; - $vars['id'] = $article_id; - } - else - { - $vars['view'] = 'category'; - $vars['id'] = $cat_id; - } - - return $vars; - } - - // We get the category id from the menu item and search from there - $id = $item->query['id']; - $category = JCategories::getInstance('Content')->get($id); - - if (!$category) - { - JError::raiseError(404, JText::_('COM_CONTENT_ERROR_PARENT_CATEGORY_NOT_FOUND')); - - return $vars; - } - - $categories = $category->getChildren(); - $vars['catid'] = $id; - $vars['id'] = $id; - $found = 0; - - foreach ($segments as $segment) - { - $segment = str_replace(':', '-', $segment); - - foreach ($categories as $category) - { - if ($category->alias == $segment) - { - $vars['id'] = $category->id; - $vars['catid'] = $category->id; - $vars['view'] = 'category'; - $categories = $category->getChildren(); - $found = 1; - break; - } - } - - if ($found == 0) - { - if ($advanced) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from('#__content') - ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) - ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); - $db->setQuery($query); - $cid = $db->loadResult(); - } - else - { - $cid = $segment; - } - - $vars['id'] = $cid; - $vars['view'] = 'article'; - } + return false; + } - $found = 0; - } + /** + * Method to get the segment(s) for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } - return $vars; + /** + * Method to get the segment(s) for an article + * + * @param string $segment Segment of the article to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getArticleId($segment, $query) + { + return (int) $segment; } } @@ -482,7 +167,8 @@ public function parse(&$segments) */ function contentBuildRoute(&$query) { - $router = new ContentRouter; + $app = JFactory::getApplication(); + $router = new ContentRouter($app, $app->getMenu()); return $router->build($query); } @@ -502,7 +188,8 @@ function contentBuildRoute(&$query) */ function contentParseRoute($segments) { - $router = new ContentRouter; + $app = JFactory::getApplication(); + $router = new ContentRouter($app, $app->getMenu()); return $router->parse($segments); } diff --git a/components/com_newsfeeds/helpers/legacyrouter.php b/components/com_newsfeeds/helpers/legacyrouter.php new file mode 100644 index 0000000000000..12f61adedaa7e --- /dev/null +++ b/components/com_newsfeeds/helpers/legacyrouter.php @@ -0,0 +1,271 @@ +router = $router; + } + + /** + * Preprocess the route for the com_newsfeeds component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_newsfeeds component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Get a menu item based on Itemid or currently active + $params = JComponentHelper::getParams('com_newsfeeds'); + $advanced = $params->get('sef_advanced_link', 0); + + if (empty($query['Itemid'])) + { + $menuItem = $this->router->menu->getActive(); + } + else + { + $menuItem = $this->router->menu->getItem($query['Itemid']); + } + + $mView = (empty($menuItem->query['view'])) ? null : $menuItem->query['view']; + $mId = (empty($menuItem->query['id'])) ? null : $menuItem->query['id']; + + if (isset($query['view'])) + { + $view = $query['view']; + + if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_newsfeeds') + { + $segments[] = $query['view']; + } + + unset($query['view']); + } + + // Are we dealing with an newsfeed that is attached to a menu item? + if (isset($query['view']) && ($mView == $query['view']) and (isset($query['id'])) and ($mId == (int) $query['id'])) + { + unset($query['view']); + unset($query['catid']); + unset($query['id']); + + return; + } + + if (isset($view) and ($view == 'category' or $view == 'newsfeed')) + { + if ($mId != (int) $query['id'] || $mView != $view) + { + if ($view == 'newsfeed' && isset($query['catid'])) + { + $catid = $query['catid']; + } + elseif (isset($query['id'])) + { + $catid = $query['id']; + } + + $menuCatid = $mId; + $categories = JCategories::getInstance('Newsfeeds'); + $category = $categories->get($catid); + + if ($category) + { + $path = $category->getPath(); + $path = array_reverse($path); + + $array = array(); + + foreach ($path as $id) + { + if ((int) $id == (int) $menuCatid) + { + break; + } + + if ($advanced) + { + list($tmp, $id) = explode(':', $id, 2); + } + + $array[] = $id; + } + + $segments = array_merge($segments, array_reverse($array)); + } + + if ($view == 'newsfeed') + { + if ($advanced) + { + list($tmp, $id) = explode(':', $query['id'], 2); + } + else + { + $id = $query['id']; + } + + $segments[] = $id; + } + } + + unset($query['id']); + unset($query['catid']); + } + + if (isset($query['layout'])) + { + if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) + { + if ($query['layout'] == $menuItem->query['layout']) + { + unset($query['layout']); + } + } + else + { + if ($query['layout'] == 'default') + { + unset($query['layout']); + } + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Get the active menu item. + $item = $this->router->menu->getActive(); + $params = JComponentHelper::getParams('com_newsfeeds'); + $advanced = $params->get('sef_advanced_link', 0); + + // Count route segments + $count = count($segments); + + // Standard routing for newsfeeds. + if (!isset($item)) + { + $vars['view'] = $segments[0]; + $vars['id'] = $segments[$count - 1]; + + return; + } + + // From the categories view, we can only jump to a category. + $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; + $categories = JCategories::getInstance('Newsfeeds')->get($id)->getChildren(); + $vars['catid'] = $id; + $vars['id'] = $id; + $found = 0; + + foreach ($segments as $segment) + { + $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + + foreach ($categories as $category) + { + if ($category->slug == $segment || $category->alias == $segment) + { + $vars['id'] = $category->id; + $vars['catid'] = $category->id; + $vars['view'] = 'category'; + $categories = $category->getChildren(); + $found = 1; + break; + } + } + + if ($found == 0) + { + if ($advanced) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from('#__newsfeeds') + ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) + ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); + $db->setQuery($query); + $nid = $db->loadResult(); + } + else + { + $nid = $segment; + } + + $vars['id'] = $nid; + $vars['view'] = 'newsfeed'; + } + + $found = 0; + } + } +} diff --git a/components/com_newsfeeds/helpers/route.php b/components/com_newsfeeds/helpers/route.php index 6ad2c5bdc386d..9e50b1f05a907 100644 --- a/components/com_newsfeeds/helpers/route.php +++ b/components/com_newsfeeds/helpers/route.php @@ -16,8 +16,6 @@ */ abstract class NewsfeedsHelperRoute { - protected static $lookup; - /** * getNewsfeedRoute * @@ -29,36 +27,17 @@ abstract class NewsfeedsHelperRoute */ public static function getNewsfeedRoute($id, $catid, $language = 0) { - $needles = array( - 'newsfeed' => array((int) $id) - ); - // Create the link $link = 'index.php?option=com_newsfeeds&view=newsfeed&id=' . $id; if ((int) $catid > 1) { - $categories = JCategories::getInstance('Newsfeeds'); - $category = $categories->get((int) $catid); - - if ($category) - { - // TODO Throw error that the category either not exists or is unpublished - $needles['category'] = array_reverse($category->getPath()); - $needles['categories'] = $needles['category']; - $link .= '&catid=' . $catid; - } + $link .= '&catid=' . $catid; } if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } return $link; @@ -77,130 +56,27 @@ public static function getCategoryRoute($catid, $language = 0) if ($catid instanceof JCategoryNode) { $id = $catid->id; - $category = $catid; } else { $id = (int) $catid; - $category = JCategories::getInstance('Newsfeeds')->get($id); } - if ($id < 1 || !($category instanceof JCategoryNode)) + if ($id < 1) { $link = ''; } else { - $needles = array(); - // Create the link $link = 'index.php?option=com_newsfeeds&view=category&id=' . $id; - $catids = array_reverse($category->getPath()); - $needles['category'] = $catids; - $needles['categories'] = $catids; - if ($language && $language != "*" && JLanguageMultilang::isEnabled()) { $link .= '&lang=' . $language; - $needles['language'] = $language; - } - - if ($item = self::_findItem($needles)) - { - $link .= '&Itemid=' . $item; } } return $link; } - - /** - * finditem - * - * @param null $needles what we are searching for - * - * @return int menu itemid - * - * @throws Exception - */ - protected static function _findItem($needles = null) - { - $app = JFactory::getApplication(); - $menus = $app->getMenu('site'); - $language = isset($needles['language']) ? $needles['language'] : '*'; - - // Prepare the reverse lookup array. - if (!isset(self::$lookup[$language])) - { - self::$lookup[$language] = array(); - - $component = JComponentHelper::getComponent('com_newsfeeds'); - - $attributes = array('component_id'); - $values = array($component->id); - - if ($language != '*') - { - $attributes[] = 'language'; - $values[] = array($needles['language'], '*'); - } - - $items = $menus->getItems($attributes, $values); - - foreach ($items as $item) - { - if (isset($item->query) && isset($item->query['view'])) - { - $view = $item->query['view']; - - if (!isset(self::$lookup[$language][$view])) - { - self::$lookup[$language][$view] = array(); - } - - if (isset($item->query['id'])) - { - /* Here it will become a bit tricky - language != * can override existing entries - language == * cannot override existing entries */ - if (!isset(self::$lookup[$language][$view][$item->query['id']]) || $item->language != '*') - { - self::$lookup[$language][$view][$item->query['id']] = $item->id; - } - } - } - } - } - - if ($needles) - { - foreach ($needles as $view => $ids) - { - if (isset(self::$lookup[$language][$view])) - { - foreach ($ids as $id) - { - if (isset(self::$lookup[$language][$view][(int) $id])) - { - return self::$lookup[$language][$view][(int) $id]; - } - } - } - } - } - - // Check if the active menuitem matches the requested language - $active = $menus->getActive(); - - if ($active && ($language == '*' || in_array($active->language, array('*', $language)) || !JLanguageMultilang::isEnabled())) - { - return $active->id; - } - - // If not found, return language specific home link - $default = $menus->getDefault($language); - - return !empty($default->id) ? $default->id : null; - } } diff --git a/components/com_newsfeeds/router.php b/components/com_newsfeeds/router.php index 89fe7766b4fe9..5435e097474e7 100644 --- a/components/com_newsfeeds/router.php +++ b/components/com_newsfeeds/router.php @@ -14,235 +14,138 @@ * * @since 3.3 */ -class NewsfeedsRouter extends JComponentRouterBase +class NewsfeedsRouter extends JComponentRouterView { /** - * Build the route for the com_newsfeeds component - * - * @param array &$query An array of URL arguments - * - * @return array The URL arguments to use to assemble the subsequent URL. - * - * @since 3.3 + * Newsfeeds Component router constructor + * + * @param JApplicationCms $app The application object + * @param JMenu $menu The menu object to work with */ - public function build(&$query) + public function __construct($app = null, $menu = null) { - $segments = array(); - - // Get a menu item based on Itemid or currently active - $params = JComponentHelper::getParams('com_newsfeeds'); - $advanced = $params->get('sef_advanced_link', 0); - - if (empty($query['Itemid'])) - { - $menuItem = $this->menu->getActive(); - } - else - { - $menuItem = $this->menu->getItem($query['Itemid']); - } - - $mView = (empty($menuItem->query['view'])) ? null : $menuItem->query['view']; - $mId = (empty($menuItem->query['id'])) ? null : $menuItem->query['id']; - - if (isset($query['view'])) - { - $view = $query['view']; - - if (empty($query['Itemid']) || empty($menuItem) || $menuItem->component != 'com_newsfeeds') - { - $segments[] = $query['view']; - } + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $this->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable(); + $this->registerView($category); + $newsfeed = new JComponentRouterViewconfiguration('newsfeed'); + $newsfeed->setKey('id')->setParent($category, 'catid'); + $this->registerView($newsfeed); - unset($query['view']); - } + parent::__construct($app, $menu); - // Are we dealing with an newsfeed that is attached to a menu item? - if (isset($query['view']) && ($mView == $query['view']) and (isset($query['id'])) and ($mId == (int) $query['id'])) - { - unset($query['view']); - unset($query['catid']); - unset($query['id']); + $this->attachRule(new JComponentRouterRulesMenu($this)); - return $segments; - } + $params = JComponentHelper::getParams('com_content'); - if (isset($view) and ($view == 'category' or $view == 'newsfeed')) + if ($params->get('sef_advanced', 0)) { - if ($mId != (int) $query['id'] || $mView != $view) - { - if ($view == 'newsfeed' && isset($query['catid'])) - { - $catid = $query['catid']; - } - elseif (isset($query['id'])) - { - $catid = $query['id']; - } - - $menuCatid = $mId; - $categories = JCategories::getInstance('Newsfeeds'); - $category = $categories->get($catid); - - if ($category) - { - $path = $category->getPath(); - $path = array_reverse($path); - - $array = array(); - - foreach ($path as $id) - { - if ((int) $id == (int) $menuCatid) - { - break; - } - - if ($advanced) - { - list($tmp, $id) = explode(':', $id, 2); - } - - $array[] = $id; - } - - $segments = array_merge($segments, array_reverse($array)); - } - - if ($view == 'newsfeed') - { - if ($advanced) - { - list($tmp, $id) = explode(':', $query['id'], 2); - } - else - { - $id = $query['id']; - } - - $segments[] = $id; - } - } - - unset($query['id']); - unset($query['catid']); - } - - if (isset($query['layout'])) - { - if (!empty($query['Itemid']) && isset($menuItem->query['layout'])) - { - if ($query['layout'] == $menuItem->query['layout']) - { - unset($query['layout']); - } - } - else - { - if ($query['layout'] == 'default') - { - unset($query['layout']); - } - } + $this->attachRule(new JComponentRouterRulesStandard($this)); } - - $total = count($segments); - - for ($i = 0; $i < $total; $i++) + else { - $segments[$i] = str_replace(':', '-', $segments[$i]); + require_once JPATH_SITE . '/components/com_newsfeeds/helpers/legacyrouter.php'; + $this->attachRule(new NewsfeedsRouterRulesLegacy($this)); } - - return $segments; } /** - * Parse the segments of a URL. - * - * @param array &$segments The segments of the URL to parse. - * - * @return array The URL attributes to be used by the application. + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now * - * @since 3.3 + * @return array|string The segments of this item */ - public function parse(&$segments) + public function getCategorySegment($id, $query) { - $total = count($segments); - $vars = array(); - - for ($i = 0; $i < $total; $i++) + $category = JCategories::getInstance($this->getName())->get($id); + if ($category) { - $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + return array_reverse($category->getPath()); } - // Get the active menu item. - $item = $this->menu->getActive(); - $params = JComponentHelper::getParams('com_newsfeeds'); - $advanced = $params->get('sef_advanced_link', 0); - - // Count route segments - $count = count($segments); - - // Standard routing for newsfeeds. - if (!isset($item)) - { - $vars['view'] = $segments[0]; - $vars['id'] = $segments[$count - 1]; + return array(); + } - return $vars; - } + /** + * Method to get the segment(s) for a category + * + * @param string $id ID of the category to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); + } - // From the categories view, we can only jump to a category. - $id = (isset($item->query['id']) && $item->query['id'] > 1) ? $item->query['id'] : 'root'; - $categories = JCategories::getInstance('Newsfeeds')->get($id)->getChildren(); - $vars['catid'] = $id; - $vars['id'] = $id; - $found = 0; + /** + * Method to get the segment(s) for a newsfeed + * + * @param string $id ID of the newsfeed to retrieve the segments for + * @param array $query The request that is build right now + * + * @return array|string The segments of this item + */ + public function getNewsfeedSegment($id, $query) + { + return array($id); + } - foreach ($segments as $segment) + /** + * Method to get the id for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoryId($segment, $query) + { + if (isset($query['id'])) { - $segment = $advanced ? str_replace(':', '-', $segment) : $segment; + $category = JCategories::getInstance($this->getName())->get($query['id']); - foreach ($categories as $category) + foreach ($category->getChildren() as $child) { - if ($category->slug == $segment || $category->alias == $segment) + if ($child->id == (int) $segment) { - $vars['id'] = $category->id; - $vars['catid'] = $category->id; - $vars['view'] = 'category'; - $categories = $category->getChildren(); - $found = 1; - - break; + return $child->id; } } + } - if ($found == 0) - { - if ($advanced) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from('#__newsfeeds') - ->where($db->quoteName('catid') . ' = ' . (int) $vars['catid']) - ->where($db->quoteName('alias') . ' = ' . $db->quote($segment)); - $db->setQuery($query); - $nid = $db->loadResult(); - } - else - { - $nid = $segment; - } - - $vars['id'] = $nid; - $vars['view'] = 'newsfeed'; - } + return false; + } - $found = 0; - } + /** + * Method to get the segment(s) for a category + * + * @param string $segment Segment to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getCategoriesId($segment, $query) + { + return $this->getCategoryId($segment, $query); + } - return $vars; + /** + * Method to get the segment(s) for a newsfeed + * + * @param string $segment Segment of the newsfeed to retrieve the ID for + * @param array $query The request that is parsed right now + * + * @return mixed The id of this item or false + */ + public function getNewsfeedId($segment, $query) + { + return (int) $segment; } } @@ -260,7 +163,8 @@ public function parse(&$segments) */ function newsfeedsBuildRoute(&$query) { - $router = new NewsfeedsRouter; + $app = JFactory::getApplication(); + $router = new NewsfeedsRouter($app, $app->getMenu()); return $router->build($query); } @@ -276,7 +180,8 @@ function newsfeedsBuildRoute(&$query) */ function newsfeedsParseRoute($segments) { - $router = new NewsfeedsRouter; + $app = JFactory::getApplication(); + $router = new NewsfeedsRouter($app, $app->getMenu()); return $router->parse($segments); } diff --git a/components/com_users/controllers/remind.php b/components/com_users/controllers/remind.php index 7c297d022291a..188d4673a8f1e 100644 --- a/components/com_users/controllers/remind.php +++ b/components/com_users/controllers/remind.php @@ -34,34 +34,24 @@ public function remind() $data = $this->input->post->get('jform', array(), 'array'); // Submit the password reset request. - $return = $model->processRemindRequest($data); + $return = $model->processRemindRequest($data); // Check for a hard error. if ($return == false) { // The request failed. - // Get the route to the next page. - $itemid = UsersHelperRoute::getRemindRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=remind' . $itemid; - // Go back to the request form. $message = JText::sprintf('COM_USERS_REMIND_REQUEST_FAILED', $model->getError()); - $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=remind', false), $message, 'notice'); return false; } else { // The request succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getRemindRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=login' . $itemid; - // Proceed to step two. $message = JText::_('COM_USERS_REMIND_REQUEST_SUCCESS'); - $this->setRedirect(JRoute::_($route, false), $message); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false), $message); return true; } diff --git a/components/com_users/controllers/reset.php b/components/com_users/controllers/reset.php index cca19ef6cfe8e..aec272cf81716 100644 --- a/components/com_users/controllers/reset.php +++ b/components/com_users/controllers/reset.php @@ -35,7 +35,7 @@ public function request() $data = $this->input->post->get('jform', array(), 'array'); // Submit the password reset request. - $return = $model->processResetRequest($data); + $return = $model->processResetRequest($data); // Check for a hard error. if ($return instanceof Exception) @@ -50,40 +50,25 @@ public function request() $message = JText::_('COM_USERS_RESET_REQUEST_ERROR'); } - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset' . $itemid; - // Go back to the request form. - $this->setRedirect(JRoute::_($route, false), $message, 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset', false), $message, 'error'); return false; } elseif ($return === false) { // The request failed. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset' . $itemid; - // Go back to the request form. $message = JText::sprintf('COM_USERS_RESET_REQUEST_FAILED', $model->getError()); - $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset', false), $message, 'notice'); return false; } else { // The request succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=confirm' . $itemid; - // Proceed to step two. - $this->setRedirect(JRoute::_($route, false)); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false)); return true; } @@ -107,7 +92,7 @@ public function confirm() $data = $this->input->get('jform', array(), 'array'); // Confirm the password reset request. - $return = $model->processResetConfirm($data); + $return = $model->processResetConfirm($data); // Check for a hard error. if ($return instanceof Exception) @@ -122,40 +107,25 @@ public function confirm() $message = JText::_('COM_USERS_RESET_CONFIRM_ERROR'); } - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=confirm' . $itemid; - // Go back to the confirm form. - $this->setRedirect(JRoute::_($route, false), $message, 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'error'); return false; } elseif ($return === false) { // Confirm failed. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=confirm' . $itemid; - // Go back to the confirm form. $message = JText::sprintf('COM_USERS_RESET_CONFIRM_FAILED', $model->getError()); - $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=confirm', false), $message, 'notice'); return false; } else { // Confirm succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=complete' . $itemid; - // Proceed to step three. - $this->setRedirect(JRoute::_($route, false)); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false)); return true; } @@ -178,7 +148,7 @@ public function complete() $data = $this->input->post->get('jform', array(), 'array'); // Complete the password reset request. - $return = $model->processResetComplete($data); + $return = $model->processResetComplete($data); // Check for a hard error. if ($return instanceof Exception) @@ -193,41 +163,26 @@ public function complete() $message = JText::_('COM_USERS_RESET_COMPLETE_ERROR'); } - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=complete' . $itemid; - // Go back to the complete form. - $this->setRedirect(JRoute::_($route, false), $message, 'error'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false), $message, 'error'); return false; } elseif ($return === false) { // Complete failed. - // Get the route to the next page. - $itemid = UsersHelperRoute::getResetRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=reset&layout=complete' . $itemid; - // Go back to the complete form. $message = JText::sprintf('COM_USERS_RESET_COMPLETE_FAILED', $model->getError()); - $this->setRedirect(JRoute::_($route, false), $message, 'notice'); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=reset&layout=complete', false), $message, 'notice'); return false; } else { // Complete succeeded. - // Get the route to the next page. - $itemid = UsersHelperRoute::getLoginRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $route = 'index.php?option=com_users&view=login' . $itemid; - // Proceed to the login form. $message = JText::_('COM_USERS_RESET_COMPLETE_SUCCESS'); - $this->setRedirect(JRoute::_($route, false), $message); + $this->setRedirect(JRoute::_('index.php?option=com_users&view=login', false), $message); return true; } diff --git a/components/com_users/helpers/legacyrouter.php b/components/com_users/helpers/legacyrouter.php new file mode 100644 index 0000000000000..0bb6eaa6f540e --- /dev/null +++ b/components/com_users/helpers/legacyrouter.php @@ -0,0 +1,294 @@ +router = $router; + } + + /** + * Preprocess the route for the com_users component + * + * @param array &$query An array of URL arguments + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function preprocess(&$query) + { + } + + /** + * Build the route for the com_users component + * + * @param array &$query An array of URL arguments + * @param array &$segments The URL arguments to use to assemble the subsequent URL. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function build(&$query, &$segments) + { + // Declare static variables. + static $items; + static $default; + static $registration; + static $profile; + static $login; + static $remind; + static $resend; + static $reset; + + // Get the relevant menu items if not loaded. + if (empty($items)) + { + // Get all relevant menu items. + $items = $this->router->menu->getItems('component', 'com_users'); + + // Build an array of serialized query strings to menu item id mappings. + for ($i = 0, $n = count($items); $i < $n; $i++) + { + // Check to see if we have found the resend menu item. + if (empty($resend) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'resend')) + { + $resend = $items[$i]->id; + } + + // Check to see if we have found the reset menu item. + if (empty($reset) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'reset')) + { + $reset = $items[$i]->id; + } + + // Check to see if we have found the remind menu item. + if (empty($remind) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'remind')) + { + $remind = $items[$i]->id; + } + + // Check to see if we have found the login menu item. + if (empty($login) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'login')) + { + $login = $items[$i]->id; + } + + // Check to see if we have found the registration menu item. + if (empty($registration) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'registration')) + { + $registration = $items[$i]->id; + } + + // Check to see if we have found the profile menu item. + if (empty($profile) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'profile')) + { + $profile = $items[$i]->id; + } + } + + // Set the default menu item to use for com_users if possible. + if ($profile) + { + $default = $profile; + } + elseif ($registration) + { + $default = $registration; + } + elseif ($login) + { + $default = $login; + } + } + + if (!empty($query['view'])) + { + switch ($query['view']) + { + case 'reset': + if ($query['Itemid'] = $reset) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'resend': + if ($query['Itemid'] = $resend) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'remind': + if ($query['Itemid'] = $remind) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'login': + if ($query['Itemid'] = $login) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + case 'registration': + if ($query['Itemid'] = $registration) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + break; + + default: + case 'profile': + if (!empty($query['view'])) + { + $segments[] = $query['view']; + } + + unset ($query['view']); + + if ($query['Itemid'] = $profile) + { + unset ($query['view']); + } + else + { + $query['Itemid'] = $default; + } + + // Only append the user id if not "me". + $user = JFactory::getUser(); + + if (!empty($query['user_id']) && ($query['user_id'] != $user->id)) + { + $segments[] = $query['user_id']; + } + + unset ($query['user_id']); + + break; + } + } + + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = str_replace(':', '-', $segments[$i]); + } + } + + /** + * Parse the segments of a URL. + * + * @param array &$segments The segments of the URL to parse. + * @param array &$vars The URL attributes to be used by the application. + * + * @return void + * + * @since 3.6 + * @deprecated 4.0 + */ + public function parse(&$segments, &$vars) + { + $total = count($segments); + + for ($i = 0; $i < $total; $i++) + { + $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); + } + + // Only run routine if there are segments to parse. + if (count($segments) < 1) + { + return; + } + + // Get the package from the route segments. + $userId = array_pop($segments); + + if (!is_numeric($userId)) + { + $vars['view'] = 'profile'; + + return; + } + + if (is_numeric($userId)) + { + $db = JFactory::getDbo(); + $query = $db->getQuery(true) + ->select($db->quoteName('id')) + ->from($db->quoteName('#__users')) + ->where($db->quoteName('id') . ' = ' . (int) $userId); + $db->setQuery($query); + $userId = $db->loadResult(); + } + + // Set the package id if present. + if ($userId) + { + // Set the package id. + $vars['user_id'] = (int) $userId; + + // Set the view to package if not already set. + if (empty($vars['view'])) + { + $vars['view'] = 'profile'; + } + } + else + { + JError::raiseError(404, JText::_('JGLOBAL_RESOURCE_NOT_FOUND')); + } + } +} diff --git a/components/com_users/helpers/route.php b/components/com_users/helpers/route.php index cdca8373d3f1c..5a9fa797f0ab1 100644 --- a/components/com_users/helpers/route.php +++ b/components/com_users/helpers/route.php @@ -12,7 +12,8 @@ /** * Users Route Helper * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 */ class UsersHelperRoute { @@ -21,7 +22,8 @@ class UsersHelperRoute * * @return array An array of menu items. * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 */ public static function &getItems() { @@ -50,8 +52,8 @@ public static function &getItems() * * @return mixed Integer menu id on success, null on failure. * - * @since 1.6 - * @static + * @since 1.6 + * @deprecated 4.0 */ public static function getLoginRoute() { @@ -77,7 +79,8 @@ public static function getLoginRoute() * * @return mixed Integer menu id on success, null on failure. * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 */ public static function getProfileRoute() { @@ -105,7 +108,8 @@ public static function getProfileRoute() * * @return mixed Integer menu id on success, null on failure. * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 */ public static function getRegistrationRoute() { @@ -131,7 +135,8 @@ public static function getRegistrationRoute() * * @return mixed Integer menu id on success, null on failure. * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 */ public static function getRemindRoute() { @@ -157,7 +162,8 @@ public static function getRemindRoute() * * @return mixed Integer menu id on success, null on failure. * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 */ public static function getResendRoute() { @@ -183,7 +189,8 @@ public static function getResendRoute() * * @return mixed Integer menu id on success, null on failure. * - * @since 1.6 + * @since 1.6 + * @deprecated 4.0 */ public static function getResetRoute() { diff --git a/components/com_users/models/remind.php b/components/com_users/models/remind.php index c6238558e9026..4888c9435b55f 100644 --- a/components/com_users/models/remind.php +++ b/components/com_users/models/remind.php @@ -158,9 +158,7 @@ public function processRemindRequest($data) $config = JFactory::getConfig(); // Assemble the login link. - $itemid = UsersHelperRoute::getLoginRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $link = 'index.php?option=com_users&view=login' . $itemid; + $link = 'index.php?option=com_users&view=login'; $mode = $config->get('force_ssl', 0) == 2 ? 1 : (-1); // Put together the email template data. diff --git a/components/com_users/models/reset.php b/components/com_users/models/reset.php index eef0d87187639..ed37b3191e364 100644 --- a/components/com_users/models/reset.php +++ b/components/com_users/models/reset.php @@ -447,9 +447,7 @@ public function processResetRequest($data) // Assemble the password reset confirmation link. $mode = $config->get('force_ssl', 0) == 2 ? 1 : (-1); - $itemid = UsersHelperRoute::getLoginRoute(); - $itemid = $itemid !== null ? '&Itemid=' . $itemid : ''; - $link = 'index.php?option=com_users&view=reset&layout=confirm&token=' . $token . $itemid; + $link = 'index.php?option=com_users&view=reset&layout=confirm&token=' . $token; // Put together the email template data. $data = $user->getProperties(); diff --git a/components/com_users/router.php b/components/com_users/router.php index 082b73e90532a..73fee2ac22bf3 100644 --- a/components/com_users/router.php +++ b/components/com_users/router.php @@ -14,257 +14,39 @@ * * @since 3.2 */ -class UsersRouter extends JComponentRouterBase +class UsersRouter extends JComponentRouterView { /** - * Build the route for the com_users component - * - * @param array &$query An array of URL arguments - * - * @return array The URL arguments to use to assemble the subsequent URL. - * - * @since 3.3 + * Users Component router constructor + * + * @param JApplicationCms $app The application object + * @param JMenu $menu The menu object to work with */ - public function build(&$query) + public function __construct($app = null, $menu = null) { - // Declare static variables. - static $items; - static $default; - static $registration; - static $profile; - static $login; - static $remind; - static $resend; - static $reset; + $this->registerView(new JComponentRouterViewconfiguration('login')); + $profile = new JComponentRouterViewconfiguration('profile'); + $profile->addLayout('edit'); + $this->registerView($profile); + $this->registerView(new JComponentRouterViewconfiguration('registration')); + $this->registerView(new JComponentRouterViewconfiguration('remind')); + $this->registerView(new JComponentRouterViewconfiguration('reset')); - $segments = array(); + parent::__construct($app, $menu); - // Get the relevant menu items if not loaded. - if (empty($items)) - { - // Get all relevant menu items. - $items = $this->menu->getItems('component', 'com_users'); - - // Build an array of serialized query strings to menu item id mappings. - for ($i = 0, $n = count($items); $i < $n; $i++) - { - // Check to see if we have found the resend menu item. - if (empty($resend) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'resend')) - { - $resend = $items[$i]->id; - } - - // Check to see if we have found the reset menu item. - if (empty($reset) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'reset')) - { - $reset = $items[$i]->id; - } - - // Check to see if we have found the remind menu item. - if (empty($remind) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'remind')) - { - $remind = $items[$i]->id; - } - - // Check to see if we have found the login menu item. - if (empty($login) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'login')) - { - $login = $items[$i]->id; - } - - // Check to see if we have found the registration menu item. - if (empty($registration) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'registration')) - { - $registration = $items[$i]->id; - } - - // Check to see if we have found the profile menu item. - if (empty($profile) && !empty($items[$i]->query['view']) && ($items[$i]->query['view'] == 'profile')) - { - $profile = $items[$i]->id; - } - } - - // Set the default menu item to use for com_users if possible. - if ($profile) - { - $default = $profile; - } - elseif ($registration) - { - $default = $registration; - } - elseif ($login) - { - $default = $login; - } - } - - if (!empty($query['view'])) - { - switch ($query['view']) - { - case 'reset': - if ($query['Itemid'] = $reset) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - case 'resend': - if ($query['Itemid'] = $resend) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - case 'remind': - if ($query['Itemid'] = $remind) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - case 'login': - if ($query['Itemid'] = $login) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - case 'registration': - if ($query['Itemid'] = $registration) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - break; - - default: - case 'profile': - if (!empty($query['view'])) - { - $segments[] = $query['view']; - } - - unset ($query['view']); - - if ($query['Itemid'] = $profile) - { - unset ($query['view']); - } - else - { - $query['Itemid'] = $default; - } - - // Only append the user id if not "me". - $user = JFactory::getUser(); - - if (!empty($query['user_id']) && ($query['user_id'] != $user->id)) - { - $segments[] = $query['user_id']; - } - - unset ($query['user_id']); - - break; - } - } - - $total = count($segments); + $this->attachRule(new JComponentRouterRulesMenu($this)); - for ($i = 0; $i < $total; $i++) - { - $segments[$i] = str_replace(':', '-', $segments[$i]); - } - - return $segments; - } - - /** - * Parse the segments of a URL. - * - * @param array &$segments The segments of the URL to parse. - * - * @return array The URL attributes to be used by the application. - * - * @since 3.3 - */ - public function parse(&$segments) - { - $total = count($segments); - $vars = array(); - - for ($i = 0; $i < $total; $i++) - { - $segments[$i] = preg_replace('/-/', ':', $segments[$i], 1); - } - - // Only run routine if there are segments to parse. - if (count($segments) < 1) - { - return; - } - - // Get the package from the route segments. - $userId = array_pop($segments); - - if (!is_numeric($userId)) - { - $vars['view'] = 'profile'; - - return $vars; - } - - if (is_numeric($userId)) - { - $db = JFactory::getDbo(); - $query = $db->getQuery(true) - ->select($db->quoteName('id')) - ->from($db->quoteName('#__users')) - ->where($db->quoteName('id') . ' = ' . (int) $userId); - $db->setQuery($query); - $userId = $db->loadResult(); - } + $params = JComponentHelper::getParams('com_content'); - // Set the package id if present. - if ($userId) + if ($params->get('sef_advanced', 0)) { - // Set the package id. - $vars['user_id'] = (int) $userId; - - // Set the view to package if not already set. - if (empty($vars['view'])) - { - $vars['view'] = 'profile'; - } + $this->attachRule(new JComponentRouterRulesStandard($this)); } else { - JError::raiseError(404, JText::_('JGLOBAL_RESOURCE_NOT_FOUND')); + require_once JPATH_SITE . '/components/com_users/helpers/legacyrouter.php'; + $this->attachRule(new UsersRouterRulesLegacy($this)); } - - return $vars; } } @@ -282,7 +64,8 @@ public function parse(&$segments) */ function usersBuildRoute(&$query) { - $router = new UsersRouter; + $app = JFactory::getApplication(); + $router = new UsersRouter($app, $app->getMenu()); return $router->build($query); } @@ -298,7 +81,8 @@ function usersBuildRoute(&$query) */ function usersParseRoute($segments) { - $router = new UsersRouter; + $app = JFactory::getApplication(); + $router = new UsersRouter($app, $app->getMenu()); return $router->parse($segments); } diff --git a/libraries/cms/component/router/rules/menu.php b/libraries/cms/component/router/rules/menu.php new file mode 100644 index 0000000000000..da5304f31d29a --- /dev/null +++ b/libraries/cms/component/router/rules/menu.php @@ -0,0 +1,242 @@ +router = $router; + + $this->buildLookup(); + } + + /** + * Finds the right Itemid for this query + * + * @param array &$query The query array to process + * + * @return void + * + * @since 3.4 + */ + public function preprocess(&$query) + { + if (isset($query['Itemid']) && $this->router->menu->getActive() && $query['Itemid'] != $this->router->menu->getActive()->id) + { + return; + } + + $language = '*'; + if (isset($query['lang'])) + { + $language = $query['lang']; + + if (!isset($this->lookup[$query['lang']])) + { + $this->buildLookup($query['lang']); + } + } + + $needles = $this->router->getPath($query); + + $layout = ''; + + if (isset($query['layout'])) + { + $layout = ':' . $query['layout']; + } + + if ($needles) + { + foreach ($needles as $view => $ids) + { + if (isset($this->lookup[$language][$view . $layout])) + { + if (is_bool($ids)) + { + $query['Itemid'] = $this->lookup[$language][$view . $layout]; + return; + } + foreach ($ids as $id) + { + if (isset($this->lookup[$language][$view . $layout][(int) $id])) + { + $query['Itemid'] = $this->lookup[$language][$view . $layout][(int) $id]; + return; + } + + if (isset($this->lookup[$language][$view][(int) $id])) + { + $query['Itemid'] = $this->lookup[$language][$view][(int) $id]; + return; + } + } + } + } + } + + // Check if the active menuitem matches the requested language + $active = $this->router->menu->getActive(); + + if ($active && $active->component == 'com_' . $this->router->getName() + && ($language == '*' || in_array($active->language, array('*', $language)) || !JLanguageMultilang::isEnabled())) + { + $query['Itemid'] = $active->id; + return; + } + + // If not found, return language specific home link + $default = $this->router->menu->getDefault($language); + + if (!empty($default->id)) + { + $query['Itemid'] = $default->id; + } + } + + /** + * Method to build the lookup array + * + * @param string $language The language that the lookup should be built up for + * + * @return void + * + * @since 3.4 + */ + protected function buildLookup($language = '*') + { + // Prepare the reverse lookup array. + if (!isset($this->lookup[$language])) + { + $this->lookup[$language] = array(); + + $component = JComponentHelper::getComponent('com_' . $this->router->getName()); + $views = $this->router->getViews(); + + $attributes = array('component_id'); + $values = array((int) $component->id); + + $attributes[] = 'language'; + $values[] = array($language, '*'); + + $items = $this->router->menu->getItems($attributes, $values); + + foreach ($items as $item) + { + if (isset($item->query) && isset($item->query['view'])) + { + $view = $item->query['view']; + + $layout = ''; + + if (isset($item->query['layout'])) + { + $layout = ':' . $item->query['layout']; + } + + if ($views[$view]->key) + { + if (!isset($this->lookup[$language][$view . $layout])) + { + $this->lookup[$language][$view . $layout] = array(); + } + + if (!isset($this->lookup[$language][$view])) + { + $this->lookup[$language][$view] = array(); + } + + /** + * Here it will become a bit tricky + * language != * can override existing entries + * language == * cannot override existing entries + */ + if (isset($item->query[$views[$view]->key]) + && (!isset($this->lookup[$language][$view . $layout][$item->query[$views[$view]->key]]) || $item->language != '*')) + { + $this->lookup[$language][$view . $layout][$item->query[$views[$view]->key]] = $item->id; + $this->lookup[$language][$view][$item->query[$views[$view]->key]] = $item->id; + } + } + else + { + /** + * Here it will become a bit tricky + * language != * can override existing entries + * language == * cannot override existing entries + */ + if (!isset($this->lookup[$language][$view . $layout]) || $item->language != '*') + { + $this->lookup[$language][$view . $layout] = $item->id; + $this->lookup[$language][$view] = $item->id; + } + } + } + } + } + } + + /** + * Dummymethod to fullfill the interface requirements + * + * @param array &$segments The URL segments to parse + * @param array &$vars The vars that result from the segments + * + * @return void + * + * @since 3.4 + * @codeCoverageIgnore + */ + public function parse(&$segments, &$vars) + { + } + + /** + * Dummymethod to fullfill the interface requirements + * + * @param array &$query The vars that should be converted + * @param array &$segments The URL segments to create + * + * @return void + * + * @since 3.4 + * @codeCoverageIgnore + */ + public function build(&$query, &$segments) + { + } +} diff --git a/libraries/cms/component/router/rules/nomenu.php b/libraries/cms/component/router/rules/nomenu.php new file mode 100644 index 0000000000000..f0d269d23b2d7 --- /dev/null +++ b/libraries/cms/component/router/rules/nomenu.php @@ -0,0 +1,110 @@ +router = $router; + } + + /** + * Dummymethod to fullfill the interface requirements + * + * @param array &$query The query array to process + * + * @return void + * + * @since 3.4 + * @codeCoverageIgnore + */ + public function preprocess(&$query) + { + } + + /** + * Parse a menu-less URL + * + * @param array &$segments The URL segments to parse + * @param array &$vars The vars that result from the segments + * + * @return void + * + * @since 3.4 + */ + public function parse(&$segments, &$vars) + { + $active = $this->router->menu->getActive(); + + if (!is_object($active)) + { + $views = $this->router->getViews(); + + if (isset($views[$segments[0]])) + { + $vars['view'] = array_shift($segments); + + if (isset($views[$vars['view']]->key) && isset($segments[0])) + { + $vars[$views[$vars['view']]->key] = preg_replace('/-/', ':', array_shift($segments), 1); + } + } + } + } + + /** + * Build a menu-less URL + * + * @param array &$query The vars that should be converted + * @param array &$segments The URL segments to create + * + * @return void + * + * @since 3.4 + */ + public function build(&$query, &$segments) + { + if (!isset($query['Itemid']) && isset($query['view'])) + { + $views = $this->router->getViews(); + if (isset($views[$query['view']])) + { + $segments[] = $query['view']; + + if ($views[$query['view']]->key) + { + $key = $views[$query['view']]->key; + $segments[] = str_replace(':', '-', $query[$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 new file mode 100644 index 0000000000000..8562eaaa50f5d --- /dev/null +++ b/libraries/cms/component/router/rules/standard.php @@ -0,0 +1,287 @@ +router = $router; + } + + /** + * Dummymethod to fullfill the interface requirements + * + * @param array &$query The query array to process + * + * @return void + * + * @since 3.4 + */ + public function preprocess(&$query) + { + } + + /** + * Parse the URL + * + * @param array &$segments The URL segments to parse + * @param array &$vars The vars that result from the segments + * + * @return void + * + * @since 3.4 + */ + public function parse(&$segments, &$vars) + { + // Get the views and the currently active query vars + $views = $this->router->getViews(); + $active = $this->router->menu->getActive(); + $vars = array_merge($active->query, $vars); + + // We don't have a view or its not a view of this component! We stop here + if (!isset($vars['view']) || !isset($views[$vars['view']])) + { + return; + } + + // Copy the segments, so that we can iterate over all of them and at the same time modify the original segments + $temp_segments = $segments; + + // Iterate over the segments as long as a segment fits + foreach ($temp_segments as $segment) + { + // Our current view is nestable. We need to check first if the segment fits to that + if ($views[$vars['view']]->nestable) + { + if (is_callable(array($this->router, 'get' . ucfirst($views[$vars['view']]->name) . 'Id'))) + { + $key = call_user_func_array(array($this->router, 'get' . ucfirst($views[$vars['view']]->name) . 'Id'), array($segment, $vars)); + + // Did we get a proper key? If not, we need to look in the child-views + if ($key) + { + $vars[$views[$vars['view']]->key] = $key; + array_shift($segments); + continue; + } + } + else + { + // The router is not complete. The getKey() method is missing. + return; + } + } + + // Lets find the right view that belongs to this segment + $found = false; + foreach ($views[$vars['view']]->children as $view) + { + if (!$view->key) + { + if ($view->name == $segment) + { + // The segment is a view name + $parent = $views[$vars['view']]; + $vars['view'] = $view->name; + $found = true; + + if ($view->parent_key && isset($vars[$parent->key])) + { + $parent_key = $vars[$parent->key]; + unset($vars[$parent->key]); + $vars[$view->parent_key] = $parent_key; + } + + break; + } + } + else + { + if (is_callable(array($this->router, 'get' . ucfirst($view->name) . 'Id'))) + { + // Hand the data over to the router specific method and see if there is a content item that fits + $key = call_user_func_array(array($this->router, 'get' . ucfirst($view->name) . 'Id'), array($segment, $vars)); + + if ($key) + { + // Found the right view and the right item + $parent = $views[$vars['view']]; + $vars['view'] = $view->name; + $found = true; + + if ($view->parent_key && isset($vars[$parent->key])) + { + $parent_key = $vars[$parent->key]; + unset($vars[$parent->key]); + $vars[$view->parent_key] = $parent_key; + } + + $vars[$view->key] = $key; + + break; + } + } + } + } + + if (!$found) + { + return; + } + else + { + array_shift($segments); + } + } + } + + /** + * Build a standard URL + * + * @param array &$query The vars that should be converted + * @param array &$segments The URL segments to create + * + * @return void + * + * @since 3.4 + */ + public function build(&$query, &$segments) + { + // Get the menu item belonging to the Itemid that has been found + $item = $this->router->menu->getItem($query['Itemid']); + + if (!isset($query['view'])) + { + return; + } + + // Get all views for this component + $views = $this->router->getViews(); + + // Return directly when the URL of the Itemid is identical with the URL to build + if (isset($item->query['view']) && $item->query['view'] == $query['view']) + { + $view = $views[$query['view']]; + + if (isset($item->query[$view->key]) && $item->query[$view->key] == (int) $query[$view->key]) + { + unset($query[$view->key]); + while ($view) + { + unset($query[$view->parent_key]); + $view = $view->parent; + } + unset($query['view']); + + if (isset($item->query['layout']) && isset($query['layout']) && $item->query['layout'] == $query['layout']) + { + unset($query['layout']); + } + + return; + } + + if (!$view->key) + { + if (isset($item->query['layout']) && isset($query['layout']) && $item->query['layout'] == $query['layout']) + { + unset($query['view']); + unset($query['layout']); + return; + } + } + } + + // Get the path from the view of the current URL and parse it to the menu item + $path = array_reverse($this->router->getPath($query)); + $found = false; + $found2 = false; + for ($i = 0, $j = count($path); $i < $j; $i++) + { + reset($path); + $view = key($path); + if ($found) + { + $ids = array_shift($path); + if ($views[$view]->nestable) + { + foreach (array_reverse($ids) as $id) + { + if ($found2) + { + $segments[] = str_replace(':', '-', $id); + } + else + { + if ((int) $item->query[$views[$view]->key] == (int) $id) + { + $found2 = true; + } + } + } + } + else + { + if (is_bool($ids)) + { + $segments[] = $views[$view]->name; + } + else + { + $segments[] = str_replace(':', '-', $ids[0]); + } + } + } + else + { + if ($item->query['view'] != $view) + { + array_shift($path); + } + else + { + if (!$views[$view]->nestable) + { + array_shift($path); + } + else + { + $i--; + $found2 = false; + } + $found = true; + } + } + unset($query[$views[$view]->parent_key]); + } + unset($query['layout']); + unset($query[$views[$query['view']]->key]); + unset($query['view']); + } +} diff --git a/libraries/cms/component/router/view.php b/libraries/cms/component/router/view.php index 2fb145a53740b..5bb960a116bab 100644 --- a/libraries/cms/component/router/view.php +++ b/libraries/cms/component/router/view.php @@ -111,9 +111,20 @@ public function getPath($query) $childkey = $view->parent_key; - if ($key && isset($query[$key]) && is_callable(array($this, 'get' . ucfirst($view->name) . 'Segment'))) + if (($key || $view->key) && is_callable(array($this, 'get' . ucfirst($view->name) . 'Segment'))) { - $result[$view->name] = call_user_func_array(array($this, 'get' . ucfirst($view->name) . 'Segment'), array($query[$key], $query)); + if (isset($query[$key])) + { + $result[$view->name] = call_user_func_array(array($this, 'get' . ucfirst($view->name) . 'Segment'), array($query[$key], $query)); + } + elseif (isset($query[$view->key])) + { + $result[$view->name] = call_user_func_array(array($this, 'get' . ucfirst($view->name) . 'Segment'), array($query[$view->key], $query)); + } + else + { + $result[$view->name] = array(); + } } else { @@ -229,6 +240,7 @@ public function build(&$query) { $rule->build($query, $segments); } + return $segments; } diff --git a/modules/mod_login/tmpl/default.php b/modules/mod_login/tmpl/default.php index 4f56a3d02a011..fff63775cbe9a 100644 --- a/modules/mod_login/tmpl/default.php +++ b/modules/mod_login/tmpl/default.php @@ -98,16 +98,16 @@ diff --git a/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php index f373b161012da..c786f135b4f56 100644 --- a/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php +++ b/tests/unit/suites/libraries/cms/component/router/JComponentRouterViewTest.php @@ -16,7 +16,7 @@ * * @package Joomla.UnitTest * @subpackage Component - * @since 3.4 + * @since 3.5 */ class JComponentRouterViewTest extends TestCaseDatabase { @@ -24,7 +24,7 @@ class JComponentRouterViewTest extends TestCaseDatabase * Object under test * * @var JComponentRouterView - * @since 3.4 + * @since 3.5 */ protected $object; @@ -34,7 +34,7 @@ class JComponentRouterViewTest extends TestCaseDatabase * * @return void * - * @since 3.4 + * @since 3.5 */ protected function setUp() { @@ -65,7 +65,7 @@ protected function getDataSet() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::registerView */ public function testRegisterView() @@ -85,7 +85,7 @@ public function testRegisterView() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::getViews */ public function testGetViews() @@ -100,15 +100,65 @@ public function testGetViews() $this->assertEquals($views, $this->object->getViews()); } + /** + * Cases for testGetPath + * + * @return array + * + * @since 3.5 + */ + public function casesGetPath() + { + $cases = array(); + // No view, so we don't have a path to return. + $cases[] = array(array('task' => 'edit'), array()); + + // View without any parents and children + $cases[] = array(array('view' => 'form'), array('form' => true)); + + // View without any parents, but with children + $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'))); + + //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') + ) + ); + + //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' + ), + 'categories' => array('20:extensions', + '19:joomla', + '14:sample-data-articles' + ) + ) + ); + + return $cases; + } + /** * Tests the getPath() method * * @return void * - * @since 3.4 + * @dataProvider casesGetPath + * @since 3.5 * @covers JComponentRouterView::getPath */ - public function testGetPath() + public function testGetPath($input, $result) { // This test requires an application registered to JFactory $this->saveFactoryState(); @@ -122,41 +172,7 @@ public function testGetPath() $this->object->registerView($view); } - // No view, so we don't have a path to return. - $query = array('task' => 'edit'); - $this->assertEquals(array(), $this->object->getPath($query)); - - // View without any parents and children - $query = array('view' => 'form'); - $this->assertEquals(array('form' => true), $this->object->getPath($query)); - - // View without any parents, but with children - $query = array('view' => 'categories'); - $this->assertEquals(array('categories' => true), $this->object->getPath($query)); - - // View with parent and children - $query = array('view' => 'category', 'id' => '9'); - $this->assertEquals(array('category' => array('9:uncategorised'), 'categories' => true), $this->object->getPath($query)); - - //View with parent, no children - $query = array('view' => 'article', 'id' => '42:question-for-everything', 'catid' => '9'); - $this->assertEquals(array( - 'article' => array('42:question-for-everything'), - 'category' => array('9:uncategorised'), - 'categories' => true), - $this->object->getPath($query)); - - //View with parent, no children and nested view - $query = array('view' => 'article', 'id' => '42:question-for-everything', 'catid' => '20'); - $this->assertEquals(array( - 'article' => array('42:question-for-everything'), - 'category' => array('20:extensions', - '19:joomla', - '14:sample-data-articles' - ), - 'categories' => true), - $this->object->getPath($query) - ); + $this->assertEquals($result, $this->object->getPath($input)); $this->restoreFactoryState(); } @@ -166,7 +182,7 @@ public function testGetPath() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::getRules */ public function testGetRules() @@ -181,7 +197,7 @@ public function testGetRules() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::attachRules */ public function testAttachRules() @@ -197,7 +213,7 @@ public function testAttachRules() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::attachRule */ public function testAttachRule() @@ -215,7 +231,7 @@ public function testAttachRule() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::detachRule */ public function testDetachRule() @@ -233,7 +249,7 @@ public function testDetachRule() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::preprocess */ public function testPreprocess() @@ -248,7 +264,7 @@ public function testPreprocess() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::build */ public function testBuild() @@ -265,7 +281,7 @@ public function testBuild() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::parse */ public function testParse() @@ -282,7 +298,7 @@ public function testParse() * * @return void * - * @since 3.4 + * @since 3.5 * @covers JComponentRouterView::getName */ public function testGetName() @@ -298,7 +314,7 @@ public function testGetName() * * @return void * - * @since 3.4 + * @since 3.5 * @expectedException Exception * @covers JComponentRouterView::getName */ @@ -316,8 +332,9 @@ public function testGetNameException() protected function getComContentViews() { $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); $category = new JComponentRouterViewconfiguration('category'); - $category->setKey('id')->setParent($categories)->setNestable()->addLayout('blog'); + $category->setKey('id')->setParent($categories, 'catid')->setNestable()->addLayout('blog'); $article = new JComponentRouterViewconfiguration('article'); $article->setKey('id')->setParent($category, 'catid'); $archive = new JComponentRouterViewconfiguration('archive'); diff --git a/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesMenuTest.php b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesMenuTest.php new file mode 100644 index 0000000000000..38176227a76d3 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesMenuTest.php @@ -0,0 +1,237 @@ +getMockCmsApp(); + JFactory::$application = $app; + $router = new JComponentRouterViewInspector($app, $app->getMenu()); + $router->set('name', 'content'); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $router->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories)->setNestable()->addLayout('blog'); + $router->registerView($category); + $article = new JComponentRouterViewconfiguration('article'); + $article->setKey('id')->setParent($category, 'catid'); + $router->registerView($article); + $archive = new JComponentRouterViewconfiguration('archive'); + $router->registerView($archive); + $featured = new JComponentRouterViewconfiguration('featured'); + $router->registerView($featured); + $form = new JComponentRouterViewconfiguration('form'); + $router->registerView($form); + $router->menu = new MockJComponentRouterRulesMenuMenuObject(); + + $this->object = new JComponentRouterRulesMenuInspector($router); + } + + /** + * Gets the data set to be loaded into the database during setup + * + * @return PHPUnit_Extensions_Database_DataSet_CsvDataSet + * + * @since 3.5 + */ + protected function getDataSet() + { + $dataSet = new PHPUnit_Extensions_Database_DataSet_CsvDataSet(',', "'", '\\'); + + $dataSet->addTable('jos_categories', JPATH_TEST_DATABASE . '/jos_categories.csv'); + $dataSet->addTable('jos_extensions', JPATH_TEST_DATABASE . '/jos_extensions.csv'); + + return $dataSet; + } + + /** + * Tests the __construct() method + * + * @return void + * + * @since 3.5 + */ + public function testConstruct() + { + $this->assertInstanceOf('JComponentRouterRulesMenu', $this->object); + $this->assertInstanceOf('JComponentRouterView', $this->object->get('router')); + $this->assertEquals(array( + '*' => array( + 'featured' => '47', + 'categories' => array(14 => '48'), + 'category' => array (20 => '49')) + ), $this->object->get('lookup')); + } + + /** + * Cases for testPreprocess + * + * @return array + * + * @since 3.5 + */ + public function casesPreprocess() + { + $cases = array(); + + // Check direct link to a simple view + $cases[] = array(array('option' => 'com_content', 'view' => 'featured'), + array('option' => 'com_content', 'view' => 'featured', 'Itemid' => '47')); + + // Check direct link to a simple view with a language + $cases[] = array(array('option' => 'com_content', 'view' => 'featured', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'featured', 'lang' => 'en-GB', 'Itemid' => '51')); + + // Check direct link to a view with a key + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '14'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'Itemid' => '48')); + + // Check direct link to a view with a key with a language + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'lang' => 'en-GB', 'Itemid' => '50')); + + // Check indirect link to a nested view with a key + $cases[] = array(array('option' => 'com_content', 'view' => 'category', 'id' => '22'), + array('option' => 'com_content', 'view' => 'category', 'id' => '22', 'Itemid' => '49')); + + // Check indirect link to a nested view with a key and a language + $cases[] = array(array('option' => 'com_content', 'view' => 'category', 'id' => '22', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'category', 'id' => '22', 'lang' => 'en-GB', 'Itemid' => '49')); + + // Check indirect link to a single view behind a nested view with a key + $cases[] = array(array('option' => 'com_content', 'view' => 'article', 'id' => '42', 'catid' => '22'), + array('option' => 'com_content', 'view' => 'article', 'id' => '42', 'catid' => '22', 'Itemid' => '49')); + + // Check indirect link to a single view behind a nested view with a key and language + $cases[] = array(array('option' => 'com_content', 'view' => 'article', 'id' => '42', 'catid' => '22', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'article', 'id' => '42', 'catid' => '22', 'lang' => 'en-GB', 'Itemid' => '49')); + + // Check non-existing menu link + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '42'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'Itemid' => '49')); + + // Check indirect link to a single view behind a nested view with a key and language + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'lang' => 'en-GB'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'lang' => 'en-GB', 'Itemid' => '49')); + + // Check if a query with existing Itemid that is not the current active menu-item is not touched + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'Itemid' => '99'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '42', 'Itemid' => '99')); + + // Check if a query with existing Itemid that is the current active menu-item is correctly searched + $cases[] = array(array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'Itemid' => '49'), + array('option' => 'com_content', 'view' => 'categories', 'id' => '14', 'Itemid' => '48')); + + return $cases; + } + + /** + * Tests the preprocess() method + * + * @return void + * + * @dataProvider casesPreprocess + * @since 3.5 + */ + public function testPreprocess($input, $result) + { + $this->saveFactoryState(); + + $this->object->preprocess($input); + $this->assertEquals($result, $input); + + $this->restoreFactoryState(); + } + + /** + * Tests the preprocess() method + * + * @return void + * + * @since 3.5 + */ + public function testPreprocessLanguage() + { + $this->saveFactoryState(); + + // Test if the default Itemid is used if everything else fails + $router = $this->object->get('router'); + $router->menu->active = null; + $query = array(); + $this->object->preprocess($query); + $this->assertEquals(array('Itemid' => '47'), $query); + + // Test if the correct default item is used based on the language + $query = array('lang' => 'en-GB'); + $this->object->preprocess($query); + $this->assertEquals(array('lang' => 'en-GB', 'Itemid' => '51'), $query); + + $this->restoreFactoryState(); + } + + /** + * Tests the buildLookup() method + * + * @return void + * + * @since 3.5 + */ + public function testBuildLookup() + { + $this->assertEquals(array( + '*' => array( + 'featured' => '47', + 'categories' => array(14 => '48'), + 'category' => array (20 => '49')) + ), $this->object->get('lookup')); + + $this->object->runBuildLookUp('en-GB'); + $this->assertEquals(array( + '*' => array( + 'featured' => '47', + 'categories' => array(14 => '48'), + 'category' => array (20 => '49')), + 'en-GB' => array( + 'featured' => '51', + 'categories' => array(14 => '50'), + 'category' => array (20 => '49')) + ), $this->object->get('lookup')); + } +} diff --git a/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php new file mode 100644 index 0000000000000..029d819fa4893 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/JComponentRouterRulesNomenuTest.php @@ -0,0 +1,163 @@ +getMockCmsApp(); + $router = new JComponentRouterViewInspector($app, $app->getMenu()); + $router->set('name', 'content'); + $categories = new JComponentRouterViewconfiguration('categories'); + $categories->setKey('id'); + $router->registerView($categories); + $category = new JComponentRouterViewconfiguration('category'); + $category->setKey('id')->setParent($categories)->setNestable()->addLayout('blog'); + $router->registerView($category); + $article = new JComponentRouterViewconfiguration('article'); + $article->setKey('id')->setParent($category, 'catid'); + $router->registerView($article); + $archive = new JComponentRouterViewconfiguration('archive'); + $router->registerView($archive); + $featured = new JComponentRouterViewconfiguration('featured'); + $router->registerView($featured); + $form = new JComponentRouterViewconfiguration('form'); + $router->registerView($form); + + $this->object = new JComponentRouterRulesNomenuInspector($router); + } + + /** + * Tests the __construct() method + * + * @return void + * + * @since 3.4 + */ + public function testConstruct() + { + $this->assertInstanceOf('JComponentRouterRulesNomenu', $this->object); + $this->assertInstanceOf('JComponentRouterView', $this->object->get('router')); + } + + /** + * Tests the parse() method + * + * @return void + * + * @since 3.4 + */ + public function testParse() + { + // Check if a false view is properly rejected + $segments = array('falseview'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array('falseview'), $segments); + $this->assertEquals(array('option' => 'com_content'), $vars); + + // Check if a single view is properly parsed + $segments = array('featured'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array(), $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'featured'), $vars); + + // Check if a view with ID is properly parsed + $segments = array('category', '23-the-question'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array(), $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'category', 'id' => '23:the-question'), $vars); + + // Check if a view that normally has an ID but which is missing is properly parsed + $segments = array('category'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array(), $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'category'), $vars); + + // Test if the rule is properly skipped when a menu item is set + $router = $this->object->get('router'); + $router->menu->expects($this->any()) + ->method('getActive') + ->will($this->returnValue(new stdClass())); + $segments = array('article', '42:the-answer'); + $vars = array('option' => 'com_content'); + $this->object->parse($segments, $vars); + $this->assertEquals(array('article', '42:the-answer'), $segments); + $this->assertEquals(array('option' => 'com_content'), $vars); + } + + /** + * Tests the build() method + * + * @return void + * + * @since 3.4 + */ + 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'); + $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(), $segments); + + // Test if a false view is properly not treated + $query = array('option' => 'com_content', 'view' => 'falseview', 'id' => '42:the-answer'); + $segments = array(); + $this->object->build($query, $segments); + $this->assertEquals(array('option' => 'com_content', 'view' => 'falseview', 'id' => '42:the-answer'), $query); + $this->assertEquals(array(), $segments); + + // Test if a single view without identifier is properly build + $query = array('option' => 'com_content', 'view' => 'featured'); + $segments = array(); + $this->object->build($query, $segments); + $this->assertEquals(array('option' => 'com_content'), $query); + $this->assertEquals(array('featured'), $segments); + + // Test if a single view with identifier is properly build + $query = array('option' => 'com_content', 'view' => 'article', 'id' => '42:the-answer'); + $segments = array(); + $this->object->build($query, $segments); + $this->assertEquals(array('option' => 'com_content'), $query); + $this->assertEquals(array('article', '42-the-answer'), $segments); + } +} diff --git a/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesMenuInspector.php b/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesMenuInspector.php new file mode 100644 index 0000000000000..774114d3ce917 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesMenuInspector.php @@ -0,0 +1,52 @@ +$key; + } + + /** + * Sets an attribute of the object + * + * @param string $key Attributename to return + * @param mixed $value Value to be set + * + * @return void + * + * @since 3.4 + */ + public function set($key, $value) + { + $this->$key = $value; + } + + public function runBuildLookup($language = '*') + { + return $this->buildLookup($language); + } +} \ No newline at end of file diff --git a/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesNomenuInspector.php b/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesNomenuInspector.php new file mode 100644 index 0000000000000..e6f45d319301b --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/stubs/JComponentRouterRulesNomenuInspector.php @@ -0,0 +1,47 @@ +$key; + } + + /** + * Sets an attribute of the object + * + * @param string $key Attributename to return + * @param mixed $value Value to be set + * + * @return void + * + * @since 3.4 + */ + public function set($key, $value) + { + $this->$key = $value; + } +} \ No newline at end of file diff --git a/tests/unit/suites/libraries/cms/component/router/rules/stubs/MockJComponentRouterRulesMenuMenuObject.php b/tests/unit/suites/libraries/cms/component/router/rules/stubs/MockJComponentRouterRulesMenuMenuObject.php new file mode 100644 index 0000000000000..58270e8d17296 --- /dev/null +++ b/tests/unit/suites/libraries/cms/component/router/rules/stubs/MockJComponentRouterRulesMenuMenuObject.php @@ -0,0 +1,196 @@ +items[47] = (object) array( + 'id' => '47', + 'menutype' => 'testmenu', + 'title' => 'Content Home', + 'alias' => 'content-home', + 'route' => 'content-home', + 'link' => 'index.php?option=com_content&view=featured', + 'type' => 'component', + 'level' => '1', + 'language' => '*', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '0', + 'query' => array('option' => 'com_content', 'view' => 'featured')); + + $this->items[48] = (object) array( + 'id' => '48', + 'menutype' => 'testmenu', + 'title' => 'Categories View', + 'alias' => 'categories', + 'route' => 'content-home/categories', + 'link' => 'index.php?option=com_content&view=categories&id=14', + 'type' => 'component', + 'level' => '2', + 'language' => '*', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '47', + 'query' => array('option' => 'com_content', 'view' => 'categories', 'id' => '14')); + + $this->items[49] = (object) array( + 'id' => '49', + 'menutype' => 'testmenu', + 'title' => 'Category View', + 'alias' => 'category-view', + 'route' => 'category-view', + 'link' => 'index.php?option=com_content&view=category&id=20', + 'type' => 'component', + 'level' => '1', + 'language' => '*', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '47', + 'query' => array('option' => 'com_content', 'view' => 'category', 'id' => '20')); + + $this->items[50] = (object) array( + 'id' => '50', + 'menutype' => 'testmenu', + 'title' => 'Categories View', + 'alias' => 'categories', + 'route' => 'content-home/categories', + 'link' => 'index.php?option=com_content&view=categories&id=14', + 'type' => 'component', + 'level' => '2', + 'language' => 'en-GB', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '47', + 'query' => array('option' => 'com_content', 'view' => 'categories', 'id' => '14')); + + $this->items[51] = (object) array( + 'id' => '51', + 'menutype' => 'testmenu', + 'title' => 'Content Home', + 'alias' => 'content-home', + 'route' => 'content-home', + 'link' => 'index.php?option=com_content&view=featured', + 'type' => 'component', + 'level' => '1', + 'language' => 'en-GB', + 'component_id' => '22', + 'component' => 'com_content', + 'parent_id' => '0', + 'query' => array('option' => 'com_content', 'view' => 'featured')); + } + + /** + * Gets the menu item set that fits the search array + * + * @param array $attributes Search criteria + * @param array $values Search criteria + * + * @return mixed Menu items + * + * @since 3.4 + */ + public function getItems($attributes, $values) + { + $items = array(); + $attributes = (array) $attributes; + $values = (array) $values; + + foreach ($this->items as $item) + { + $test = true; + + for ($i = 0, $count = count($attributes); $i < $count; $i++) + { + if (is_array($values[$i])) + { + if (!in_array($item->{$attributes[$i]}, $values[$i])) + { + $test = false; + break; + } + } + else + { + if ($item->{$attributes[$i]} != $values[$i]) + { + $test = false; + break; + } + } + } + + if ($test) + { + $items[] = $item; + } + } + + return $items; + } + + /** + * Return the currently active menuitem + * + * @return object Menuitem + * @since 3.4 + */ + public function getActive() + { + return (isset($this->items[$this->active]) ? $this->items[$this->active] : null); + } + + /** + * Return the default menuitem for the language + * + * @param string $language Language for the default + * + * @return object Menuitem + * @since 3.4 + */ + public function getDefault($language = '*') + { + if ($language == '*') + { + return $this->items[47]; + } + + if ($language == 'en-GB') + { + return $this->items[51]; + } + } +} \ No newline at end of file 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 bffb7762f2af2..cb0e56ea398ba 100644 --- a/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php +++ b/tests/unit/suites/libraries/cms/component/router/stubs/JComponentRouterViewInspector.php @@ -57,7 +57,27 @@ public function set($key, $value) public function getCategorySegment($id, $query) { $category = JCategories::getInstance($this->getName())->get($id); - return array_reverse($category->getPath()); + + if ($category) + { + return array_reverse($category->getPath()); + } + + return array(); + } + + /** + * Get content items of the type categories + * + * @param int $id ID of the category to load + * + * @return array Categories path identified by $id + * + * @since 3.4 + */ + public function getCategoriesSegment($id, $query) + { + return $this->getCategorySegment($id, $query); } /** diff --git a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php index a17e741d88d84..09cef8b0297b2 100644 --- a/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php +++ b/tests/unit/suites/libraries/cms/router/JRouterSiteTest.php @@ -18,7 +18,7 @@ * @group Router * @since 3.0 */ -class JRouterSiteTest extends TestCase +class JRouterSiteTest extends TestCaseDatabase { /** * Backup of the $_SERVER variable @@ -28,6 +28,22 @@ class JRouterSiteTest extends TestCase */ private $server; + /** + * Gets the data set to be loaded into the database during setup + * + * @return PHPUnit_Extensions_Database_DataSet_CsvDataSet + * + * @since 3.2 + */ + protected function getDataSet() + { + $dataSet = new PHPUnit_Extensions_Database_DataSet_CsvDataSet(',', "'", '\\'); + + $dataSet->addTable('jos_extensions', JPATH_TEST_DATABASE . '/jos_extensions.csv'); + + return $dataSet; + } + /** * Sets up the fixture, for example, opens a network connection. * This method is called before a test is executed. @@ -1325,9 +1341,9 @@ public function testGetComponentRouter() /** * Check if a proper router is automatically loaded - * by loading the router of com_content + * by loading the router of com_search */ - $this->assertInstanceOf('ContentRouter', $object->getComponentRouter('com_content')); + $this->assertInstanceOf('SearchRouter', $object->getComponentRouter('com_search')); /** * Check if an instance of JComponentRouterLegacy