Ruskof
Ruskof

Reputation: 43

Symfony 4, find() an entity

Thanks to the symfony doc https://symfony.com/doc/current/doctrine.html#updating-an-object, i am able to use get/set methods from my entity called 'Produit'.

But when i call the method setProduit() (from Paniers entity) Phpstorm say "expected App\Entity\Paniers, got Object" for the $produitSelected.

i don't know why phpstorm say that because i'm able to use methods, what's the problem ? find() return an entity object, right ?

class PaniersController extends AbstractController
{

    /**
    * @Route("/paniers/add/{id}", name="paniers.add")
    */
    public function addPanier(Request $request, Environment $twig, RegistryInterface $doctrine, $id)
    {
        $produitSelected = $doctrine->getRepository(Produit::class)->find($id);
        if (!$produitSelected) {
            throw $this->createNotFoundException(
                'Pas de produit trouvé pour l\' id : '.$id
            );
        }
        $lignePanier=$doctrine->getRepository(Paniers::class)->findOneBy(['produit' => $produitSelected, 'user' =>$this->getUser()]);
        if($produitSelected->getStock()>0){
            if ($lignePanier){
                $quantite =$lignePanier->getQuantite();
                $lignePanier->setQuantite($quantite+1);
            } else {
                $lignePanier = new Paniers();
                $lignePanier->setUser($this->getUser())
                ->setDateAjoutPanier(new \DateTime(date('Y-m-d')))
                ->setQuantite(1)
                ->setProduit($produitSelected);
            }
            $doctrine->getManager()->persist($lignePanier);
            $produitSelected->setStock($produitSelected->getStock()-1);
            $doctrine->getManager()->persist($produitSelected);
            $doctrine->getManager()->flush();
        }
    }
}

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PaniersRepository")
 * @ORM\Table(name="paniers")
 */
class Paniers
{

//...

   /**
   * @ORM\ManyToOne(targetEntity="Produit")
   * @ORM\JoinColumn(name="produit_id", referencedColumnName="id")
   */
  private $produit;

     public function getProduit(): ?Produit
  {
      return $this->produit;
  }

  public function setProduit(?Produit $produit): self
  {
      $this->produit = $produit;
      return $this;
  }
}

Upvotes: 4

Views: 6764

Answers (3)

Zeljko
Zeljko

Reputation: 5158

You first need to fix code :

Don't inject $id, you only need to typehint your entity: https://symfony.com/doc/current/best_practices/controllers.html#using-the-paramconverter

Don't inject $doctrine, use $em = $this->getDoctrine()->getManager();

Don't inject $twig, use return $this->render('...template', []);

Use English, it is always the rule. Not only other people could help you but also because Symfony understands it and you will need that when you start using form collections: https://symfony.com/doc/current/form/form_collections.html

Inject repository and you will have autocomplete and spot errors easier. Use ```make:entity`` command and you will see what I think, hard to explain.

Upvotes: 2

Sebastian
Sebastian

Reputation: 70

In addition to Denis V's correct answer, I want to add that you could also modify your controller like this:

public function addPanier(Request $request, Environment $twig, RegistryInterface $doctrine,ProduitRepository $produitRepository, $id)
        {
            $produitSelected = $produitRepostiory->find($id);
            //rest of the code
       }

This way phpstorm also knows the type of the returned object, as every returned object is type hinted in the corresponding repository.

Upvotes: 4

Denis V
Denis V

Reputation: 3390

PhpStorm is apparently not that smart to understand that the actual type of the return value of find($id) in this case will be Produit. But you can help it:

/** @var Produit $produitSelected */
$produitSelected = $doctrine->getRepository(Produit::class)->find($id);

To make it working you should either use Produit with the full namespace or add the namespace directly within the type hint.

Of course this doesn't guarantee or ensure that the actual type will be Produit. So, if you make a mistake, PhpStorm will report the type incorrectly.

Upvotes: 3

Related Questions