[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/src/Extension/ -> ExtensionManagerTrait.php (source)

   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  }


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer