Использование своего класса 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();