sococa Posted August 12 Share Posted August 12 (edited) Prestashop 8.1.1 PHP 8.1.29 Hi everyone, I'm trying to create a module, but for a reason that i don't understand, the call to my service in my controller don't work. : $sendCodeService = ServiceLocator::get('lebrun.lebruntwofa.sendcodeservice'); //C'EST ICI QUE CA MERDE When i directly call the url https://prestashop.local/module/lebruntwofa/sendcode in the browser, i receive this error : However, the service is called with the same name that the services.yam name : services: _defaults: public: true lebrun.lebruntwofa.sendcodeservice: public: true class: Lebrun\Lebruntwofa\Services\SendcodeService He's well declared : /var/www/prestashop$ sudo php bin/console debug:container lebrun.lebruntwofa.sendcodeservice Information for Service "lebrun.lebruntwofa.sendcodeservice" ============================================================ ---------------- --------------------------------------------- Option Value ---------------- --------------------------------------------- Service ID lebrun.lebruntwofa.sendcodeservice Class Lebrun\Lebruntwofa\Services\SendcodeService Tags - Public yes Synthetic no Lazy no Shared yes Abstract no Autowired yes Autoconfigured yes ---------------- --------------------------------------------- I think the strucure files and names of files are good : So i have no idea of what's wrong, i hope someone can help me 🙏 I share you the entire module for a better comprehension. Thank you ! lebruntwofa.zip Edited August 14 by sococa solved (see edit history) Link to comment Share on other sites More sharing options...
Andrei H Posted August 12 Share Posted August 12 Hello, It looks like the ServiceLocator is trying to find the class, but it cannot do so, as its name is not provided. Providing its id might work only for the admin pages. You can do the following: In your module folder run composer du - this might be optional In the controller, at the top add: use Lebrun\Lebruntwofa\Services\SendcodeService; Use ServiceLocator::get(SendcodeService::class) instead of ServiceLocator::get('lebrun.lebruntwofa.sendcodeservice') Also, if you look into the ServiceLocator class, you will see that it will be removed at some point, therefore a better way to do it is to manually inject the service via the __construct method or via a setter. Btw, nice comment on line 62 Link to comment Share on other sites More sharing options...
sococa Posted August 13 Author Share Posted August 13 (edited) Hello @Andrei H, Thank you, you are divine. My comment was absolutely necessary It works However, i have 2 questions. 1/ How did you find this ?? I didn't see all this in the doc. Nothing about ServiceLocator. 2/ You said : "Also, if you look into the ServiceLocator class, you will see that it will be removed at some point, therefore a better way to do it is to manually inject the service via the __construct method or via a setter." So, i need to use _construct instead of ServiceLocator::get(SendcodeService::class) ? I need to place ServiceLocator::get(SendcodeService::class) in this construct ? public function __construct() { $this->name = 'lebruntwofa'; $this->tab = 'others'; $this->version = '1.0.0'; $this->author = 'lebrun'; $this->need_instance = 1; $this->ps_versions_compliancy = [ 'min' => '8.0.0', 'max' => '8.99.99', ]; $this->bootstrap = true; parent::__construct(); $this->confirmUninstall = $this->l('Do you still you want to uninstall this module?'); $this->displayName = $this->l('Lebrun Two Factor Authentification'); $this->description = $this->l('Ajoute une authentification par code à la connexion des clients'); } Big thanks again. Edited August 13 by sococa (see edit history) Link to comment Share on other sites More sharing options...
Andrei H Posted August 13 Share Posted August 13 Hello, For the first one, I initially done it via trial and error. It was asking for a class name, so I added the full path to it. But I also tried with a google search and found the importing solution, which is better I guess. As for the second one, if you go into src/Adapter/ServiceLocator.php, you will see the following comment: "To be removed in 1.7.1." - this is clearly not the case, as we are using PrestaShop 8 and the class is still present, but it might be removed in the future. Actually, forget what I said above about the construct, the easiest way to do this is the following: At the top of the file add: use PrestaShop\PrestaShop\Core\Foundation\IoC\Container; Replace ServiceLocator::get(SendcodeService::class) with (new Container())->make(SendcodeService::class); One way to make this cleaner is to store this service in a class property. Here is how: At the top of the class add the following: private $sendCodeService; At the top of the initContent method add the following: $this->sendCodeService = (new Container())->make(SendcodeService::class); Now you will have access to the service via $this->sendCodeService in every method inside the class, thus not need to initialize it in each method. 1 Link to comment Share on other sites More sharing options...
sococa Posted August 14 Author Share Posted August 14 Ok thanks, I never would have thought to show in src/Adapter ... Problem solved ! 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now