Jump to content

[SOLVED]This doesn't seem to be a class name error


Recommended Posts

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 :Capturedcrandu2024-08-1209-54-55.thumb.png.916ccf7b4e8ae1b77973ace5e1b50c47.png

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 : 
Capturedcrandu2024-08-1210-07-11.png.c1a1e7c0169f688bd69a19efe8fa3c6e.png

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 by sococa
solved (see edit history)
Link to comment
Share on other sites

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 :D
 

Link to comment
Share on other sites

Posted (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 by sococa (see edit history)
Link to comment
Share on other sites

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.

  • Like 1
Link to comment
Share on other sites

  • sococa changed the title to [SOLVED]This doesn't seem to be a class name error

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...