/libraries/src/Extension/LegacyComponent.php

https://github.com/joomla/joomla-cms · PHP · 276 lines · 127 code · 39 blank · 110 comment · 18 complexity · 0f5ccded729ca1c66260ce59bf63e876 MD5 · raw file

  1. <?php
  2. /**
  3. * Joomla! Content Management System
  4. *
  5. * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org>
  6. * @license GNU General Public License version 2 or later; see LICENSE.txt
  7. */
  8. namespace Joomla\CMS\Extension;
  9. use Joomla\CMS\Application\CMSApplicationInterface;
  10. use Joomla\CMS\Categories\CategoryInterface;
  11. use Joomla\CMS\Categories\CategoryServiceInterface;
  12. use Joomla\CMS\Categories\CategoryServiceTrait;
  13. use Joomla\CMS\Categories\SectionNotFoundException;
  14. use Joomla\CMS\Component\Router\RouterInterface;
  15. use Joomla\CMS\Component\Router\RouterLegacy;
  16. use Joomla\CMS\Component\Router\RouterServiceInterface;
  17. use Joomla\CMS\Dispatcher\DispatcherInterface;
  18. use Joomla\CMS\Dispatcher\LegacyComponentDispatcher;
  19. use Joomla\CMS\Fields\FieldsServiceInterface;
  20. use Joomla\CMS\Filesystem\Path;
  21. use Joomla\CMS\Menu\AbstractMenu;
  22. use Joomla\CMS\MVC\Factory\LegacyFactory;
  23. use Joomla\CMS\MVC\Factory\MVCFactoryInterface;
  24. use Joomla\CMS\MVC\Factory\MVCFactoryServiceInterface;
  25. use Joomla\CMS\Tag\TagServiceInterface;
  26. use Joomla\CMS\Tag\TagServiceTrait;
  27. /**
  28. * Access to component specific services.
  29. *
  30. * @since 4.0.0
  31. */
  32. class LegacyComponent implements
  33. ComponentInterface,
  34. MVCFactoryServiceInterface,
  35. CategoryServiceInterface,
  36. FieldsServiceInterface,
  37. RouterServiceInterface,
  38. TagServiceInterface
  39. {
  40. use CategoryServiceTrait, TagServiceTrait {
  41. CategoryServiceTrait::getTableNameForSection insteadof TagServiceTrait;
  42. CategoryServiceTrait::getStateColumnForSection insteadof TagServiceTrait;
  43. }
  44. /**
  45. * @var string
  46. *
  47. * @since 4.0.0
  48. */
  49. private $component;
  50. /**
  51. * LegacyComponentContainer constructor.
  52. *
  53. * @param string $component The component
  54. *
  55. * @since 4.0.0
  56. */
  57. public function __construct(string $component)
  58. {
  59. $this->component = str_replace('com_', '', $component);
  60. }
  61. /**
  62. * Returns the dispatcher for the given application.
  63. *
  64. * @param CMSApplicationInterface $application The application
  65. *
  66. * @return DispatcherInterface
  67. *
  68. * @since 4.0.0
  69. */
  70. public function getDispatcher(CMSApplicationInterface $application): DispatcherInterface
  71. {
  72. return new LegacyComponentDispatcher($application);
  73. }
  74. /**
  75. * Get the factory.
  76. *
  77. * @return MVCFactoryInterface
  78. *
  79. * @since 4.0.0
  80. * @throws \UnexpectedValueException May be thrown if the factory has not been set.
  81. */
  82. public function getMVCFactory(): MVCFactoryInterface
  83. {
  84. return new LegacyFactory();
  85. }
  86. /**
  87. * Returns the category service.
  88. *
  89. * @param array $options The options
  90. * @param string $section The section
  91. *
  92. * @return CategoryInterface
  93. *
  94. * @since 4.0.0
  95. * @throws SectionNotFoundException
  96. */
  97. public function getCategory(array $options = [], $section = ''): CategoryInterface
  98. {
  99. $classname = ucfirst($this->component) . ucfirst($section) . 'Categories';
  100. if (!class_exists($classname)) {
  101. $path = JPATH_SITE . '/components/com_' . $this->component . '/helpers/category.php';
  102. if (!is_file($path)) {
  103. throw new SectionNotFoundException();
  104. }
  105. include_once $path;
  106. }
  107. if (!class_exists($classname)) {
  108. throw new SectionNotFoundException();
  109. }
  110. return new $classname($options);
  111. }
  112. /**
  113. * Adds Count Items for Category Manager.
  114. *
  115. * @param \stdClass[] $items The category objects
  116. * @param string $section The section
  117. *
  118. * @return void
  119. *
  120. * @since 4.0.0
  121. * @throws \Exception
  122. */
  123. public function countItems(array $items, string $section)
  124. {
  125. $helper = $this->loadHelper();
  126. if (!$helper || !\is_callable(array($helper, 'countItems'))) {
  127. return;
  128. }
  129. $helper::countItems($items, $section);
  130. }
  131. /**
  132. * Adds Count Items for Tag Manager.
  133. *
  134. * @param \stdClass[] $items The content objects
  135. * @param string $extension The name of the active view.
  136. *
  137. * @return void
  138. *
  139. * @since 4.0.0
  140. * @throws \Exception
  141. */
  142. public function countTagItems(array $items, string $extension)
  143. {
  144. $helper = $this->loadHelper();
  145. if (!$helper || !\is_callable(array($helper, 'countTagItems'))) {
  146. return;
  147. }
  148. $helper::countTagItems($items, $extension);
  149. }
  150. /**
  151. * Returns a valid section for articles. If it is not valid then null
  152. * is returned.
  153. *
  154. * @param string $section The section to get the mapping for
  155. * @param object $item The item
  156. *
  157. * @return string|null The new section
  158. *
  159. * @since 4.0.0
  160. */
  161. public function validateSection($section, $item = null)
  162. {
  163. $helper = $this->loadHelper();
  164. if (!$helper || !\is_callable(array($helper, 'validateSection'))) {
  165. return $section;
  166. }
  167. return $helper::validateSection($section, $item);
  168. }
  169. /**
  170. * Returns valid contexts.
  171. *
  172. * @return array
  173. *
  174. * @since 4.0.0
  175. */
  176. public function getContexts(): array
  177. {
  178. $helper = $this->loadHelper();
  179. if (!$helper || !\is_callable(array($helper, 'getContexts'))) {
  180. return [];
  181. }
  182. return $helper::getContexts();
  183. }
  184. /**
  185. * Returns the router.
  186. *
  187. * @param CMSApplicationInterface $application The application object
  188. * @param AbstractMenu $menu The menu object to work with
  189. *
  190. * @return RouterInterface
  191. *
  192. * @since 4.0.0
  193. */
  194. public function createRouter(CMSApplicationInterface $application, AbstractMenu $menu): RouterInterface
  195. {
  196. $compname = ucfirst($this->component);
  197. $class = $compname . 'Router';
  198. if (!class_exists($class)) {
  199. // Use the component routing handler if it exists
  200. $path = JPATH_SITE . '/components/com_' . $this->component . '/router.php';
  201. // Use the custom routing handler if it exists
  202. if (is_file($path)) {
  203. require_once $path;
  204. }
  205. }
  206. if (class_exists($class)) {
  207. $reflection = new \ReflectionClass($class);
  208. if (\in_array('Joomla\\CMS\\Component\\Router\\RouterInterface', $reflection->getInterfaceNames())) {
  209. return new $class($application, $menu);
  210. }
  211. }
  212. return new RouterLegacy($compname);
  213. }
  214. /**
  215. * Returns the classname of the legacy helper class. If none is found it returns false.
  216. *
  217. * @return boolean|string
  218. *
  219. * @since 4.0.0
  220. */
  221. private function loadHelper()
  222. {
  223. $className = ucfirst($this->component) . 'Helper';
  224. if (class_exists($className)) {
  225. return $className;
  226. }
  227. $file = Path::clean(JPATH_ADMINISTRATOR . '/components/com_' . $this->component . '/helpers/' . $this->component . '.php');
  228. if (!is_file($file)) {
  229. return false;
  230. }
  231. \JLoader::register($className, $file);
  232. if (!class_exists($className)) {
  233. return false;
  234. }
  235. return $className;
  236. }
  237. }