[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2018 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE 8 */ 9 10 namespace Joomla\CMS\Extension; 11 12 use Joomla\CMS\Dispatcher\ModuleDispatcherFactory; 13 use Joomla\CMS\Event\AbstractEvent; 14 use Joomla\CMS\Helper\HelperFactory; 15 use Joomla\CMS\Plugin\CMSPlugin; 16 use Joomla\CMS\Plugin\PluginHelper; 17 use Joomla\DI\Container; 18 use Joomla\DI\Exception\ContainerNotFoundException; 19 use Joomla\DI\ServiceProviderInterface; 20 use Joomla\Event\DispatcherInterface; 21 22 // phpcs:disable PSR1.Files.SideEffects 23 \defined('JPATH_PLATFORM') or die; 24 // phpcs:enable PSR1.Files.SideEffects 25 26 /** 27 * Trait for classes which can load extensions 28 * 29 * @since 4.0.0 30 */ 31 trait ExtensionManagerTrait 32 { 33 /** 34 * Boots the component with the given name. 35 * 36 * @param string $component The component to boot. 37 * 38 * @return ComponentInterface 39 * 40 * @since 4.0.0 41 */ 42 public function bootComponent($component): ComponentInterface 43 { 44 // Normalize the component name 45 $component = strtolower(str_replace('com_', '', $component)); 46 47 // Path to look for services 48 $path = JPATH_ADMINISTRATOR . '/components/com_' . $component; 49 50 return $this->loadExtension(ComponentInterface::class, $component, $path); 51 } 52 53 /** 54 * Boots the module with the given name. 55 * 56 * @param string $module The module to boot 57 * @param string $applicationName The application name 58 * 59 * @return ModuleInterface 60 * 61 * @since 4.0.0 62 */ 63 public function bootModule($module, $applicationName): ModuleInterface 64 { 65 // Normalize the module name 66 $module = strtolower(str_replace('mod_', '', $module)); 67 68 // Path to look for services 69 $path = JPATH_SITE . '/modules/mod_' . $module; 70 71 if ($applicationName === 'administrator') { 72 $path = JPATH_ADMINISTRATOR . '/modules/mod_' . $module; 73 } 74 75 return $this->loadExtension(ModuleInterface::class, $module, $path); 76 } 77 78 /** 79 * Boots the plugin with the given name and type. 80 * 81 * @param string $plugin The plugin name 82 * @param string $type The type of the plugin 83 * 84 * @return PluginInterface 85 * 86 * @since 4.0.0 87 */ 88 public function bootPlugin($plugin, $type): PluginInterface 89 { 90 // Normalize the plugin name 91 $plugin = strtolower(str_replace('plg_', '', $plugin)); 92 93 // Path to look for services 94 $path = JPATH_SITE . '/plugins/' . $type . '/' . $plugin; 95 96 return $this->loadExtension(PluginInterface::class, $plugin . ':' . $type, $path); 97 } 98 99 /** 100 * Loads the extension. 101 * 102 * @param string $type The extension type 103 * @param string $extensionName The extension name 104 * @param string $extensionPath The path of the extension 105 * 106 * @return ComponentInterface|ModuleInterface|PluginInterface 107 * 108 * @since 4.0.0 109 */ 110 private function loadExtension($type, $extensionName, $extensionPath) 111 { 112 // Check if the extension is already loaded 113 if (!empty(ExtensionHelper::$extensions[$type][$extensionName])) { 114 return ExtensionHelper::$extensions[$type][$extensionName]; 115 } 116 117 // The container to get the services from 118 $container = $this->getContainer()->createChild(); 119 120 $container->get(DispatcherInterface::class)->dispatch( 121 'onBeforeExtensionBoot', 122 AbstractEvent::create( 123 'onBeforeExtensionBoot', 124 [ 125 'subject' => $this, 126 'type' => $type, 127 'extensionName' => $extensionName, 128 'container' => $container 129 ] 130 ) 131 ); 132 133 // The path of the loader file 134 $path = $extensionPath . '/services/provider.php'; 135 136 if (is_file($path)) { 137 // Load the file 138 $provider = require_once $path; 139 140 // Check if the extension supports the service provider interface 141 if ($provider instanceof ServiceProviderInterface) { 142 $provider->register($container); 143 } 144 } 145 146 // Fallback to legacy 147 if (!$container->has($type)) { 148 switch ($type) { 149 case ComponentInterface::class: 150 $container->set($type, new LegacyComponent('com_' . $extensionName)); 151 break; 152 case ModuleInterface::class: 153 $container->set($type, new Module(new ModuleDispatcherFactory(''), new HelperFactory(''))); 154 break; 155 case PluginInterface::class: 156 list($pluginName, $pluginType) = explode(':', $extensionName); 157 $container->set($type, $this->loadPluginFromFilesystem($pluginName, $pluginType)); 158 } 159 } 160 161 $container->get(DispatcherInterface::class)->dispatch( 162 'onAfterExtensionBoot', 163 AbstractEvent::create( 164 'onAfterExtensionBoot', 165 [ 166 'subject' => $this, 167 'type' => $type, 168 'extensionName' => $extensionName, 169 'container' => $container 170 ] 171 ) 172 ); 173 174 $extension = $container->get($type); 175 176 if ($extension instanceof BootableExtensionInterface) { 177 $extension->boot($container); 178 } 179 180 // Cache the extension 181 ExtensionHelper::$extensions[$type][$extensionName] = $extension; 182 183 return $extension; 184 } 185 186 /** 187 * Creates a CMS plugin from the filesystem. 188 * 189 * @param string $plugin The plugin 190 * @param string $type The type 191 * 192 * @return CMSPlugin 193 * 194 * @since 4.0.0 195 */ 196 private function loadPluginFromFilesystem(string $plugin, string $type) 197 { 198 // The dispatcher 199 $dispatcher = $this->getContainer()->get(DispatcherInterface::class); 200 201 // Clear the names 202 $plugin = preg_replace('/[^A-Z0-9_\.-]/i', '', $plugin); 203 $type = preg_replace('/[^A-Z0-9_\.-]/i', '', $type); 204 205 // The path of the plugin 206 $path = JPATH_PLUGINS . '/' . $type . '/' . $plugin . '/' . $plugin . '.php'; 207 208 // Return an empty class when the file doesn't exist 209 if (!is_file($path)) { 210 return new DummyPlugin($dispatcher); 211 } 212 213 // Include the file of the plugin 214 require_once $path; 215 216 // Compile the classname 217 $className = 'Plg' . str_replace('-', '', $type) . $plugin; 218 219 if ($type === 'editors-xtd') { 220 // This type doesn't follow the convention 221 $className = 'PlgEditorsXtd' . $plugin; 222 223 if (!class_exists($className)) { 224 $className = 'PlgButton' . $plugin; 225 } 226 } 227 228 // Return an empty class when the class doesn't exist 229 if (!class_exists($className)) { 230 return new DummyPlugin($dispatcher); 231 } 232 233 // Instantiate the plugin 234 return new $className($dispatcher, (array) PluginHelper::getPlugin($type, $plugin)); 235 } 236 237 /** 238 * Get the DI container. 239 * 240 * @return Container 241 * 242 * @since 4.0.0 243 * @throws ContainerNotFoundException May be thrown if the container has not been set. 244 */ 245 abstract protected function getContainer(); 246 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |