From 5e73d6bce750405bc21d74e429d885846c53d969 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Tue, 13 Feb 2018 12:56:31 +0100 Subject: [PATCH 01/22] Move component categories helper to services --- .../com_content/services/services.php | 24 ++++++ .../com_fields/Model/FieldModel.php | 2 +- components/com_content/helpers/category.php | 33 ------- libraries/src/Categories/Categories.php | 86 +++++++++++-------- .../src/Component/ComponentContainer.php | 50 +++++++++++ .../Component/ComponentContainerInterface.php | 33 +++++++ libraries/src/Component/ComponentHelper.php | 47 ++++++++++ .../Component/LegacyComponentContainer.php | 69 +++++++++++++++ .../Component/Service/Provider/Categories.php | 62 +++++++++++++ libraries/src/MVC/Model/BaseDatabaseModel.php | 16 ++++ 10 files changed, 350 insertions(+), 72 deletions(-) create mode 100644 administrator/components/com_content/services/services.php delete mode 100644 components/com_content/helpers/category.php create mode 100644 libraries/src/Component/ComponentContainer.php create mode 100644 libraries/src/Component/ComponentContainerInterface.php create mode 100644 libraries/src/Component/LegacyComponentContainer.php create mode 100644 libraries/src/Component/Service/Provider/Categories.php diff --git a/administrator/components/com_content/services/services.php b/administrator/components/com_content/services/services.php new file mode 100644 index 0000000000000..6639211e37e3c --- /dev/null +++ b/administrator/components/com_content/services/services.php @@ -0,0 +1,24 @@ +share( + 'ContentContainer', + function (\Joomla\DI\Container $parent) + { + $container = new \Joomla\CMS\Component\ComponentContainer($parent); + $container->registerServiceProvider( + new \Joomla\CMS\Component\Service\Provider\Categories(['table' => '#__content', 'extension' => 'com_content']) + ); + + return $container; + }, + true +); diff --git a/administrator/components/com_fields/Model/FieldModel.php b/administrator/components/com_fields/Model/FieldModel.php index 903eb005becfb..57681c10e2276 100644 --- a/administrator/components/com_fields/Model/FieldModel.php +++ b/administrator/components/com_fields/Model/FieldModel.php @@ -967,7 +967,7 @@ protected function preprocessForm(\JForm $form, $data, $group = 'content') } // Setting the context for the category field - $cat = \JCategories::getInstance(str_replace('com_', '', $component)); + $cat = $this->bootComponent($component)->getCategories(); if ($cat && $cat->get('root')->hasChildren()) { diff --git a/components/com_content/helpers/category.php b/components/com_content/helpers/category.php deleted file mode 100644 index 24983bf982031..0000000000000 --- a/components/com_content/helpers/category.php +++ /dev/null @@ -1,33 +0,0 @@ -_extension = $options['extension']; - $this->_table = $options['table']; - $this->_field = isset($options['field']) && $options['field'] ? $options['field'] : 'catid'; - $this->_key = isset($options['key']) && $options['key'] ? $options['key'] : 'id'; - $this->_statefield = $options['statefield'] ?? 'state'; - - $options['access'] = $options['access'] ?? 'true'; - $options['published'] = $options['published'] ?? 1; - $options['countItems'] = $options['countItems'] ?? 0; - $options['currentlang'] = Multilanguage::isEnabled() ? Factory::getLanguage()->getTag() : 0; - - $this->_options = $options; - - return true; + $this->setOptions($options); } /** @@ -125,7 +113,8 @@ public function __construct($options) * * @return Categories|boolean Categories object on success, boolean false if an object does not exist * - * @since 1.6 + * @since 1.6 + * @deprecated 5.0 Use the ComponentContainerInterface to get the categories */ public static function getInstance($extension, $options = array()) { @@ -136,33 +125,17 @@ public static function getInstance($extension, $options = array()) return self::$instances[$hash]; } - $parts = explode('.', $extension); - $component = 'com_' . strtolower($parts[0]); - $section = count($parts) > 1 ? $parts[1] : ''; - $classname = ucfirst(substr($component, 4)) . ucfirst($section) . 'Categories'; - - if (!class_exists($classname)) - { - $path = JPATH_SITE . '/components/' . $component . '/helpers/category.php'; - - if (!is_file($path)) - { - return false; - } + $parts = explode('.', $extension, 2); - include_once $path; - } + $categories = ComponentHelper::boot($parts[0])->getCategories(count($parts) > 1 ? $parts[1] : ''); - // Check for a possible service from the container otherwise manually instantiate the class - if (\JFactory::getContainer()->exists($classname)) - { - self::$instances[$hash] = \JFactory::getContainer()->get($classname); - } - else + if ($categories) { - self::$instances[$hash] = new $classname($options); + $categories->setOptions($options); } + self::$instances[$hash] = $categories; + return self::$instances[$hash]; } @@ -389,4 +362,41 @@ protected function _load($id) $this->_nodes[$id] = null; } } + + /** + * Sets the options for this service. The given options do overwrite the + * internal options with the same index. The existing options are not cleared + * when they are not specified in the given options array. + * + * @param array $options The new options + * + * @since __DEPLOY_VERSION__ + */ + public function setOptions(array $options) + { + if ($this->_options == $options) + { + return; + } + + // Merge the options to not loose the base config + $options = array_merge($this->_options, $options); + + $this->_extension = $options['extension']; + $this->_table = $options['table']; + $this->_field = isset($options['field']) && $options['field'] ? $options['field'] : 'catid'; + $this->_key = isset($options['key']) && $options['key'] ? $options['key'] : 'id'; + $this->_statefield = $options['statefield'] ?? 'state'; + + $options['access'] = $options['access'] ?? 'true'; + $options['published'] = $options['published'] ?? 1; + $options['countItems'] = $options['countItems'] ?? 0; + $options['currentlang'] = Multilanguage::isEnabled() ? Factory::getLanguage()->getTag() : 0; + + $this->_options = $options; + + // Reset the cache + $this->_nodes = []; + $this->_checkedCategories = []; + } } diff --git a/libraries/src/Component/ComponentContainer.php b/libraries/src/Component/ComponentContainer.php new file mode 100644 index 0000000000000..60674c4a1141c --- /dev/null +++ b/libraries/src/Component/ComponentContainer.php @@ -0,0 +1,50 @@ +has($serviceName)) + { + return null; + } + + return $this->get($serviceName); + } +} diff --git a/libraries/src/Component/ComponentContainerInterface.php b/libraries/src/Component/ComponentContainerInterface.php new file mode 100644 index 0000000000000..58a253355261f --- /dev/null +++ b/libraries/src/Component/ComponentContainerInterface.php @@ -0,0 +1,33 @@ +getNamespaceName(), $from + 11, $to)); } + + /** + * Boots the component with the given name. + * + * @param string $component The component name, eg. com_content. + * @param ContainerInterface $container The container. + * + * @return ComponentContainerInterface The service container + * + * @since __DEPLOY_VERSION__ + */ + public static function boot($component, ContainerInterface $container = null): ComponentContainerInterface + { + // Normalize the component name + $component = strtolower(str_replace('com_', '', $component)); + + // The service name + $serviceName = ucfirst($component) . 'Container'; + + // The container which holds the component container + $container = $container ? : Factory::getContainer(); + + // Check if the service is already available + if ($container->has($serviceName)) + { + return $container->get($serviceName); + } + + // Allow components to register services + $path = JPATH_ADMINISTRATOR . '/components/com_' . $component . '/services/services.php'; + + if (file_exists($path)) + { + // Load the services file + require_once $path; + } + + if (!$container->has($serviceName)) + { + $container->set($serviceName, new LegacyComponentContainer($component)); + } + + // Return the child container + return $container->get($serviceName); + } } diff --git a/libraries/src/Component/LegacyComponentContainer.php b/libraries/src/Component/LegacyComponentContainer.php new file mode 100644 index 0000000000000..389b18429ad59 --- /dev/null +++ b/libraries/src/Component/LegacyComponentContainer.php @@ -0,0 +1,69 @@ +component = $component; + } + + /** + * Returns the category service. If the service is not available + * null is returned. + * + * @param string $section The section + * + * @return Categories|null + * + * @since __DEPLOY_VERSION__ + */ + public function getCategories($section = ''): Categories + { + $classname = ucfirst(substr($this->component, 4)) . ucfirst($section) . 'Categories'; + + if (!class_exists($classname)) + { + $path = JPATH_SITE . '/components/' . $this->component . '/helpers/category.php'; + + if (!is_file($path)) + { + return null; + } + + include_once $path; + } + + return new $classname([]); + } +} diff --git a/libraries/src/Component/Service/Provider/Categories.php b/libraries/src/Component/Service/Provider/Categories.php new file mode 100644 index 0000000000000..9dfc27dd4dfaf --- /dev/null +++ b/libraries/src/Component/Service/Provider/Categories.php @@ -0,0 +1,62 @@ +options = $options; + } + + /** + * Registers the service provider with a DI container. + * + * @param Container $container The DI container. + * + * @return void + * + * @since __DEPLOY_VERSION__ + */ + public function register(Container $container) + { + $container->share( + 'categories', + function (Container $container) + { + return new \Joomla\CMS\Categories\Categories($this->options); + }, + true + ); + } +} diff --git a/libraries/src/MVC/Model/BaseDatabaseModel.php b/libraries/src/MVC/Model/BaseDatabaseModel.php index 7a228251fb9b4..d7a1086bd73f5 100644 --- a/libraries/src/MVC/Model/BaseDatabaseModel.php +++ b/libraries/src/MVC/Model/BaseDatabaseModel.php @@ -10,6 +10,7 @@ defined('JPATH_PLATFORM') or die; +use Joomla\CMS\Component\ComponentContainerInterface; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\MVC\Factory\LegacyFactory; use Joomla\CMS\MVC\Factory\MVCFactory; @@ -657,4 +658,19 @@ protected function cleanCache($group = null, $client_id = 0) // Trigger the onContentCleanCache event. \JFactory::getApplication()->triggerEvent($this->event_clean_cache, $options); } + + /** + * Boots the component with the given name. + * + * @param string $component The component name, eg. com_content. + * + * @return ComponentContainerInterface The service container + * + * @since __DEPLOY_VERSION__ + */ + protected function bootComponent($component): ComponentContainerInterface + { + // @Todo move the static call to an interface + return ComponentHelper::boot($component); + } } From 7d7bc87a196d5d77736d39295bc489db7d4b0009 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Tue, 13 Feb 2018 14:47:12 +0100 Subject: [PATCH 02/22] CS --- libraries/src/Categories/Categories.php | 4 +++- libraries/src/Component/ComponentContainer.php | 4 ++-- libraries/src/Component/ComponentContainerInterface.php | 2 +- libraries/src/Component/LegacyComponentContainer.php | 4 ++-- libraries/src/Component/Service/Provider/Categories.php | 4 ++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/libraries/src/Categories/Categories.php b/libraries/src/Categories/Categories.php index 3d896a6e3cfb8..6c1d3d1dc1154 100644 --- a/libraries/src/Categories/Categories.php +++ b/libraries/src/Categories/Categories.php @@ -368,7 +368,9 @@ protected function _load($id) * internal options with the same index. The existing options are not cleared * when they are not specified in the given options array. * - * @param array $options The new options + * @param array $options The new options + * + * @return void * * @since __DEPLOY_VERSION__ */ diff --git a/libraries/src/Component/ComponentContainer.php b/libraries/src/Component/ComponentContainer.php index 60674c4a1141c..02baf20158e5d 100644 --- a/libraries/src/Component/ComponentContainer.php +++ b/libraries/src/Component/ComponentContainer.php @@ -25,7 +25,7 @@ class ComponentContainer extends Container implements ComponentContainerInterfac * Returns the category service. If the service is not available * null is returned. * - * @param string $section The section + * @param string $section The section * * @return Categories|null * @@ -37,7 +37,7 @@ public function getCategories($section = ''): Categories if ($section) { - $serviceName .= '.' .strtolower($section); + $serviceName .= '.' . strtolower($section); } if (!$this->has($serviceName)) diff --git a/libraries/src/Component/ComponentContainerInterface.php b/libraries/src/Component/ComponentContainerInterface.php index 58a253355261f..e4dde40d5bba0 100644 --- a/libraries/src/Component/ComponentContainerInterface.php +++ b/libraries/src/Component/ComponentContainerInterface.php @@ -23,7 +23,7 @@ interface ComponentContainerInterface * Returns the category service. If the service is not available * null is returned. * - * @param string $section The section + * @param string $section The section * * @return Categories|null * diff --git a/libraries/src/Component/LegacyComponentContainer.php b/libraries/src/Component/LegacyComponentContainer.php index 389b18429ad59..213949a825edd 100644 --- a/libraries/src/Component/LegacyComponentContainer.php +++ b/libraries/src/Component/LegacyComponentContainer.php @@ -29,7 +29,7 @@ class LegacyComponentContainer implements ComponentContainerInterface /** * LegacyComponentContainer constructor. * - * @param string $component + * @param string $component The component * * @since __DEPLOY_VERSION__ */ @@ -42,7 +42,7 @@ public function __construct(string $component) * Returns the category service. If the service is not available * null is returned. * - * @param string $section The section + * @param string $section The section * * @return Categories|null * diff --git a/libraries/src/Component/Service/Provider/Categories.php b/libraries/src/Component/Service/Provider/Categories.php index 9dfc27dd4dfaf..9c06d28caaf46 100644 --- a/libraries/src/Component/Service/Provider/Categories.php +++ b/libraries/src/Component/Service/Provider/Categories.php @@ -16,7 +16,7 @@ /** * Service provider for the components's categories dependency * - * @since __DEPLOY_VERSION__ + * @since __DEPLOY_VERSION__ */ class Categories implements ServiceProviderInterface { @@ -30,7 +30,7 @@ class Categories implements ServiceProviderInterface /** * Categories constructor. * - * @param array $options The options for the categories + * @param array $options The options for the categories * * @since __DEPLOY_VERSION__ */ From fdcf139036a0cbe16ec31be554cae2ee6572af00 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Tue, 13 Feb 2018 15:16:25 +0100 Subject: [PATCH 03/22] Fix unit tests --- libraries/src/Categories/Categories.php | 8 ++++---- libraries/src/Component/ComponentContainer.php | 2 +- .../src/Component/ComponentContainerInterface.php | 2 +- .../src/Component/LegacyComponentContainer.php | 13 +++++++++---- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/libraries/src/Categories/Categories.php b/libraries/src/Categories/Categories.php index 6c1d3d1dc1154..b54a0a39c1e14 100644 --- a/libraries/src/Categories/Categories.php +++ b/libraries/src/Categories/Categories.php @@ -376,7 +376,7 @@ protected function _load($id) */ public function setOptions(array $options) { - if ($this->_options == $options) + if ($this->_options && $this->_options == $options) { return; } @@ -390,9 +390,9 @@ public function setOptions(array $options) $this->_key = isset($options['key']) && $options['key'] ? $options['key'] : 'id'; $this->_statefield = $options['statefield'] ?? 'state'; - $options['access'] = $options['access'] ?? 'true'; - $options['published'] = $options['published'] ?? 1; - $options['countItems'] = $options['countItems'] ?? 0; + $options['access'] = isset($options['access']) ? $options['access'] : 'true'; + $options['published'] = isset($options['published']) ? $options['published'] : 1; + $options['countItems'] = isset($options['countItems']) ? $options['countItems'] : 0; $options['currentlang'] = Multilanguage::isEnabled() ? Factory::getLanguage()->getTag() : 0; $this->_options = $options; diff --git a/libraries/src/Component/ComponentContainer.php b/libraries/src/Component/ComponentContainer.php index 02baf20158e5d..92ed73cd8df92 100644 --- a/libraries/src/Component/ComponentContainer.php +++ b/libraries/src/Component/ComponentContainer.php @@ -31,7 +31,7 @@ class ComponentContainer extends Container implements ComponentContainerInterfac * * @since __DEPLOY_VERSION__ */ - public function getCategories($section = ''): Categories + public function getCategories($section = '') { $serviceName = 'categories'; diff --git a/libraries/src/Component/ComponentContainerInterface.php b/libraries/src/Component/ComponentContainerInterface.php index e4dde40d5bba0..96d219ef6dbe9 100644 --- a/libraries/src/Component/ComponentContainerInterface.php +++ b/libraries/src/Component/ComponentContainerInterface.php @@ -29,5 +29,5 @@ interface ComponentContainerInterface * * @since __DEPLOY_VERSION__ */ - public function getCategories($section = ''): Categories; + public function getCategories($section = ''); } diff --git a/libraries/src/Component/LegacyComponentContainer.php b/libraries/src/Component/LegacyComponentContainer.php index 213949a825edd..8d6bafc98867e 100644 --- a/libraries/src/Component/LegacyComponentContainer.php +++ b/libraries/src/Component/LegacyComponentContainer.php @@ -35,7 +35,7 @@ class LegacyComponentContainer implements ComponentContainerInterface */ public function __construct(string $component) { - $this->component = $component; + $this->component = str_replace('com_', '', $component); } /** @@ -48,13 +48,13 @@ public function __construct(string $component) * * @since __DEPLOY_VERSION__ */ - public function getCategories($section = ''): Categories + public function getCategories($section = '') { - $classname = ucfirst(substr($this->component, 4)) . ucfirst($section) . 'Categories'; + $classname = ucfirst($this->component) . ucfirst($section) . 'Categories'; if (!class_exists($classname)) { - $path = JPATH_SITE . '/components/' . $this->component . '/helpers/category.php'; + $path = JPATH_SITE . '/components/com_' . $this->component . '/helpers/category.php'; if (!is_file($path)) { @@ -64,6 +64,11 @@ public function getCategories($section = ''): Categories include_once $path; } + if (!class_exists($classname)) + { + return null; + } + return new $classname([]); } } From 1a119fdc1ba254cd7dec56802cc431d768451b46 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Tue, 13 Feb 2018 16:21:25 +0100 Subject: [PATCH 04/22] Use a class for the categories service instead of a service provider --- .../com_content/services/services.php | 4 +- components/com_content/Service/Category.php | 36 +++++++++++ .../Component/Service/Provider/Categories.php | 62 ------------------- 3 files changed, 37 insertions(+), 65 deletions(-) create mode 100644 components/com_content/Service/Category.php delete mode 100644 libraries/src/Component/Service/Provider/Categories.php diff --git a/administrator/components/com_content/services/services.php b/administrator/components/com_content/services/services.php index 6639211e37e3c..d954a06a56891 100644 --- a/administrator/components/com_content/services/services.php +++ b/administrator/components/com_content/services/services.php @@ -14,9 +14,7 @@ function (\Joomla\DI\Container $parent) { $container = new \Joomla\CMS\Component\ComponentContainer($parent); - $container->registerServiceProvider( - new \Joomla\CMS\Component\Service\Provider\Categories(['table' => '#__content', 'extension' => 'com_content']) - ); + $container->set('categories', new \Joomla\Component\Content\Site\Service\Category); return $container; }, diff --git a/components/com_content/Service/Category.php b/components/com_content/Service/Category.php new file mode 100644 index 0000000000000..6e1374761af33 --- /dev/null +++ b/components/com_content/Service/Category.php @@ -0,0 +1,36 @@ +options = $options; - } - - /** - * Registers the service provider with a DI container. - * - * @param Container $container The DI container. - * - * @return void - * - * @since __DEPLOY_VERSION__ - */ - public function register(Container $container) - { - $container->share( - 'categories', - function (Container $container) - { - return new \Joomla\CMS\Categories\Categories($this->options); - }, - true - ); - } -} From 166c511f44f0cdb6e3a7d77c9b70a64a475e11a0 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Tue, 13 Feb 2018 17:01:09 +0100 Subject: [PATCH 05/22] Make the sniffs happy --- libraries/src/Component/LegacyComponentContainer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Component/LegacyComponentContainer.php b/libraries/src/Component/LegacyComponentContainer.php index 8d6bafc98867e..a5525f9b28e15 100644 --- a/libraries/src/Component/LegacyComponentContainer.php +++ b/libraries/src/Component/LegacyComponentContainer.php @@ -69,6 +69,6 @@ public function getCategories($section = '') return null; } - return new $classname([]); + return new $classname(array()); } } From 44c11408ae03f58b519f95d3a0e79fade5645e87 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 14 Feb 2018 07:53:01 +0100 Subject: [PATCH 06/22] Move boot the extension helper --- libraries/src/Component/ComponentHelper.php | 45 --------- .../ComponentContainer.php | 0 .../ComponentContainerInterface.php | 2 +- .../Extension/ExtensionContainerInterface.php | 22 +++++ libraries/src/Extension/ExtensionLoader.php | 91 +++++++++++++++++++ .../LegacyComponentContainer.php | 0 6 files changed, 114 insertions(+), 46 deletions(-) rename libraries/src/{Component => Extension}/ComponentContainer.php (100%) rename libraries/src/{Component => Extension}/ComponentContainerInterface.php (90%) create mode 100644 libraries/src/Extension/ExtensionContainerInterface.php create mode 100644 libraries/src/Extension/ExtensionLoader.php rename libraries/src/{Component => Extension}/LegacyComponentContainer.php (100%) diff --git a/libraries/src/Component/ComponentHelper.php b/libraries/src/Component/ComponentHelper.php index 260812a94ad18..0f21f7fdb1c72 100644 --- a/libraries/src/Component/ComponentHelper.php +++ b/libraries/src/Component/ComponentHelper.php @@ -554,49 +554,4 @@ public static function getComponentName($object, string $alternativeName): strin return 'com_' . strtolower(substr($reflect->getNamespaceName(), $from + 11, $to)); } - - /** - * Boots the component with the given name. - * - * @param string $component The component name, eg. com_content. - * @param ContainerInterface $container The container. - * - * @return ComponentContainerInterface The service container - * - * @since __DEPLOY_VERSION__ - */ - public static function boot($component, ContainerInterface $container = null): ComponentContainerInterface - { - // Normalize the component name - $component = strtolower(str_replace('com_', '', $component)); - - // The service name - $serviceName = ucfirst($component) . 'Container'; - - // The container which holds the component container - $container = $container ? : Factory::getContainer(); - - // Check if the service is already available - if ($container->has($serviceName)) - { - return $container->get($serviceName); - } - - // Allow components to register services - $path = JPATH_ADMINISTRATOR . '/components/com_' . $component . '/services/services.php'; - - if (file_exists($path)) - { - // Load the services file - require_once $path; - } - - if (!$container->has($serviceName)) - { - $container->set($serviceName, new LegacyComponentContainer($component)); - } - - // Return the child container - return $container->get($serviceName); - } } diff --git a/libraries/src/Component/ComponentContainer.php b/libraries/src/Extension/ComponentContainer.php similarity index 100% rename from libraries/src/Component/ComponentContainer.php rename to libraries/src/Extension/ComponentContainer.php diff --git a/libraries/src/Component/ComponentContainerInterface.php b/libraries/src/Extension/ComponentContainerInterface.php similarity index 90% rename from libraries/src/Component/ComponentContainerInterface.php rename to libraries/src/Extension/ComponentContainerInterface.php index 96d219ef6dbe9..f82757e7a774b 100644 --- a/libraries/src/Component/ComponentContainerInterface.php +++ b/libraries/src/Extension/ComponentContainerInterface.php @@ -17,7 +17,7 @@ * * @since __DEPLOY_VERSION__ */ -interface ComponentContainerInterface +interface ComponentContainerInterface extends ExtensionContainerInterface { /** * Returns the category service. If the service is not available diff --git a/libraries/src/Extension/ExtensionContainerInterface.php b/libraries/src/Extension/ExtensionContainerInterface.php new file mode 100644 index 0000000000000..ed260a809292a --- /dev/null +++ b/libraries/src/Extension/ExtensionContainerInterface.php @@ -0,0 +1,22 @@ +loadExtensionContainer(ucfirst($component) . 'ComponentContainer', 'com_' . $component, $path); + } + + /** + * Loads the extension container for the given extension. + * + * @param string $serviceName The service name + * @param string $extensionName The extension name + * @param string $extensionPath The path of the extension + * + * @return ExtensionContainerInterface The service container + * + * @since __DEPLOY_VERSION__ + */ + private function loadExtensionContainer($serviceName, $extensionName, $extensionPath): ExtensionContainerInterface + { + // The container which holds the component container + $container = $this->getContainer(); + + // Check if the service is already available + if ($container->has($serviceName)) + { + return $container->get($serviceName); + } + + $path = $extensionPath . '/services/services.php'; + + if (file_exists($path)) + { + // Load the services file + require_once $path; + } + + // Fallback to legacy + if (!$container->has($serviceName)) + { + $legacyContainer = null; + + if (strpos($extensionName, 'com_') === 0) + { + $legacyContainer = new LegacyComponentContainer($extensionName); + } + + $container->set($serviceName, $legacyContainer); + } + + // Return the child container + return $container->get($serviceName); + } +} diff --git a/libraries/src/Component/LegacyComponentContainer.php b/libraries/src/Extension/LegacyComponentContainer.php similarity index 100% rename from libraries/src/Component/LegacyComponentContainer.php rename to libraries/src/Extension/LegacyComponentContainer.php From db25ff43d4f471d917c656dad91b6a30f9250db6 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 14 Feb 2018 08:13:05 +0100 Subject: [PATCH 07/22] Introduce extension loader interface --- .../com_content/services/services.php | 4 +-- libraries/src/Application/CMSApplication.php | 3 +- .../Application/CMSApplicationInterface.php | 3 +- libraries/src/Application/CliApplication.php | 4 +-- .../src/Application/ConsoleApplication.php | 4 +-- libraries/src/Categories/Categories.php | 2 +- libraries/src/Component/ComponentHelper.php | 2 -- .../src/Extension/ComponentContainer.php | 2 +- .../Extension/ComponentContainerInterface.php | 2 +- .../Extension/ExtensionContainerInterface.php | 4 +-- libraries/src/Extension/ExtensionLoader.php | 1 - .../Extension/ExtensionLoaderInterface.php | 30 +++++++++++++++++++ .../Extension/LegacyComponentContainer.php | 2 +- libraries/src/MVC/Model/BaseDatabaseModel.php | 6 ++-- 14 files changed, 48 insertions(+), 21 deletions(-) create mode 100644 libraries/src/Extension/ExtensionLoaderInterface.php diff --git a/administrator/components/com_content/services/services.php b/administrator/components/com_content/services/services.php index d954a06a56891..980432dce43e5 100644 --- a/administrator/components/com_content/services/services.php +++ b/administrator/components/com_content/services/services.php @@ -10,10 +10,10 @@ defined('_JEXEC') or die; $container->share( - 'ContentContainer', + 'ContentComponentContainer', function (\Joomla\DI\Container $parent) { - $container = new \Joomla\CMS\Component\ComponentContainer($parent); + $container = new \Joomla\CMS\Extension\ComponentContainer($parent); $container->set('categories', new \Joomla\Component\Content\Site\Service\Category); return $container; diff --git a/libraries/src/Application/CMSApplication.php b/libraries/src/Application/CMSApplication.php index 608e1f5958a91..af76428ac2ca3 100644 --- a/libraries/src/Application/CMSApplication.php +++ b/libraries/src/Application/CMSApplication.php @@ -14,6 +14,7 @@ use Joomla\CMS\Authentication\Authentication; use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Event\BeforeExecuteEvent; +use Joomla\CMS\Extension\ExtensionLoader; use Joomla\CMS\Input\Input; use Joomla\CMS\Language\Language; use Joomla\CMS\Menu\AbstractMenu; @@ -35,7 +36,7 @@ */ abstract class CMSApplication extends WebApplication implements ContainerAwareInterface, CMSApplicationInterface { - use ContainerAwareTrait, ExtensionNamespaceMapper; + use ExtensionLoader, ExtensionNamespaceMapper; /** * Array of options for the \JDocument object diff --git a/libraries/src/Application/CMSApplicationInterface.php b/libraries/src/Application/CMSApplicationInterface.php index 486e756a0a647..05836e88a69da 100644 --- a/libraries/src/Application/CMSApplicationInterface.php +++ b/libraries/src/Application/CMSApplicationInterface.php @@ -8,6 +8,7 @@ namespace Joomla\CMS\Application; +use Joomla\CMS\Extension\ExtensionLoaderInterface; use Joomla\CMS\User\User; use Joomla\Session\SessionInterface; @@ -16,7 +17,7 @@ * * @since 4.0.0 */ -interface CMSApplicationInterface +interface CMSApplicationInterface extends ExtensionLoaderInterface { /** * Constant defining an enqueued emergency message diff --git a/libraries/src/Application/CliApplication.php b/libraries/src/Application/CliApplication.php index 1a0be334170c3..ba4937afa95ff 100644 --- a/libraries/src/Application/CliApplication.php +++ b/libraries/src/Application/CliApplication.php @@ -14,10 +14,10 @@ use Joomla\CMS\Application\CLI\CliInput; use Joomla\CMS\Application\CLI\CliOutput; use Joomla\CMS\Application\CLI\Output\Stdout; +use Joomla\CMS\Extension\ExtensionLoader; use Joomla\Input\Cli; use Joomla\Input\Input; use Joomla\DI\Container; -use Joomla\DI\ContainerAwareTrait; use Joomla\Event\DispatcherAwareInterface; use Joomla\Event\DispatcherAwareTrait; use Joomla\Event\DispatcherInterface; @@ -32,7 +32,7 @@ */ abstract class CliApplication extends AbstractApplication implements DispatcherAwareInterface, CMSApplicationInterface { - use DispatcherAwareTrait, EventAware, IdentityAware, ContainerAwareTrait; + use DispatcherAwareTrait, EventAware, IdentityAware, ExtensionLoader; /** * Output object diff --git a/libraries/src/Application/ConsoleApplication.php b/libraries/src/Application/ConsoleApplication.php index 5e446b1c16d4d..a84b63959c77a 100644 --- a/libraries/src/Application/ConsoleApplication.php +++ b/libraries/src/Application/ConsoleApplication.php @@ -11,11 +11,11 @@ defined('JPATH_PLATFORM') or die; use Joomla\CMS\Console; +use Joomla\CMS\Extension\ExtensionLoader; use Joomla\CMS\Input\Cli; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Console\Application; use Joomla\DI\Container; -use Joomla\DI\ContainerAwareTrait; use Joomla\Event\DispatcherAwareInterface; use Joomla\Event\DispatcherAwareTrait; use Joomla\Event\DispatcherInterface; @@ -30,7 +30,7 @@ */ class ConsoleApplication extends Application implements DispatcherAwareInterface, CMSApplicationInterface { - use DispatcherAwareTrait, EventAware, IdentityAware, ContainerAwareTrait; + use DispatcherAwareTrait, EventAware, IdentityAware, ExtensionLoader; /** * The application message queue. diff --git a/libraries/src/Categories/Categories.php b/libraries/src/Categories/Categories.php index b54a0a39c1e14..9abe9102c73bf 100644 --- a/libraries/src/Categories/Categories.php +++ b/libraries/src/Categories/Categories.php @@ -127,7 +127,7 @@ public static function getInstance($extension, $options = array()) $parts = explode('.', $extension, 2); - $categories = ComponentHelper::boot($parts[0])->getCategories(count($parts) > 1 ? $parts[1] : ''); + $categories = Factory::getApplication()->bootComponent($parts[0])->getCategories(count($parts) > 1 ? $parts[1] : ''); if ($categories) { diff --git a/libraries/src/Component/ComponentHelper.php b/libraries/src/Component/ComponentHelper.php index 0f21f7fdb1c72..c8ee948a13e3d 100644 --- a/libraries/src/Component/ComponentHelper.php +++ b/libraries/src/Component/ComponentHelper.php @@ -12,10 +12,8 @@ use Joomla\CMS\Access\Access; use Joomla\CMS\Component\Exception\MissingComponentException; -use Joomla\CMS\Factory; use Joomla\Registry\Registry; use Joomla\CMS\Dispatcher\DispatcherInterface; -use Psr\Container\ContainerInterface; /** * Component helper class diff --git a/libraries/src/Extension/ComponentContainer.php b/libraries/src/Extension/ComponentContainer.php index 92ed73cd8df92..525ea5cda2053 100644 --- a/libraries/src/Extension/ComponentContainer.php +++ b/libraries/src/Extension/ComponentContainer.php @@ -6,7 +6,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\CMS\Component; +namespace Joomla\CMS\Extension; defined('JPATH_PLATFORM') or die; diff --git a/libraries/src/Extension/ComponentContainerInterface.php b/libraries/src/Extension/ComponentContainerInterface.php index f82757e7a774b..156f8589795a4 100644 --- a/libraries/src/Extension/ComponentContainerInterface.php +++ b/libraries/src/Extension/ComponentContainerInterface.php @@ -6,7 +6,7 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\CMS\Component; +namespace Joomla\CMS\Extension; defined('JPATH_PLATFORM') or die; diff --git a/libraries/src/Extension/ExtensionContainerInterface.php b/libraries/src/Extension/ExtensionContainerInterface.php index ed260a809292a..039c53b60d5c3 100644 --- a/libraries/src/Extension/ExtensionContainerInterface.php +++ b/libraries/src/Extension/ExtensionContainerInterface.php @@ -6,12 +6,10 @@ * @license GNU General Public License version 2 or later; see LICENSE.txt */ -namespace Joomla\CMS\Component; +namespace Joomla\CMS\Extension; defined('JPATH_PLATFORM') or die; -use Joomla\CMS\Extension\Extension; - /** * Access to component specific services. * diff --git a/libraries/src/Extension/ExtensionLoader.php b/libraries/src/Extension/ExtensionLoader.php index 3908c5b91d8e7..9e82527b4ddba 100644 --- a/libraries/src/Extension/ExtensionLoader.php +++ b/libraries/src/Extension/ExtensionLoader.php @@ -10,7 +10,6 @@ defined('JPATH_PLATFORM') or die; -use Joomla\CMS\Component\ExtensionContainerInterface; use Joomla\DI\ContainerAwareTrait; /** diff --git a/libraries/src/Extension/ExtensionLoaderInterface.php b/libraries/src/Extension/ExtensionLoaderInterface.php new file mode 100644 index 0000000000000..87919169be8e0 --- /dev/null +++ b/libraries/src/Extension/ExtensionLoaderInterface.php @@ -0,0 +1,30 @@ +bootComponent($component); } } From 5f126d3a1b719ad2214dd0f76a6b790d4838407f Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 14 Feb 2018 08:18:49 +0100 Subject: [PATCH 08/22] Revert not needed interface --- libraries/src/Application/CMSApplication.php | 1 - .../Extension/ComponentContainerInterface.php | 2 +- .../Extension/ExtensionContainerInterface.php | 20 ------------------- libraries/src/Extension/ExtensionLoader.php | 4 ++-- 4 files changed, 3 insertions(+), 24 deletions(-) delete mode 100644 libraries/src/Extension/ExtensionContainerInterface.php diff --git a/libraries/src/Application/CMSApplication.php b/libraries/src/Application/CMSApplication.php index af76428ac2ca3..fd0183faffd0d 100644 --- a/libraries/src/Application/CMSApplication.php +++ b/libraries/src/Application/CMSApplication.php @@ -25,7 +25,6 @@ use Joomla\CMS\User\User; use Joomla\DI\Container; use Joomla\DI\ContainerAwareInterface; -use Joomla\DI\ContainerAwareTrait; use Joomla\Registry\Registry; use Joomla\Session\SessionEvent; diff --git a/libraries/src/Extension/ComponentContainerInterface.php b/libraries/src/Extension/ComponentContainerInterface.php index 156f8589795a4..2b594cf12d01a 100644 --- a/libraries/src/Extension/ComponentContainerInterface.php +++ b/libraries/src/Extension/ComponentContainerInterface.php @@ -17,7 +17,7 @@ * * @since __DEPLOY_VERSION__ */ -interface ComponentContainerInterface extends ExtensionContainerInterface +interface ComponentContainerInterface { /** * Returns the category service. If the service is not available diff --git a/libraries/src/Extension/ExtensionContainerInterface.php b/libraries/src/Extension/ExtensionContainerInterface.php deleted file mode 100644 index 039c53b60d5c3..0000000000000 --- a/libraries/src/Extension/ExtensionContainerInterface.php +++ /dev/null @@ -1,20 +0,0 @@ -getContainer(); From 27f89f2a9de6b6d4a4f5bfc873d5d72fa2b1b6ca Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 14 Feb 2018 08:45:02 +0100 Subject: [PATCH 09/22] CS --- libraries/src/Extension/ExtensionLoader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/src/Extension/ExtensionLoader.php b/libraries/src/Extension/ExtensionLoader.php index 7fd29d3b5694b..7c06c372ca48a 100644 --- a/libraries/src/Extension/ExtensionLoader.php +++ b/libraries/src/Extension/ExtensionLoader.php @@ -15,7 +15,7 @@ /** * Trait for classes which can load extensions * - * @since 4.0.0 + * @since __DEPLOY_VERSION__ */ trait ExtensionLoader { @@ -36,7 +36,7 @@ public function bootComponent($component): ComponentContainerInterface $component = strtolower(str_replace('com_', '', $component)); // Path to to look for services - $path = JPATH_ADMINISTRATOR . '/components/com_' . $component ; + $path = JPATH_ADMINISTRATOR . '/components/com_' . $component; return $this->loadExtensionContainer(ucfirst($component) . 'ComponentContainer', 'com_' . $component, $path); } From ff0000fe433f70f728baceaacc3e80cb2c5b7e41 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 14 Feb 2018 14:18:55 +0100 Subject: [PATCH 10/22] Language fixes --- libraries/src/Categories/Categories.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/src/Categories/Categories.php b/libraries/src/Categories/Categories.php index 9abe9102c73bf..94e51c9cdf446 100644 --- a/libraries/src/Categories/Categories.php +++ b/libraries/src/Categories/Categories.php @@ -364,7 +364,7 @@ protected function _load($id) } /** - * Sets the options for this service. The given options do overwrite the + * Sets the options for this service. The given options overwrite the * internal options with the same index. The existing options are not cleared * when they are not specified in the given options array. * @@ -381,7 +381,7 @@ public function setOptions(array $options) return; } - // Merge the options to not loose the base config + // Merge the options to not lose the base config $options = array_merge($this->_options, $options); $this->_extension = $options['extension']; From 80931ab525449021828f6a9f999ac3636814c488 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 14 Feb 2018 15:18:31 +0100 Subject: [PATCH 11/22] Make getConatiner abstract --- libraries/src/Application/CMSApplication.php | 3 ++- libraries/src/Application/CliApplication.php | 3 ++- libraries/src/Application/ConsoleApplication.php | 3 ++- libraries/src/Extension/ExtensionLoader.php | 13 ++++++++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/libraries/src/Application/CMSApplication.php b/libraries/src/Application/CMSApplication.php index fd0183faffd0d..ec11fb56029a3 100644 --- a/libraries/src/Application/CMSApplication.php +++ b/libraries/src/Application/CMSApplication.php @@ -25,6 +25,7 @@ use Joomla\CMS\User\User; use Joomla\DI\Container; use Joomla\DI\ContainerAwareInterface; +use Joomla\DI\ContainerAwareTrait; use Joomla\Registry\Registry; use Joomla\Session\SessionEvent; @@ -35,7 +36,7 @@ */ abstract class CMSApplication extends WebApplication implements ContainerAwareInterface, CMSApplicationInterface { - use ExtensionLoader, ExtensionNamespaceMapper; + use ContainerAwareTrait, ExtensionLoader, ExtensionNamespaceMapper; /** * Array of options for the \JDocument object diff --git a/libraries/src/Application/CliApplication.php b/libraries/src/Application/CliApplication.php index ba4937afa95ff..3efe701eab868 100644 --- a/libraries/src/Application/CliApplication.php +++ b/libraries/src/Application/CliApplication.php @@ -15,6 +15,7 @@ use Joomla\CMS\Application\CLI\CliOutput; use Joomla\CMS\Application\CLI\Output\Stdout; use Joomla\CMS\Extension\ExtensionLoader; +use Joomla\DI\ContainerAwareTrait; use Joomla\Input\Cli; use Joomla\Input\Input; use Joomla\DI\Container; @@ -32,7 +33,7 @@ */ abstract class CliApplication extends AbstractApplication implements DispatcherAwareInterface, CMSApplicationInterface { - use DispatcherAwareTrait, EventAware, IdentityAware, ExtensionLoader; + use DispatcherAwareTrait, EventAware, IdentityAware, ContainerAwareTrait, ExtensionLoader; /** * Output object diff --git a/libraries/src/Application/ConsoleApplication.php b/libraries/src/Application/ConsoleApplication.php index a84b63959c77a..4f3a4c236774c 100644 --- a/libraries/src/Application/ConsoleApplication.php +++ b/libraries/src/Application/ConsoleApplication.php @@ -16,6 +16,7 @@ use Joomla\CMS\Plugin\PluginHelper; use Joomla\Console\Application; use Joomla\DI\Container; +use Joomla\DI\ContainerAwareTrait; use Joomla\Event\DispatcherAwareInterface; use Joomla\Event\DispatcherAwareTrait; use Joomla\Event\DispatcherInterface; @@ -30,7 +31,7 @@ */ class ConsoleApplication extends Application implements DispatcherAwareInterface, CMSApplicationInterface { - use DispatcherAwareTrait, EventAware, IdentityAware, ExtensionLoader; + use DispatcherAwareTrait, EventAware, IdentityAware, ContainerAwareTrait, ExtensionLoader; /** * The application message queue. diff --git a/libraries/src/Extension/ExtensionLoader.php b/libraries/src/Extension/ExtensionLoader.php index 7c06c372ca48a..df55a331fc7bf 100644 --- a/libraries/src/Extension/ExtensionLoader.php +++ b/libraries/src/Extension/ExtensionLoader.php @@ -10,7 +10,9 @@ defined('JPATH_PLATFORM') or die; +use Joomla\DI\Container; use Joomla\DI\ContainerAwareTrait; +use Joomla\DI\Exception\ContainerNotFoundException; /** * Trait for classes which can load extensions @@ -19,7 +21,6 @@ */ trait ExtensionLoader { - use ContainerAwareTrait; /** * Boots the component with the given name. @@ -87,4 +88,14 @@ private function loadExtensionContainer($serviceName, $extensionName, $extension // Return the child container return $container->get($serviceName); } + + /** + * Get the DI container. + * + * @return Container + * + * @since __DEPLOY_VERSION__ + * @throws ContainerNotFoundException May be thrown if the container has not been set. + */ + abstract protected function getContainer(); } From 9eadbb912b2a6a7f2b7808bf0e0399f0ac69b66d Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Wed, 14 Feb 2018 15:20:51 +0100 Subject: [PATCH 12/22] CS --- libraries/src/Application/CliApplication.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Application/CliApplication.php b/libraries/src/Application/CliApplication.php index 3efe701eab868..4b8fa81b7ec20 100644 --- a/libraries/src/Application/CliApplication.php +++ b/libraries/src/Application/CliApplication.php @@ -15,10 +15,10 @@ use Joomla\CMS\Application\CLI\CliOutput; use Joomla\CMS\Application\CLI\Output\Stdout; use Joomla\CMS\Extension\ExtensionLoader; -use Joomla\DI\ContainerAwareTrait; use Joomla\Input\Cli; use Joomla\Input\Input; use Joomla\DI\Container; +use Joomla\DI\ContainerAwareTrait; use Joomla\Event\DispatcherAwareInterface; use Joomla\Event\DispatcherAwareTrait; use Joomla\Event\DispatcherInterface; From 09e457453daa133e9b302e3c676a8c94abddd041 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Thu, 15 Feb 2018 16:31:55 +0100 Subject: [PATCH 13/22] Distinguish between optional and required options --- libraries/src/Categories/Categories.php | 52 +++++++++---------- .../src/Extension/ComponentContainer.php | 10 +++- .../Extension/ComponentContainerInterface.php | 5 +- .../Extension/LegacyComponentContainer.php | 7 ++- 4 files changed, 43 insertions(+), 31 deletions(-) diff --git a/libraries/src/Categories/Categories.php b/libraries/src/Categories/Categories.php index 94e51c9cdf446..0e2a96e05936d 100644 --- a/libraries/src/Categories/Categories.php +++ b/libraries/src/Categories/Categories.php @@ -10,7 +10,6 @@ defined('JPATH_PLATFORM') or die; -use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\Language\Multilanguage; @@ -102,6 +101,19 @@ class Categories */ public function __construct($options) { + // Required options + $this->_extension = $options['extension']; + $this->_table = $options['table']; + $this->_field = isset($options['field']) && $options['field'] ? $options['field'] : 'catid'; + $this->_key = isset($options['key']) && $options['key'] ? $options['key'] : 'id'; + $this->_statefield = $options['statefield'] ?? 'state'; + + // Default some optional options + $this->_options['access'] = 'true'; + $this->_options['published'] = 1; + $this->_options['countItems'] = 0; + $this->_options['currentlang'] = Multilanguage::isEnabled() ? Factory::getLanguage()->getTag() : 0; + $this->setOptions($options); } @@ -127,12 +139,7 @@ public static function getInstance($extension, $options = array()) $parts = explode('.', $extension, 2); - $categories = Factory::getApplication()->bootComponent($parts[0])->getCategories(count($parts) > 1 ? $parts[1] : ''); - - if ($categories) - { - $categories->setOptions($options); - } + $categories = Factory::getApplication()->bootComponent($parts[0])->getCategories($options, count($parts) > 1 ? $parts[1] : ''); self::$instances[$hash] = $categories; @@ -364,9 +371,8 @@ protected function _load($id) } /** - * Sets the options for this service. The given options overwrite the - * internal options with the same index. The existing options are not cleared - * when they are not specified in the given options array. + * Allows to set some optional options, eg. if the access level should be considered. + * Also clears the internal children cache. * * @param array $options The new options * @@ -376,26 +382,20 @@ protected function _load($id) */ public function setOptions(array $options) { - if ($this->_options && $this->_options == $options) + if (isset($options['access'])) { - return; + $this->_options['access'] = $options['access']; } - // Merge the options to not lose the base config - $options = array_merge($this->_options, $options); - - $this->_extension = $options['extension']; - $this->_table = $options['table']; - $this->_field = isset($options['field']) && $options['field'] ? $options['field'] : 'catid'; - $this->_key = isset($options['key']) && $options['key'] ? $options['key'] : 'id'; - $this->_statefield = $options['statefield'] ?? 'state'; - - $options['access'] = isset($options['access']) ? $options['access'] : 'true'; - $options['published'] = isset($options['published']) ? $options['published'] : 1; - $options['countItems'] = isset($options['countItems']) ? $options['countItems'] : 0; - $options['currentlang'] = Multilanguage::isEnabled() ? Factory::getLanguage()->getTag() : 0; + if (isset($options['published'])) + { + $this->_options['published'] = $options['published']; + } - $this->_options = $options; + if (isset($options['countItems'])) + { + $this->_options['countItems'] = $options['countItems']; + } // Reset the cache $this->_nodes = []; diff --git a/libraries/src/Extension/ComponentContainer.php b/libraries/src/Extension/ComponentContainer.php index 525ea5cda2053..e74f2cf9c7026 100644 --- a/libraries/src/Extension/ComponentContainer.php +++ b/libraries/src/Extension/ComponentContainer.php @@ -26,12 +26,15 @@ class ComponentContainer extends Container implements ComponentContainerInterfac * null is returned. * * @param string $section The section + * @param array $options The options * * @return Categories|null * + * @see Categories::setOptions() + * * @since __DEPLOY_VERSION__ */ - public function getCategories($section = '') + public function getCategories(array $options = [], $section = '') { $serviceName = 'categories'; @@ -45,6 +48,9 @@ public function getCategories($section = '') return null; } - return $this->get($serviceName); + $categories = $this->get($serviceName); + $categories->setOptions($options); + + return $categories; } } diff --git a/libraries/src/Extension/ComponentContainerInterface.php b/libraries/src/Extension/ComponentContainerInterface.php index 2b594cf12d01a..e3d558f7fd782 100644 --- a/libraries/src/Extension/ComponentContainerInterface.php +++ b/libraries/src/Extension/ComponentContainerInterface.php @@ -24,10 +24,13 @@ interface ComponentContainerInterface * null is returned. * * @param string $section The section + * @param array $options The options * * @return Categories|null * + * @see Categories::setOptions() + * * @since __DEPLOY_VERSION__ */ - public function getCategories($section = ''); + public function getCategories(array $options = [], $section = ''); } diff --git a/libraries/src/Extension/LegacyComponentContainer.php b/libraries/src/Extension/LegacyComponentContainer.php index 9f2f9ddfb9b2b..967c6fc2a0787 100644 --- a/libraries/src/Extension/LegacyComponentContainer.php +++ b/libraries/src/Extension/LegacyComponentContainer.php @@ -43,12 +43,15 @@ public function __construct(string $component) * null is returned. * * @param string $section The section + * @param array $options The options * * @return Categories|null * + * @see Categories::setOptions() + * * @since __DEPLOY_VERSION__ */ - public function getCategories($section = '') + public function getCategories(array $options = [], $section = '') { $classname = ucfirst($this->component) . ucfirst($section) . 'Categories'; @@ -69,6 +72,6 @@ public function getCategories($section = '') return null; } - return new $classname(array()); + return new $classname($options); } } From ca128f75e91a525d66d8c716b9404a6e2dbafe35 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Thu, 15 Feb 2018 16:41:01 +0100 Subject: [PATCH 14/22] CS --- libraries/src/Extension/ComponentContainer.php | 2 +- libraries/src/Extension/ComponentContainerInterface.php | 2 +- libraries/src/Extension/LegacyComponentContainer.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/src/Extension/ComponentContainer.php b/libraries/src/Extension/ComponentContainer.php index e74f2cf9c7026..725c86de24386 100644 --- a/libraries/src/Extension/ComponentContainer.php +++ b/libraries/src/Extension/ComponentContainer.php @@ -25,8 +25,8 @@ class ComponentContainer extends Container implements ComponentContainerInterfac * Returns the category service. If the service is not available * null is returned. * - * @param string $section The section * @param array $options The options + * @param string $section The section * * @return Categories|null * diff --git a/libraries/src/Extension/ComponentContainerInterface.php b/libraries/src/Extension/ComponentContainerInterface.php index e3d558f7fd782..40f56285b096c 100644 --- a/libraries/src/Extension/ComponentContainerInterface.php +++ b/libraries/src/Extension/ComponentContainerInterface.php @@ -23,8 +23,8 @@ interface ComponentContainerInterface * Returns the category service. If the service is not available * null is returned. * - * @param string $section The section * @param array $options The options + * @param string $section The section * * @return Categories|null * diff --git a/libraries/src/Extension/LegacyComponentContainer.php b/libraries/src/Extension/LegacyComponentContainer.php index 967c6fc2a0787..2af54bdff5c01 100644 --- a/libraries/src/Extension/LegacyComponentContainer.php +++ b/libraries/src/Extension/LegacyComponentContainer.php @@ -42,8 +42,8 @@ public function __construct(string $component) * Returns the category service. If the service is not available * null is returned. * - * @param string $section The section * @param array $options The options + * @param string $section The section * * @return Categories|null * From 91c907d56f8b5d26521ef8e192e8f1d162ff52bd Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Fri, 16 Feb 2018 08:51:06 +0100 Subject: [PATCH 15/22] Run isolated --- libraries/src/Extension/ExtensionLoader.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/src/Extension/ExtensionLoader.php b/libraries/src/Extension/ExtensionLoader.php index df55a331fc7bf..1012cd5219a34 100644 --- a/libraries/src/Extension/ExtensionLoader.php +++ b/libraries/src/Extension/ExtensionLoader.php @@ -11,7 +11,6 @@ defined('JPATH_PLATFORM') or die; use Joomla\DI\Container; -use Joomla\DI\ContainerAwareTrait; use Joomla\DI\Exception\ContainerNotFoundException; /** @@ -68,8 +67,13 @@ private function loadExtensionContainer($serviceName, $extensionName, $extension if (file_exists($path)) { - // Load the services file - require_once $path; + // Run the services file in an isolated environment where only the container is available + $loader = static function() use($container, $path) + { + // Load the services file + require_once $path; + }; + $loader($container); } // Fallback to legacy From d5b6c8ae95c505c51f410be2a001bf482ed7891e Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Mon, 19 Feb 2018 15:45:21 +0100 Subject: [PATCH 16/22] Load the container trough a class --- .../com_content/services/provider.php | 38 ++++++ .../com_content/services/services.php | 22 ---- libraries/src/Application/CMSApplication.php | 4 +- .../Application/CMSApplicationInterface.php | 4 +- libraries/src/Application/CliApplication.php | 4 +- .../src/Application/ConsoleApplication.php | 4 +- .../{ComponentContainer.php => Component.php} | 34 ++++-- ...erInterface.php => ComponentInterface.php} | 2 +- libraries/src/Extension/ExtensionLoader.php | 105 ---------------- ...face.php => ExtensionManagerInterface.php} | 6 +- .../src/Extension/ExtensionManagerTrait.php | 113 ++++++++++++++++++ ...onentContainer.php => LegacyComponent.php} | 2 +- .../Extension/Service/Provider/Component.php | 46 +++++++ libraries/src/MVC/Model/BaseDatabaseModel.php | 6 +- 14 files changed, 235 insertions(+), 155 deletions(-) create mode 100644 administrator/components/com_content/services/provider.php delete mode 100644 administrator/components/com_content/services/services.php rename libraries/src/Extension/{ComponentContainer.php => Component.php} (61%) rename libraries/src/Extension/{ComponentContainerInterface.php => ComponentInterface.php} (95%) delete mode 100644 libraries/src/Extension/ExtensionLoader.php rename libraries/src/Extension/{ExtensionLoaderInterface.php => ExtensionManagerInterface.php} (77%) create mode 100644 libraries/src/Extension/ExtensionManagerTrait.php rename libraries/src/Extension/{LegacyComponentContainer.php => LegacyComponent.php} (95%) create mode 100644 libraries/src/Extension/Service/Provider/Component.php diff --git a/administrator/components/com_content/services/provider.php b/administrator/components/com_content/services/provider.php new file mode 100644 index 0000000000000..78c556a3b8685 --- /dev/null +++ b/administrator/components/com_content/services/provider.php @@ -0,0 +1,38 @@ +set('categories', ['' => new Category]); + $container->registerServiceProvider(new Component); + } +} diff --git a/administrator/components/com_content/services/services.php b/administrator/components/com_content/services/services.php deleted file mode 100644 index 980432dce43e5..0000000000000 --- a/administrator/components/com_content/services/services.php +++ /dev/null @@ -1,22 +0,0 @@ -share( - 'ContentComponentContainer', - function (\Joomla\DI\Container $parent) - { - $container = new \Joomla\CMS\Extension\ComponentContainer($parent); - $container->set('categories', new \Joomla\Component\Content\Site\Service\Category); - - return $container; - }, - true -); diff --git a/libraries/src/Application/CMSApplication.php b/libraries/src/Application/CMSApplication.php index ec11fb56029a3..cdef60ee94d32 100644 --- a/libraries/src/Application/CMSApplication.php +++ b/libraries/src/Application/CMSApplication.php @@ -14,7 +14,7 @@ use Joomla\CMS\Authentication\Authentication; use Joomla\CMS\Event\AbstractEvent; use Joomla\CMS\Event\BeforeExecuteEvent; -use Joomla\CMS\Extension\ExtensionLoader; +use Joomla\CMS\Extension\ExtensionManagerTrait; use Joomla\CMS\Input\Input; use Joomla\CMS\Language\Language; use Joomla\CMS\Menu\AbstractMenu; @@ -36,7 +36,7 @@ */ abstract class CMSApplication extends WebApplication implements ContainerAwareInterface, CMSApplicationInterface { - use ContainerAwareTrait, ExtensionLoader, ExtensionNamespaceMapper; + use ContainerAwareTrait, ExtensionManagerTrait, ExtensionNamespaceMapper; /** * Array of options for the \JDocument object diff --git a/libraries/src/Application/CMSApplicationInterface.php b/libraries/src/Application/CMSApplicationInterface.php index 05836e88a69da..3c3b6845b06d0 100644 --- a/libraries/src/Application/CMSApplicationInterface.php +++ b/libraries/src/Application/CMSApplicationInterface.php @@ -8,7 +8,7 @@ namespace Joomla\CMS\Application; -use Joomla\CMS\Extension\ExtensionLoaderInterface; +use Joomla\CMS\Extension\ExtensionManagerInterface; use Joomla\CMS\User\User; use Joomla\Session\SessionInterface; @@ -17,7 +17,7 @@ * * @since 4.0.0 */ -interface CMSApplicationInterface extends ExtensionLoaderInterface +interface CMSApplicationInterface extends ExtensionManagerInterface { /** * Constant defining an enqueued emergency message diff --git a/libraries/src/Application/CliApplication.php b/libraries/src/Application/CliApplication.php index 4b8fa81b7ec20..f928a52c8543e 100644 --- a/libraries/src/Application/CliApplication.php +++ b/libraries/src/Application/CliApplication.php @@ -14,7 +14,7 @@ use Joomla\CMS\Application\CLI\CliInput; use Joomla\CMS\Application\CLI\CliOutput; use Joomla\CMS\Application\CLI\Output\Stdout; -use Joomla\CMS\Extension\ExtensionLoader; +use Joomla\CMS\Extension\ExtensionManagerTrait; use Joomla\Input\Cli; use Joomla\Input\Input; use Joomla\DI\Container; @@ -33,7 +33,7 @@ */ abstract class CliApplication extends AbstractApplication implements DispatcherAwareInterface, CMSApplicationInterface { - use DispatcherAwareTrait, EventAware, IdentityAware, ContainerAwareTrait, ExtensionLoader; + use DispatcherAwareTrait, EventAware, IdentityAware, ContainerAwareTrait, ExtensionManagerTrait; /** * Output object diff --git a/libraries/src/Application/ConsoleApplication.php b/libraries/src/Application/ConsoleApplication.php index 4f3a4c236774c..62b7c8b0cd56e 100644 --- a/libraries/src/Application/ConsoleApplication.php +++ b/libraries/src/Application/ConsoleApplication.php @@ -11,7 +11,7 @@ defined('JPATH_PLATFORM') or die; use Joomla\CMS\Console; -use Joomla\CMS\Extension\ExtensionLoader; +use Joomla\CMS\Extension\ExtensionManagerTrait; use Joomla\CMS\Input\Cli; use Joomla\CMS\Plugin\PluginHelper; use Joomla\Console\Application; @@ -31,7 +31,7 @@ */ class ConsoleApplication extends Application implements DispatcherAwareInterface, CMSApplicationInterface { - use DispatcherAwareTrait, EventAware, IdentityAware, ContainerAwareTrait, ExtensionLoader; + use DispatcherAwareTrait, EventAware, IdentityAware, ContainerAwareTrait, ExtensionManagerTrait; /** * The application message queue. diff --git a/libraries/src/Extension/ComponentContainer.php b/libraries/src/Extension/Component.php similarity index 61% rename from libraries/src/Extension/ComponentContainer.php rename to libraries/src/Extension/Component.php index 725c86de24386..106380017a0d9 100644 --- a/libraries/src/Extension/ComponentContainer.php +++ b/libraries/src/Extension/Component.php @@ -11,16 +11,21 @@ defined('JPATH_PLATFORM') or die; use Joomla\CMS\Categories\Categories; -use Joomla\DI\Container; -use Psr\Container\ContainerInterface; /** * Access to component specific services. * * @since __DEPLOY_VERSION__ */ -class ComponentContainer extends Container implements ComponentContainerInterface +class Component implements ComponentInterface { + /** + * An array of categories. + * + * @var array + */ + private $categories; + /** * Returns the category service. If the service is not available * null is returned. @@ -36,21 +41,26 @@ class ComponentContainer extends Container implements ComponentContainerInterfac */ public function getCategories(array $options = [], $section = '') { - $serviceName = 'categories'; - - if ($section) - { - $serviceName .= '.' . strtolower($section); - } - - if (!$this->has($serviceName)) + if (!key_exists($section, $this->categories)) { return null; } - $categories = $this->get($serviceName); + $categories = clone $this->categories[$section]; $categories->setOptions($options); return $categories; } + + /** + * An array of categories where the key is the name of the section. + * If the component has no sections then the array must have at least + * an empty key. + * + * @param array $categories The categories + */ + public function setCategories(array $categories) + { + $this->categories = $categories; + } } diff --git a/libraries/src/Extension/ComponentContainerInterface.php b/libraries/src/Extension/ComponentInterface.php similarity index 95% rename from libraries/src/Extension/ComponentContainerInterface.php rename to libraries/src/Extension/ComponentInterface.php index 40f56285b096c..90876c24eccb2 100644 --- a/libraries/src/Extension/ComponentContainerInterface.php +++ b/libraries/src/Extension/ComponentInterface.php @@ -17,7 +17,7 @@ * * @since __DEPLOY_VERSION__ */ -interface ComponentContainerInterface +interface ComponentInterface { /** * Returns the category service. If the service is not available diff --git a/libraries/src/Extension/ExtensionLoader.php b/libraries/src/Extension/ExtensionLoader.php deleted file mode 100644 index 1012cd5219a34..0000000000000 --- a/libraries/src/Extension/ExtensionLoader.php +++ /dev/null @@ -1,105 +0,0 @@ -loadExtensionContainer(ucfirst($component) . 'ComponentContainer', 'com_' . $component, $path); - } - - /** - * Loads the extension container for the given extension. - * - * @param string $serviceName The service name - * @param string $extensionName The extension name - * @param string $extensionPath The path of the extension - * - * @return mixed The extension service container - * - * @since __DEPLOY_VERSION__ - */ - private function loadExtensionContainer($serviceName, $extensionName, $extensionPath) - { - // The container which holds the component container - $container = $this->getContainer(); - - // Check if the service is already available - if ($container->has($serviceName)) - { - return $container->get($serviceName); - } - - $path = $extensionPath . '/services/services.php'; - - if (file_exists($path)) - { - // Run the services file in an isolated environment where only the container is available - $loader = static function() use($container, $path) - { - // Load the services file - require_once $path; - }; - $loader($container); - } - - // Fallback to legacy - if (!$container->has($serviceName)) - { - $legacyContainer = null; - - if (strpos($extensionName, 'com_') === 0) - { - $legacyContainer = new LegacyComponentContainer($extensionName); - } - - $container->set($serviceName, $legacyContainer); - } - - // Return the child container - return $container->get($serviceName); - } - - /** - * Get the DI container. - * - * @return Container - * - * @since __DEPLOY_VERSION__ - * @throws ContainerNotFoundException May be thrown if the container has not been set. - */ - abstract protected function getContainer(); -} diff --git a/libraries/src/Extension/ExtensionLoaderInterface.php b/libraries/src/Extension/ExtensionManagerInterface.php similarity index 77% rename from libraries/src/Extension/ExtensionLoaderInterface.php rename to libraries/src/Extension/ExtensionManagerInterface.php index 87919169be8e0..a15ee474ca0f7 100644 --- a/libraries/src/Extension/ExtensionLoaderInterface.php +++ b/libraries/src/Extension/ExtensionManagerInterface.php @@ -15,16 +15,16 @@ * * @since __DEPLOY_VERSION__ */ -interface ExtensionLoaderInterface +interface ExtensionManagerInterface { /** * Boots the component with the given name. * * @param string $component The component to boot. * - * @return ComponentContainerInterface + * @return ComponentInterface * * @since __DEPLOY_VERSION__ */ - public function bootComponent($component): ComponentContainerInterface; + public function bootComponent($component): ComponentInterface; } diff --git a/libraries/src/Extension/ExtensionManagerTrait.php b/libraries/src/Extension/ExtensionManagerTrait.php new file mode 100644 index 0000000000000..43536121b36d1 --- /dev/null +++ b/libraries/src/Extension/ExtensionManagerTrait.php @@ -0,0 +1,113 @@ + []]; + + /** + * Boots the component with the given name. + * + * @param string $component The component to boot. + * + * @return ComponentInterface + * + * @since __DEPLOY_VERSION__ + */ + public function bootComponent($component): ComponentInterface + { + // Normalize the component name + $component = strtolower(str_replace('com_', '', $component)); + + // Path to to look for services + $path = JPATH_ADMINISTRATOR . '/components/com_' . $component; + + return $this->loadExtension('component', $component, $path); + } + + /** + * Loads the extension. + * + * @param string $type The extension type + * @param string $extensionName The extension name + * @param string $extensionPath The path of the extension + * + * @return mixed The extension + * + * @since __DEPLOY_VERSION__ + */ + private function loadExtension($type, $extensionName, $extensionPath) + { + // Check if the extension is already loaded + if (!empty($this->extensions[$type][$extensionName])) + { + return $this->extensions[$type][$extensionName]; + } + + // The container to get the services from + $container = new Container($this->getContainer()); + + // The class name to load + $className = ucfirst($extensionName) . ucfirst($type) . 'ServiceProvider'; + + // The path of the loader file + $path = $extensionPath . '/services/provider.php'; + + if (!class_exists($className) && file_exists($path)) + { + // Load the file + require_once $path; + } + + // Check if the extension supports the service provider interface + if (class_exists($className) && is_subclass_of($className, ServiceProviderInterface::class)) + { + $extensionLoader = new $className; + $extensionLoader->register($container); + } + + // Fallback to legacy + if (!$container->has($type) && $type == 'component') + { + $container->set($type, new LegacyComponent('com_' . $extensionName)); + } + + // Cache the extension + $this->extensions[$type][$extensionName] = $container->get($type); + + return $this->extensions[$type][$extensionName]; + } + + /** + * Get the DI container. + * + * @return Container + * + * @since __DEPLOY_VERSION__ + * @throws ContainerNotFoundException May be thrown if the container has not been set. + */ + abstract protected function getContainer(); +} diff --git a/libraries/src/Extension/LegacyComponentContainer.php b/libraries/src/Extension/LegacyComponent.php similarity index 95% rename from libraries/src/Extension/LegacyComponentContainer.php rename to libraries/src/Extension/LegacyComponent.php index 2af54bdff5c01..8c61e758b0bd1 100644 --- a/libraries/src/Extension/LegacyComponentContainer.php +++ b/libraries/src/Extension/LegacyComponent.php @@ -17,7 +17,7 @@ * * @since __DEPLOY_VERSION__ */ -class LegacyComponentContainer implements ComponentContainerInterface +class LegacyComponent implements ComponentInterface { /** * @var string diff --git a/libraries/src/Extension/Service/Provider/Component.php b/libraries/src/Extension/Service/Provider/Component.php new file mode 100644 index 0000000000000..cccf38b5f59c5 --- /dev/null +++ b/libraries/src/Extension/Service/Provider/Component.php @@ -0,0 +1,46 @@ +set( + 'component', + function (Container $container) + { + $component = new \Joomla\CMS\Extension\Component; + + $component->setCategories($container->get('categories')); + + return $component; + } + ); + } +} diff --git a/libraries/src/MVC/Model/BaseDatabaseModel.php b/libraries/src/MVC/Model/BaseDatabaseModel.php index 23c8192e23e20..4ff148a40cd92 100644 --- a/libraries/src/MVC/Model/BaseDatabaseModel.php +++ b/libraries/src/MVC/Model/BaseDatabaseModel.php @@ -10,7 +10,7 @@ defined('JPATH_PLATFORM') or die; -use Joomla\CMS\Extension\ComponentContainerInterface; +use Joomla\CMS\Extension\ComponentInterface; use Joomla\CMS\Component\ComponentHelper; use Joomla\CMS\Factory; use Joomla\CMS\MVC\Factory\LegacyFactory; @@ -665,11 +665,11 @@ protected function cleanCache($group = null, $client_id = 0) * * @param string $component The component name, eg. com_content. * - * @return ComponentContainerInterface The service container + * @return ComponentInterface The service container * * @since __DEPLOY_VERSION__ */ - protected function bootComponent($component): ComponentContainerInterface + protected function bootComponent($component): ComponentInterface { return Factory::getApplication()->bootComponent($component); } From 82a0e734dd41ba283ea26813a2ab96d4b89a8b52 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Mon, 19 Feb 2018 15:50:01 +0100 Subject: [PATCH 17/22] Load the container trough a class --- libraries/src/Extension/Component.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libraries/src/Extension/Component.php b/libraries/src/Extension/Component.php index 106380017a0d9..c6072a82af20a 100644 --- a/libraries/src/Extension/Component.php +++ b/libraries/src/Extension/Component.php @@ -23,6 +23,8 @@ class Component implements ComponentInterface * An array of categories. * * @var array + * + * @since __DEPLOY_VERSION__ */ private $categories; @@ -58,6 +60,10 @@ public function getCategories(array $options = [], $section = '') * an empty key. * * @param array $categories The categories + * + * @return void + * + * @since __DEPLOY_VERSION__ */ public function setCategories(array $categories) { From bf25d1cdc2d34071a5f53154139c697b241236ab Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Mon, 19 Feb 2018 15:52:31 +0100 Subject: [PATCH 18/22] Safe check --- libraries/src/Extension/Service/Provider/Component.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/src/Extension/Service/Provider/Component.php b/libraries/src/Extension/Service/Provider/Component.php index cccf38b5f59c5..dc62f7ab9cc77 100644 --- a/libraries/src/Extension/Service/Provider/Component.php +++ b/libraries/src/Extension/Service/Provider/Component.php @@ -37,7 +37,10 @@ function (Container $container) { $component = new \Joomla\CMS\Extension\Component; - $component->setCategories($container->get('categories')); + if ($container->has('categories')) + { + $component->setCategories($container->get('categories')); + } return $component; } From 16b7c71cff6e1905adf7253a82351a9681d426b5 Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Mon, 19 Feb 2018 16:21:10 +0100 Subject: [PATCH 19/22] versions --- libraries/src/Extension/Service/Provider/Component.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/src/Extension/Service/Provider/Component.php b/libraries/src/Extension/Service/Provider/Component.php index dc62f7ab9cc77..b3d3ed1ec8c59 100644 --- a/libraries/src/Extension/Service/Provider/Component.php +++ b/libraries/src/Extension/Service/Provider/Component.php @@ -16,7 +16,7 @@ /** * Service provider for the component's dispatcher dependency * - * @since 4.0 + * @since __DEPLOY_VERSION__ */ class Component implements ServiceProviderInterface { @@ -27,7 +27,7 @@ class Component implements ServiceProviderInterface * * @return void * - * @since 4.0 + * @since __DEPLOY_VERSION__ */ public function register(Container $container) { From 5a9912c8f265dff51805e82e7af74624a3373dfe Mon Sep 17 00:00:00 2001 From: Allon Moritz Date: Mon, 19 Feb 2018 16:22:30 +0100 Subject: [PATCH 20/22] doc --- libraries/src/Categories/Categories.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Categories/Categories.php b/libraries/src/Categories/Categories.php index 0e2a96e05936d..6eb493e40ec81 100644 --- a/libraries/src/Categories/Categories.php +++ b/libraries/src/Categories/Categories.php @@ -126,7 +126,7 @@ public function __construct($options) * @return Categories|boolean Categories object on success, boolean false if an object does not exist * * @since 1.6 - * @deprecated 5.0 Use the ComponentContainerInterface to get the categories + * @deprecated 5.0 Use the ComponentInterface to get the categories */ public static function getInstance($extension, $options = array()) { From a2447d30a4a5487c5dc225912bcdded2089abfcb Mon Sep 17 00:00:00 2001 From: George Wilson Date: Thu, 1 Mar 2018 21:17:30 +0000 Subject: [PATCH 21/22] Use ComponentInterface as a typehint for now --- libraries/src/Extension/ExtensionManagerTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Extension/ExtensionManagerTrait.php b/libraries/src/Extension/ExtensionManagerTrait.php index 43536121b36d1..41e9e96bc0c16 100644 --- a/libraries/src/Extension/ExtensionManagerTrait.php +++ b/libraries/src/Extension/ExtensionManagerTrait.php @@ -55,7 +55,7 @@ public function bootComponent($component): ComponentInterface * @param string $extensionName The extension name * @param string $extensionPath The path of the extension * - * @return mixed The extension + * @return ComponentInterface * * @since __DEPLOY_VERSION__ */ From 084e0a1db9cfd4ce8e5e5b72b57eda4ec810b064 Mon Sep 17 00:00:00 2001 From: George Wilson Date: Thu, 1 Mar 2018 21:19:21 +0000 Subject: [PATCH 22/22] Use main function --- libraries/src/Extension/Component.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/src/Extension/Component.php b/libraries/src/Extension/Component.php index c6072a82af20a..d8deda6f97c73 100644 --- a/libraries/src/Extension/Component.php +++ b/libraries/src/Extension/Component.php @@ -43,7 +43,7 @@ class Component implements ComponentInterface */ public function getCategories(array $options = [], $section = '') { - if (!key_exists($section, $this->categories)) + if (!array_key_exists($section, $this->categories)) { return null; }