Использование своего класса MVC фабрики в компоненте Joomla 5
Давно назрела необходимость переопределить ->createModel()
в своём компоненте. И я хотел сделать это правильно, заменив класс MVC фабрики своим.
Давайте разберемся как создаётся экземпляр MVCFactory в компоненте
Откройте файл administrator/components/com_mycomponent/services/provider.php
одного из стандартных компонентов Joomla. В нём нас интересует строка:
$container->registerServiceProvider(new MVCFactory('\Joomla\Component\MyComponent'));
В этой строке создаётся объект класса сервис-провайдера Joomla\CMS\Extension\Service\Provider\MVCFactory
реализующего интерфейс Joomla\DI\ServiceProviderInterface
. В этом интерфейсе всего один метод register
.
Вот содержимое этого метода:
$container->set(
MVCFactoryInterface::class,
function (Container $container) {
if (\Joomla\CMS\Factory::getApplication()->isClient('api')) {
$factory = new ApiMVCFactory($this->namespace);
} else {
$factory = new \Joomla\CMS\MVC\Factory\MVCFactory($this->namespace);
}
// ...
return $factory;
}
);
Как видим, в контейнер Joomla\DI\Container
в метод set
передаются два параметра:
имя ресурса — string
имя интерфейса Joomla\CMS\MVC\Factory\MVCFactoryInterface::class
, который должна реализовывать MVC-фабрика;
функция — callable
функция, которая создаёт экземпляр класса MVC-фабрики, реализующего данный интерфейс.
Таким образом, для внедрения собственного класса MVC фабрики надо создать два новых класса (я не привожу код классов, так как вы можете просто наследовать их от стандартных.):
Собственно класс фабрики, реализующий интерфейс Joomla\CMS\MVC\Factory\MVCFactoryInterface
(можно наследовать от стандартного Joomla\CMS\MVC\Factory\MVCFactory
);
И класс сервис-провайдера реализующий интерфейс Joomla\DI\ServiceProviderInterface
(можно наследовать от стандартного Joomla\CMS\Extension\Service\Provider\MVCFactory
).
И в файле administrator/components/com_mycomponent/services/provider.php
в методе register
зарегистрировать свой сервис-провайдер вместо стандартного:
$container->registerServiceProvider(new MyMVCFactory('\\Joomla\\Component\\MyComponent'));
Теперь вы можете получить доступ к своей MVC фабрике следующим образом:
В контроллерах (MVC фабрику своего компонента):
$mvcFactory = $this->factory;
В классах использующих MVCFactoryAwareTrait
, например в моделях наследующих класс BaseDatabaseModel
(MVC фабрику своего компонента):
$mvcFactory = $this->getMVCFactory();
В любом месте можно получить MVC фаблику любого компонента:
$mvcFactory = Joomla\CMS\Factory::getApplication()
->bootComponent('my_component')
->getMVCFactory();