docs
docs copied to clipboard
Symfony Container not available for Legacy Environment
The PrestaShop Module Services documentation mentions that we are able to obtain the Symfony Container from our modules. This isn't working for me when extending PaymentModule on 1.7.5.2.
public function getContent()
{
// Error: Attempted to call an undefined method named "getContainer" of class "AdminModulesController".
$formFactory = $this->context->controller->getContainer()->get('form.factory');
}
I did find something similar in the Psaddonsconnect which does work for me. Should we use this instead?
public function getContent()
{
global $kernel;
$formFactory = $kernel->getContainer()->get('form.factory');
}
In fact there are 3 containers :
- Front container contains legacy services for front office
- Back container contains legacy services for back office
- Symfony container contains Symfony services but only available on back office for now because front office migration is not started.
Currently, if you want some Symfony services on front office, you have to declare them in config/front/services.yml inside your modules. Same as if you use them as standalone.
Oh ok that makes sense. I was trying to use the Symfony Services that are already loaded from the Modules main class and i guess how to get the Symfony Sevices was what I was confused but i think I get it. Thanks!
class MyModule extends Module
{
public function getContent()
{
// Accessing legacy back-office service container - works but service not found
$legacy_service = $this->context->controller->get('form.factory');
// Accessing Symfony service container - works and service is found
global $kernel;
$symfony_service = $kernel->getContainer()->get('form.factory');
// The documentation under Services mentions this method - does not work. Error - undefined method 'getContainer'
// this is where the documentation threw me off
$unidentified_service = $this->context->controller->getContainer()->get('custom.service');
}
}
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
if (file_exists(__DIR__ . '/vendor/autoload.php')) {
// Only for PrestaShop < 1.7.6.0
require_once __DIR__ . '/vendor/autoload.php';
}
// Use statement should be after your autoloader inclusion
use PrestaShop\PrestaShop\Adapter\SymfonyContainer;
class MyModule extends Module
{
public function getContent()
{
$symfonyContainer = SymfonyContainer::getInstance();
// You must declare your service in module/mymodule/config/services.yml
$myService = $this->getSymfonyContainer()->get('mymodule.myservice');
}
}
Thank you!
Hi,
how about this ?
class MyModule extends Module
{
public function getContent()
{
// the service still needs to be declared in the right file
$this->get('mymodule.myservice');
}
}
$symfonyContainer = SymfonyContainer::getInstance();
We should never use that directly, this was a terrible idea to create such global state. Note that it will boot the "entire" Symfony application where it's called, so if it's called in a "front office" hook the performance impact will be really huge !
Right now the only two options that work for me on 1.7.5.2 are the SymfonyContainer singleton and calling global on the kernel. The $this->get method looks for services but only works for me on modern controllers. From the module class I'm only able to get legacy services.
Since my problem is only with Admin Legacy Controller i guess would it be okay to use SymfonyContainer for this only?
<?php
class MyModule extends Module
{
public function getContent()
{
// works fine - legacy service
$service = $this->get('employee');
// You have requested a non-existent service
$service = $this->get('mymodule.service'); // defined in my services.yml
// You have requested a non-existent service
$form = $this->get('form.factory'); // Symfony service, not defined in my modules services.yml
// works fine
$form = SymfonyContainer::getInstance()->get('form.factory');
// works fine
global $kernel;
$symfony_service = $kernel->getContainer()->get('form.factory');
}
}
class ModernAdminController extends \PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController
{
public function demoAction()
{
// Works fine
$service = $this->get('mymodule.service'); // defined in my services.yml
// Works fine
$form = $this->get('form.factory'); // Symfony service, not defined in my modules services.yml
}
}
Yes, of course !
and if you override some classes file, you can not get service anyway. like: override/classes/ImageManager.php