symfony 5 service Issue => Using $this when not in object context

Viewed 242

I have an issue when I try to write a service Class on Symfony 5. Here's my service

    <?php

namespace App\Service;

use App\Entity\OrderLine;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;

class UserContribution
{
    /**
     * @var EntityManagerInterface
     */
    private $em;

    public function __construct(EntityManagerInterface $em)
    {
        $this->em = $em;
    }

    /**
     * @param User $user
     * @return bool
     * 3 cas de figure :
     * L'utilisateur est salarié : réponse = true
     * L'utilisateur est un intérimaire : réponse = false
     * L'utilisateur est retraité :
     * S'il est dans son année de départ à la retraite : réponse = true
     * Sinon : Réponse = false
     */
    public function isUserBenefitContribution(User $user):bool
    {
        $userStatus = $user->getStatus()->getId();
        if($userStatus == 3) //retraité
        {
            $dateOfRetirement = $user->getDateOfRetirement();
            if($dateOfRetirement->format('Y') == date('Y'))
            {
                return true;
            } else {
                return false;
            }
        } else {
            return $user->getStatus()->getContribution();
        }
    }

    public function getSoldeAbondement(User $user):string
    {

        $toto = $this->em->getDoctrine()->getManager();

        $benefitContribution = UserContribution::isUserBenefitContribution($user);

        //on met à jour le solde de l'abondement
        if($benefitContribution == true) {
            //récupération abondement user si celui-ci en bénéficie
            //$soldeAbondement = $this->getParameter('app.montant_abondement_'.date('Y')) - $em->getRepository(OrderLine::class)->getSommeParticipationCSE($user);
            $soldeAbondement = $this->em->getRepository(OrderLine::class)->getSommeParticipationCSE($user);
            $soldeAbondement = number_format($soldeAbondement,'2',',',' ').' €';
        } else {
            $soldeAbondement = "NC";
        }
        return $soldeAbondement;
    }
}

When I want to use my function getSoldeAbondement, I encounter this error : Using $this when not in object context.

I don't understand why Im' not in object context ? Do I have to use self instead of This ? Am I in a static environnment ?

Thanks for your help !

2 Answers

You definitely need to use $this->em.

But there seems to be few other problems in your code :

1/ This line can be removed. Variable is not used and $this->em is the EntityManager instance itself, no need to access it. (I guess you where just testing something out of despair here)

$toto = $this->em->getDoctrine()->getManager();

2/ this is a call to a static function. But the function you call is not static.

$benefitContribution = UserContribution::isUserBenefitContribution($user);

instead you should write :

$benefitContribution = $this->isUserBenefitContribution($user);

3/ though minor problem, coding in anything else than English is a bad idea (and I'm french too). And then mixing languages in you function names and comments is definitely PLAIN BAD.

As I think none of the above will solve your main problem, could you please edit your post and show us how you use your function. Where is the call you mention (controller, other service... ???). A snippet of that could help.

/*** EDIT ****/ reaction to your new snippet (preferable to edit original post, for future clarity)

Well, Here it is ! Your error message now makes sense.

In your Controller (for instance) you should inject your service, and then call its method the proper way. Example :

use App\Service\UserContribution;

private $userContribution;

public function __construct(UserContribution $userContribution)
{
    $this->userContribution = $usercontribution;
} 

//later :
public function someMetohd()
{
    // (...)
    $soldeAbondement = $this->userContribution->getSoldeAbondement($user);
}

The call you make is, once again a call to static method :

MyClass::niceMethod() //call to static method, on the CLASS itself

$myClassInstance = new MyClass() ;
$myClassInstance->niceOtherMethod() // call to a non-static method (your case) on an INSTANCE of the class

Exactly as mentioned in point 2/ above.

Don't confuse those two :

::

and

-> 

are NOT SYNONYMOUS.

/** A BIT OF THEORY ***/

Don't get confused by Service injection in Symfony: there is somewhere in the process an instanciation (a $service = new MyService() if you prefer). But the point of a service is to be instantiated at the most ONCE in a request. Symfony hides a bit of this business and get things much more simple to write. You won't write $userContribution = new UserContribution() anywhere. You COULD write it, and it would work, you could access your UserContribution class methods. But then it would NOT be a service.
When you do as suggested in my example, Symfony do that for you :

  • in the __construct itself : nothing as for getting or instantiating your service. Which means if you don't make any call on $userContribution, it's not instantiated at all.
  • In case you make a call on your service, and only then, Symfony gets an instance of the service
    • if none has been instantiated earlier in this request, then a new one.
    • else the formerly instantiated one.

Always the SAME instance along the request, no matter how many services, events, controller... you injected and called your service in. All that ONLY IF YOU USE IT. And that's (also) why services are great !

thanks you to spend some time on my issue. Indeed, I'm not an academic developer ! Even if I known that my code should contain only english language, I am not strict enough to follow this rule !

Nevermind, here is some additional infos to understand how this class is used :

Indeed, I call this class into several SymfonyController, where I add this line :

use App\Service\UserContribution;

And after that, I call the function like this :

$soldeAbondement = UserContribution::getSoldeAbondement($user);

In one of the functions of my class.

Indeed, The error is still alive !

Related