/components/com_tags/src/Helper/RouteHelper.php

https://github.com/joomla/joomla-cms · PHP · 246 lines · 129 code · 33 blank · 84 comment · 29 complexity · 7d38533c81c58d57d170906e424eeac3 MD5 · raw file

  1. <?php
  2. /**
  3. * @package Joomla.Site
  4. * @subpackage com_tags
  5. *
  6. * @copyright (C) 2017 Open Source Matters, Inc. <https://www.joomla.org>
  7. * @license GNU General Public License version 2 or later; see LICENSE.txt
  8. */
  9. namespace Joomla\Component\Tags\Site\Helper;
  10. use Exception;
  11. use Joomla\CMS\Component\ComponentHelper;
  12. use Joomla\CMS\Helper\RouteHelper as CMSRouteHelper;
  13. use Joomla\CMS\Menu\AbstractMenu;
  14. /**
  15. * Tags Component Route Helper.
  16. *
  17. * @since 3.1
  18. */
  19. class RouteHelper extends CMSRouteHelper
  20. {
  21. /**
  22. * Lookup-table for menu items
  23. *
  24. * @var array
  25. */
  26. protected static $lookup;
  27. /**
  28. * Tries to load the router for the component and calls it. Otherwise uses getTagRoute.
  29. *
  30. * @param integer $contentItemId Component item id
  31. * @param string $contentItemAlias Component item alias
  32. * @param integer $contentCatId Component item category id
  33. * @param string $language Component item language
  34. * @param string $typeAlias Component type alias
  35. * @param string $routerName Component router
  36. *
  37. * @return string URL link to pass to the router
  38. *
  39. * @since 3.1
  40. */
  41. public static function getItemRoute($contentItemId, $contentItemAlias, $contentCatId, $language, $typeAlias, $routerName)
  42. {
  43. $link = '';
  44. $explodedAlias = explode('.', $typeAlias);
  45. $explodedRouter = explode('::', $routerName);
  46. if (file_exists($routerFile = JPATH_BASE . '/components/' . $explodedAlias[0] . '/helpers/route.php')) {
  47. \JLoader::register($explodedRouter[0], $routerFile);
  48. $routerClass = $explodedRouter[0];
  49. $routerMethod = $explodedRouter[1];
  50. if (class_exists($routerClass) && method_exists($routerClass, $routerMethod)) {
  51. if ($routerMethod === 'getCategoryRoute') {
  52. $link = $routerClass::$routerMethod($contentItemId, $language);
  53. } else {
  54. $link = $routerClass::$routerMethod($contentItemId . ':' . $contentItemAlias, $contentCatId, $language);
  55. }
  56. }
  57. }
  58. if ($link === '') {
  59. // Create a fallback link in case we can't find the component router
  60. $router = new CMSRouteHelper();
  61. $link = $router->getRoute($contentItemId, $typeAlias, $link, $language, $contentCatId);
  62. }
  63. return $link;
  64. }
  65. /**
  66. * Tries to load the router for the component and calls it. Otherwise calls getRoute.
  67. *
  68. * @param integer $id The ID of the tag
  69. *
  70. * @return string URL link to pass to the router
  71. *
  72. * @since 3.1
  73. * @throws Exception
  74. * @deprecated 5.0.0 Use getComponentTagRoute() instead
  75. */
  76. public static function getTagRoute($id)
  77. {
  78. @trigger_error('This function is replaced by the getComponentTagRoute()', E_USER_DEPRECATED);
  79. return self::getComponentTagRoute($id);
  80. }
  81. /**
  82. * Tries to load the router for the component and calls it. Otherwise calls getRoute.
  83. *
  84. * @param string $id The ID of the tag in the format TAG_ID:TAG_ALIAS
  85. * @param string $language The language of the tag
  86. *
  87. * @return string URL link to pass to the router
  88. *
  89. * @since 4.2.0
  90. * @throws Exception
  91. */
  92. public static function getComponentTagRoute(string $id, string $language = '*'): string
  93. {
  94. $needles = [
  95. 'tag' => [(int) $id],
  96. 'language' => $language,
  97. ];
  98. if ($id < 1) {
  99. $link = '';
  100. } else {
  101. $link = 'index.php?option=com_tags&view=tag&id=' . $id;
  102. if ($item = self::_findItem($needles)) {
  103. $link .= '&Itemid=' . $item;
  104. } else {
  105. $needles = [
  106. 'tags' => [1, 0],
  107. 'language' => $language,
  108. ];
  109. if ($item = self::_findItem($needles)) {
  110. $link .= '&Itemid=' . $item;
  111. }
  112. }
  113. }
  114. return $link;
  115. }
  116. /**
  117. * Tries to load the router for the tags view.
  118. *
  119. * @return string URL link to pass to the router
  120. *
  121. * @since 3.7
  122. * @throws Exception
  123. * @deprecated 5.0.0
  124. */
  125. public static function getTagsRoute()
  126. {
  127. @trigger_error('This function is replaced by the getComponentTagsRoute()', E_USER_DEPRECATED);
  128. return self::getComponentTagsRoute();
  129. }
  130. /**
  131. * Tries to load the router for the tags view.
  132. *
  133. * @param string $language The language of the tag
  134. *
  135. * @return string URL link to pass to the router
  136. *
  137. * @since 4.2.0
  138. * @throws Exception
  139. */
  140. public static function getComponentTagsRoute(string $language = '*'): string
  141. {
  142. $needles = [
  143. 'tags' => [0],
  144. 'language' => $language,
  145. ];
  146. $link = 'index.php?option=com_tags&view=tags';
  147. if ($item = self::_findItem($needles)) {
  148. $link .= '&Itemid=' . $item;
  149. }
  150. return $link;
  151. }
  152. /**
  153. * Find Item static function
  154. *
  155. * @param array $needles Array used to get the language value
  156. *
  157. * @return null
  158. *
  159. * @throws Exception
  160. */
  161. protected static function _findItem($needles = null)
  162. {
  163. $menus = AbstractMenu::getInstance('site');
  164. $language = $needles['language'] ?? '*';
  165. // Prepare the reverse lookup array.
  166. if (self::$lookup === null) {
  167. self::$lookup = array();
  168. $component = ComponentHelper::getComponent('com_tags');
  169. $items = $menus->getItems('component_id', $component->id);
  170. if ($items) {
  171. foreach ($items as $item) {
  172. if (isset($item->query, $item->query['view'])) {
  173. $lang = ($item->language != '' ? $item->language : '*');
  174. if (!isset(self::$lookup[$lang])) {
  175. self::$lookup[$lang] = array();
  176. }
  177. $view = $item->query['view'];
  178. if (!isset(self::$lookup[$lang][$view])) {
  179. self::$lookup[$lang][$view] = array();
  180. }
  181. // Only match menu items that list one tag
  182. if (isset($item->query['id']) && is_array($item->query['id'])) {
  183. foreach ($item->query['id'] as $position => $tagId) {
  184. if (!isset(self::$lookup[$lang][$view][$item->query['id'][$position]]) || count($item->query['id']) == 1) {
  185. self::$lookup[$lang][$view][$item->query['id'][$position]] = $item->id;
  186. }
  187. }
  188. } elseif ($view == 'tags') {
  189. self::$lookup[$lang]['tags'][] = $item->id;
  190. }
  191. }
  192. }
  193. }
  194. }
  195. if ($needles) {
  196. foreach ($needles as $view => $ids) {
  197. if (isset(self::$lookup[$language][$view])) {
  198. foreach ($ids as $id) {
  199. if (isset(self::$lookup[$language][$view][(int) $id])) {
  200. return self::$lookup[$language][$view][(int) $id];
  201. }
  202. }
  203. }
  204. }
  205. } else {
  206. $active = $menus->getActive();
  207. if ($active) {
  208. return $active->id;
  209. }
  210. }
  211. return null;
  212. }
  213. }