/components/com_contact/src/Service/Router.php

https://github.com/Hackwar/joomla-cms · PHP · 299 lines · 153 code · 33 blank · 113 comment · 13 complexity · 9fed8b1d8a68101e2420c963ed086947 MD5 · raw file

  1. <?php
  2. /**
  3. * @package Joomla.Site
  4. * @subpackage com_contact
  5. *
  6. * @copyright (C) 2007 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\Contact\Site\Service;
  10. \defined('_JEXEC') or die;
  11. use Joomla\CMS\Application\SiteApplication;
  12. use Joomla\CMS\Categories\CategoryFactoryInterface;
  13. use Joomla\CMS\Categories\CategoryInterface;
  14. use Joomla\CMS\Component\ComponentHelper;
  15. use Joomla\CMS\Component\Router\RouterView;
  16. use Joomla\CMS\Component\Router\RouterViewConfiguration;
  17. use Joomla\CMS\Component\Router\Rules\MenuRules;
  18. use Joomla\CMS\Component\Router\Rules\NomenuRules;
  19. use Joomla\CMS\Component\Router\Rules\StandardRules;
  20. use Joomla\CMS\Menu\AbstractMenu;
  21. use Joomla\Database\DatabaseInterface;
  22. use Joomla\Database\ParameterType;
  23. /**
  24. * Routing class from com_contact
  25. *
  26. * @since 3.3
  27. */
  28. class Router extends RouterView
  29. {
  30. /**
  31. * Flag to remove IDs
  32. *
  33. * @var boolean
  34. */
  35. protected $noIDs = false;
  36. /**
  37. * The category factory
  38. *
  39. * @var CategoryFactoryInterface
  40. *
  41. * @since 4.0.0
  42. */
  43. private $categoryFactory;
  44. /**
  45. * The category cache
  46. *
  47. * @var array
  48. *
  49. * @since 4.0.0
  50. */
  51. private $categoryCache = [];
  52. /**
  53. * The db
  54. *
  55. * @var DatabaseInterface
  56. *
  57. * @since 4.0.0
  58. */
  59. private $db;
  60. /**
  61. * Content Component router constructor
  62. *
  63. * @param SiteApplication $app The application object
  64. * @param AbstractMenu $menu The menu object to work with
  65. * @param CategoryFactoryInterface $categoryFactory The category object
  66. * @param DatabaseInterface $db The database object
  67. */
  68. public function __construct(SiteApplication $app, AbstractMenu $menu, CategoryFactoryInterface $categoryFactory, DatabaseInterface $db)
  69. {
  70. $this->categoryFactory = $categoryFactory;
  71. $this->db = $db;
  72. $params = ComponentHelper::getParams('com_contact');
  73. $this->noIDs = (bool) $params->get('sef_ids');
  74. $categories = new RouterViewConfiguration('categories');
  75. $categories->setKey('id');
  76. $this->registerView($categories);
  77. $category = new RouterViewConfiguration('category');
  78. $category->setKey('id')->setParent($categories, 'catid')->setNestable();
  79. $this->registerView($category);
  80. $contact = new RouterViewConfiguration('contact');
  81. $contact->setKey('id')->setParent($category, 'catid');
  82. $this->registerView($contact);
  83. $this->registerView(new RouterViewConfiguration('featured'));
  84. $form = new RouterViewConfiguration('form');
  85. $form->setKey('id');
  86. $this->registerView($form);
  87. parent::__construct($app, $menu);
  88. $this->attachRule(new MenuRules($this));
  89. $this->attachRule(new StandardRules($this));
  90. $this->attachRule(new NomenuRules($this));
  91. }
  92. /**
  93. * Method to get the segment(s) for a category
  94. *
  95. * @param string $id ID of the category to retrieve the segments for
  96. * @param array $query The request that is built right now
  97. *
  98. * @return array|string The segments of this item
  99. */
  100. public function getCategorySegment($id, $query)
  101. {
  102. $category = $this->getCategories()->get($id);
  103. if ($category)
  104. {
  105. $path = array_reverse($category->getPath(), true);
  106. $path[0] = '1:root';
  107. if ($this->noIDs)
  108. {
  109. foreach ($path as &$segment)
  110. {
  111. list($id, $segment) = explode(':', $segment, 2);
  112. }
  113. }
  114. return $path;
  115. }
  116. return array();
  117. }
  118. /**
  119. * Method to get the segment(s) for a category
  120. *
  121. * @param string $id ID of the category to retrieve the segments for
  122. * @param array $query The request that is built right now
  123. *
  124. * @return array|string The segments of this item
  125. */
  126. public function getCategoriesSegment($id, $query)
  127. {
  128. return $this->getCategorySegment($id, $query);
  129. }
  130. /**
  131. * Method to get the segment(s) for a contact
  132. *
  133. * @param string $id ID of the contact to retrieve the segments for
  134. * @param array $query The request that is built right now
  135. *
  136. * @return array|string The segments of this item
  137. */
  138. public function getContactSegment($id, $query)
  139. {
  140. if (!strpos($id, ':'))
  141. {
  142. $id = (int) $id;
  143. $dbquery = $this->db->getQuery(true);
  144. $dbquery->select($this->db->quoteName('alias'))
  145. ->from($this->db->quoteName('#__contact_details'))
  146. ->where($this->db->quoteName('id') . ' = :id')
  147. ->bind(':id', $id, ParameterType::INTEGER);
  148. $this->db->setQuery($dbquery);
  149. $id .= ':' . $this->db->loadResult();
  150. }
  151. if ($this->noIDs)
  152. {
  153. list($void, $segment) = explode(':', $id, 2);
  154. return array($void => $segment);
  155. }
  156. return array((int) $id => $id);
  157. }
  158. /**
  159. * Method to get the segment(s) for a form
  160. *
  161. * @param string $id ID of the contact form to retrieve the segments for
  162. * @param array $query The request that is built right now
  163. *
  164. * @return array|string The segments of this item
  165. *
  166. * @since 4.0.0
  167. */
  168. public function getFormSegment($id, $query)
  169. {
  170. return $this->getContactSegment($id, $query);
  171. }
  172. /**
  173. * Method to get the id for a category
  174. *
  175. * @param string $segment Segment to retrieve the ID for
  176. * @param array $query The request that is parsed right now
  177. *
  178. * @return mixed The id of this item or false
  179. */
  180. public function getCategoryId($segment, $query)
  181. {
  182. if (isset($query['id']))
  183. {
  184. $category = $this->getCategories(['access' => false])->get($query['id']);
  185. if ($category)
  186. {
  187. foreach ($category->getChildren() as $child)
  188. {
  189. if ($this->noIDs)
  190. {
  191. if ($child->alias == $segment)
  192. {
  193. return $child->id;
  194. }
  195. }
  196. else
  197. {
  198. if ($child->id == (int) $segment)
  199. {
  200. return $child->id;
  201. }
  202. }
  203. }
  204. }
  205. }
  206. return false;
  207. }
  208. /**
  209. * Method to get the segment(s) for a category
  210. *
  211. * @param string $segment Segment to retrieve the ID for
  212. * @param array $query The request that is parsed right now
  213. *
  214. * @return mixed The id of this item or false
  215. */
  216. public function getCategoriesId($segment, $query)
  217. {
  218. return $this->getCategoryId($segment, $query);
  219. }
  220. /**
  221. * Method to get the segment(s) for a contact
  222. *
  223. * @param string $segment Segment of the contact to retrieve the ID for
  224. * @param array $query The request that is parsed right now
  225. *
  226. * @return mixed The id of this item or false
  227. */
  228. public function getContactId($segment, $query)
  229. {
  230. if ($this->noIDs)
  231. {
  232. $dbquery = $this->db->getQuery(true);
  233. $dbquery->select($this->db->quoteName('id'))
  234. ->from($this->db->quoteName('#__contact_details'))
  235. ->where(
  236. [
  237. $this->db->quoteName('alias') . ' = :alias',
  238. $this->db->quoteName('catid') . ' = :catid',
  239. ]
  240. )
  241. ->bind(':alias', $segment)
  242. ->bind(':catid', $query['id'], ParameterType::INTEGER);
  243. $this->db->setQuery($dbquery);
  244. return (int) $this->db->loadResult();
  245. }
  246. return (int) $segment;
  247. }
  248. /**
  249. * Method to get categories from cache
  250. *
  251. * @param array $options The options for retrieving categories
  252. *
  253. * @return CategoryInterface The object containing categories
  254. *
  255. * @since 4.0.0
  256. */
  257. private function getCategories(array $options = []): CategoryInterface
  258. {
  259. $key = serialize($options);
  260. if (!isset($this->categoryCache[$key]))
  261. {
  262. $this->categoryCache[$key] = $this->categoryFactory->createCategory($options);
  263. }
  264. return $this->categoryCache[$key];
  265. }
  266. }