Partage
  • Partager sur Facebook
  • Partager sur Twitter

Relation ManyToOne non fonctionnelle

Framework Symfony

Sujet résolu
    7 avril 2020 à 2:41:03

    Bonjour à tous ! Depuis quelque temps, je me casse la tête sur un problème dans mon code PHP. J'utilise le framework Symfony et j'ai deux entités, User et PasswordToken. Elles sont liés par une relation ManyToOne. Mon problème est que lorsque j'essaye d'appeller $user->getPasswordTokens(); cela me retourne un tableau et ça marche. Cependant, lorsque j'appelle $passwordToken->getUser();, la fonction me renvoie une instance de mon utilisateur qui est vide ... Quelqu'un pourrait m'aider ? Merci !

    Mon entité User

    <?php
    
    namespace App\Entity;
    
    use Doctrine\Common\Collections\ArrayCollection;
    use Doctrine\Common\Collections\Collection;
    use Doctrine\ORM\Mapping as ORM;
    use Exception;
    use Symfony\Component\Security\Core\User\UserInterface;
    use Symfony\Component\Validator\Constraints as Assert;
    use \DateTime;
    
    /**
     * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
     * @ORM\Table(name="users")
     */
    class User implements UserInterface
    {
        /**
         * User Id
         * @ORM\Id()
         * @ORM\GeneratedValue()
         * @ORM\Column(type="integer")
         */
        private $id;
    
        /**
         * User Email
         * @Assert\NotBlank(message="Please enter an email")
         * @Assert\Email(message="Please enter a valid email")
         * @Assert\Length(max="255", maxMessage="Please enter a shorter email")
         * @ORM\Column(type="string", length=180, unique=true)
         */
        private $email;
    
        /**
         * User Roles
         * @ORM\Column(type="json")
         */
        private $roles = [];
    
        /**
         * User Encode Password
         * @var string The hashed password
         * @ORM\Column(type="string")
         */
        private $password;
    
        /**
         * User barcode
         * @Assert\NotBlank(message="Please enter a code")
         * @Assert\Length(max="255", maxMessage="Please enter a shorter code")
         * @ORM\Column(type="string", length=255)
         */
        private $code;
    
        /**
         * Created at date of user
         * @ORM\Column(type="datetime")
         */
        private $created_at;
    
        /**
         * User tel
         * @Assert\Length(max="12", maxMessage="Please enter a shorter phonenumber")
         * @ORM\Column(type="string", length=255, nullable=true)
         */
        private $tel;
    
        /**
         * User name
         * @Assert\NotBlank(message="Please enter a name")
         * @Assert\Length(min="2", max="50", minMessage="Please enter a longer name", maxMessage="Please enter a shorter firstname")
         * @ORM\Column(type="string", length=255)
         */
        private $name;
    
        /**
         * User Firstname
         * @Assert\NotBlank(message="Please enter a firstname")
         * @Assert\Length(min="2", max="50", minMessage="Please enter a longer firstname", maxMessage="Please enter a shorter firstname")
         * @ORM\Column(type="string", length=255)
         */
        private $firstname;
    
        /**
         * User date of birth
         * @Assert\NotBlank(message="Please enter a birthdate")
         * @Assert\Date(message="Please enter a valid date")
         * @ORM\Column(type="date")
         */
        private $birth_date;
    
        /**
         * User address
         * @ORM\Column(type="string", length=255, nullable=true)
         */
        private $address;
    
        /**
         * @ORM\OneToMany(targetEntity="App\Entity\Transaction", mappedBy="user")
         */
        private $transactions;
    
        /**
         * @ORM\OneToMany(targetEntity="App\Entity\PasswordToken", mappedBy="user")
         */
        private $passwordTokens;
    
        /**
         * @Assert\EqualTo(propertyPath="plaintext_password", message="Your passwords must be equal")
         * @var string
         */
        private $password_confirm;
    
        /**
         * Plain text password
         * @Assert\NotBlank(message="Please enter a password")
         * @Assert\Length(min="8", max="255", minMessage="Your password should be at least 8 characters", maxMessage="Please enter a shorter password")
         * @var string
         */
        private $plaintext_password;
    
        /**
         * User constructor.
         * @throws Exception
         */
        public function __construct() {
            $this->created_at = new DateTime();
            $this->transactions = new ArrayCollection();
            $this->passwordTokens = new ArrayCollection();
        }
    
        /**
         * Getter fo id
         * @return int|null
         */
        public function getId(): ?int
        {
            return $this->id;
        }
    
        /**
         * Getter for email
         * @return string|null
         */
        public function getEmail(): ?string
        {
            return $this->email;
        }
    
        /**
         * Setter for email
         * @param string $email
         * @return $this
         */
        public function setEmail(string $email): self
        {
            $this->email = $email;
    
            return $this;
        }
    
        /**
         * Getter for barcode
         * @return string|null
         */
        public function getCode(): ?string
        {
            return $this->code;
        }
    
        /**
         * Setter for barcode
         * @param string $code
         * @return $this
         */
        public function setCode(string $code): self
        {
            $this->code = $code;
    
            return $this;
        }
    
        /**
         * Getter for date of creation
         * @return \DateTimeInterface|null
         */
        public function getCreatedAt(): ?\DateTimeInterface
        {
            return $this->created_at;
        }
    
        /**
         * Setter for creation date
         * @param \DateTimeInterface $created_at
         * @return $this
         */
        public function setCreatedAt(\DateTimeInterface $created_at): self
        {
            $this->created_at = $created_at;
    
            return $this;
        }
    
        /**
         * Getter for phone
         * @return string|null
         */
        public function getTel(): ?string
        {
            return $this->tel;
        }
    
        /**
         * Setter for phone
         * @param string|null $tel
         * @return $this
         */
        public function setTel(?string $tel): self
        {
            $this->tel = $tel;
    
            return $this;
        }
    
        /**
         * Getter for name
         * @return string|null
         */
        public function getName(): ?string
        {
            return $this->name;
        }
    
        /** Setter for name
         * @param string $name
         * @return $this
         */
        public function setName(string $name): self
        {
            $this->name = $name;
    
            return $this;
        }
    
        /**
         * Getter for firstname
         * @return string|null
         */
        public function getFirstname(): ?string
        {
            return $this->firstname;
        }
    
        /**
         * Setter for firstname
         * @param string $firstname
         * @return $this
         */
        public function setFirstname(string $firstname): self
        {
            $this->firstname = $firstname;
    
            return $this;
        }
    
        /**
         * Getter for birthday date
         * @return \DateTimeInterface|null
         */
        public function getBirthDate(): ?\DateTimeInterface
        {
            return $this->birth_date;
        }
    
        /**
         * Setter for birthday date
         * @param \DateTimeInterface $birth_date
         * @return $this
         */
        public function setBirthDate(\DateTimeInterface $birth_date): self
        {
            $this->birth_date = $birth_date;
    
            return $this;
        }
    
        /**
         * Getter for address
         * @return string|null
         */
        public function getAddress(): ?string
        {
            return $this->address;
        }
    
        /**
         * Setter for address
         * @param string|null $address
         * @return $this
         */
        public function setAddress(?string $address): self
        {
            $this->address = $address;
    
            return $this;
        }
    
        /**
         * Getter for Password Confirm
         * @return string|null
         */
        public function getPasswordConfirm(): ?string
        {
            return $this->password_confirm;
        }
    
        /**
         * Setter for Password Confirm
         * @param string $password_confirm
         * @return User
         */
        public function setPasswordConfirm(string $password_confirm): self
        {
            $this->password_confirm = $password_confirm;
            return $this;
        }
    
        /**
         * A visual identifier that represents this user.
         *
         * @see UserInterface
         */
        public function getUsername(): string
        {
            return (string) $this->email;
        }
    
        /**
         * @see UserInterface
         */
        public function getRoles(): array
        {
            $roles = $this->roles;
            // guarantee every user at least has ROLE_USER
            $roles[] = 'ROLE_USER';
    
            return array_unique($roles);
        }
    
        /**
         * Setter for Roles
         * @param array $roles
         * @return $this
         */
        public function setRoles(array $roles): self
        {
            $this->roles = $roles;
    
            return $this;
        }
    
        /**
         * Getter for Password
         * @see UserInterface
         */
        public function getPassword(): string
        {
            return (string) $this->password;
        }
    
        /**
         * Setter for Password
         * @param string $password
         * @return $this
         */
        public function setPassword(string $password): self
        {
            $this->password = $password;
    
            return $this;
        }
    
        /**
         * Getter for salt
         * @see UserInterface
         * @return null
         */
        public function getSalt()
        {
            return null;
        }
    
        /**
         * Function to erase sensitive data of user
         * @see UserInterface
         * @return null
         */
        public function eraseCredentials()
        {
            return null;
        }
    
        /**
         * @return Collection|Transaction[]
         */
        public function getTransactions(): Collection
        {
            return $this->transactions;
        }
    
        public function addTransaction(Transaction $transaction): self
        {
            if (!$this->transactions->contains($transaction)) {
                $this->transactions[] = $transaction;
                $transaction->setUser($this);
            }
    
            return $this;
        }
    
        public function removeTransaction(Transaction $transaction): self
        {
            if ($this->transactions->contains($transaction)) {
                $this->transactions->removeElement($transaction);
                // set the owning side to null (unless already changed)
                if ($transaction->getUser() === $this) {
                    $transaction->setUser(null);
                }
            }
    
            return $this;
        }
    
        /**
         * @return Collection|PasswordToken[]
         */
        public function getPasswordTokens(): Collection
        {
            return $this->passwordTokens;
        }
    
        public function addPasswordToken(PasswordToken $passwordToken): self
        {
            if (!$this->passwordTokens->contains($passwordToken)) {
                $this->passwordTokens[] = $passwordToken;
                $passwordToken->setUser($this);
            }
    
            return $this;
        }
    
        public function removePasswordToken(PasswordToken $passwordToken): self
        {
            if ($this->passwordTokens->contains($passwordToken)) {
                $this->passwordTokens->removeElement($passwordToken);
                // set the owning side to null (unless already changed)
                if ($passwordToken->getUser() === $this) {
                    $passwordToken->setUser(null);
                }
            }
    
            return $this;
        }
    
        /**
         * Getter for plain text password
         * @return mixed
         */
        public function getPlaintextPassword()
        {
            return $this->plaintext_password;
        }
    
        /**
         * Setter for plaintext password
         * @param mixed $plaintext_password
         * @return User
         */
        public function setPlaintextPassword($plaintext_password): self
        {
            $this->plaintext_password = $plaintext_password;
    
            return $this;
        }
    
    }
    

    Mon entité PasswordToken :

    <?php
    
    namespace App\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    use Symfony\Component\Validator\Constraints as Assert;
    
    /**
     * @ORM\Entity(repositoryClass="App\Repository\PasswordTokenRepository")
     * @ORM\Table(name="password_tokens")
     */
    class PasswordToken
    {
        /**
         * @ORM\Id()
         * @ORM\GeneratedValue()
         * @ORM\Column(type="integer")
         */
        private $id;
    
        /**
         * User of the token
         * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="passwordTokens")
         * @ORM\JoinColumn(nullable=false)
         */
        private $user;
    
        /**
         * Secret token*
         * @ORM\Column(type="string", length=255)
         */
        private $token;
    
        /**
         * Expiration datetime of the token
         * @ORM\Column(type="datetime")
         */
        private $expire_at;
    
        /**
         * Email of user
         * @var $email_user
         * @Assert\Email(message="Please enter a valid email")
         * @Assert\Length(max="255", maxMessage="Please enter a shorter email")
         */
        private $email_user;
    
        /**
         * Getter for id
         * @return int|null
         */
        public function getId(): ?int
        {
            return $this->id;
        }
    
        /**
         * Getter for user
         * @return User|null
         */
        public function getUser(): ?User
        {
            return $this->user;
        }
    
        /**
         * Setter for user
         * @param User|null $user
         * @return $this
         */
        public function setUser(?User $user): self
        {
            $this->user = $user;
    
            return $this;
        }
    
        /**
         * Getter for token
         * @return string|null
         */
        public function getToken(): ?string
        {
            return $this->token;
        }
    
        /**
         * Setter for token
         * @param string $token
         * @return $this
         */
        public function setToken(string $token): self
        {
            $this->token = $token;
    
            return $this;
        }
    
        /**
         * Getter for expiration date
         * @return \DateTimeInterface|null
         */
        public function getExpireAt(): ?\DateTimeInterface
        {
            return $this->expire_at;
        }
    
        /**
         * Setter for expiration date
         * @param \DateTimeInterface $expire_at
         * @return $this
         */
        public function setExpireAt(\DateTimeInterface $expire_at): self
        {
            $this->expire_at = $expire_at;
    
            return $this;
        }
    
        /**
         * Getter for email_user
         * @return string|null
         */
        public function getEmailUser(): ?string
        {
            return $this->email_user;
        }
    
        /**
         * Setter for email_user
         * @param string $email_user
         * @return $this
         */
        public function setEmailUser(string $email_user): self
        {
            $this->email_user = $email_user;
    
            return $this;
        }
    
    }
    



    • Partager sur Facebook
    • Partager sur Twitter
    Anonyme
      7 avril 2020 à 8:20:40

      Qu'appelles-tu une instance vide ? Es-tu sûr qu'il ne s'agit pas d'un proxy ?

      • Partager sur Facebook
      • Partager sur Twitter
        7 avril 2020 à 13:48:06

        Je ne sais pas du tout. C'est un objet aux propriétés nulles. Cependant, lorsque j'appelle derrière la méthode getId(), j'obtiens bien l'id. getEmail(), j'obtiens bien l'email. En fait si j'ai bien compris c'est que Symfony ne charge le contenu que si il en a besoin ... J'avais fais un dd($user) juste après le getUser() et rien ... Mais après avoir travaillé avec cet user miracle j'ai ses propriétés !
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          7 avril 2020 à 14:19:33

          C'est ce qu'on appelle un proxy ^^

          Pour info c'est Doctrine qui gère ça, pas Symfony.

          • Partager sur Facebook
          • Partager sur Twitter
            7 avril 2020 à 14:39:06

            D'accord :-)

            Mais a quoi sert un proxy exactement ?

            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              7 avril 2020 à 14:46:40

              À éviter une requête en base si elle n’est pas nécessaire. Par défaut les associations sont considérées comme lazy par Doctrine. Quand tu récupères un PasswordToken de ta base Doctrine stocke un proxy dans $user : une classe générée automatiquement qui va étendre ta classe User et contenir son identifiant. À la moindre utilisation d’un accesseur, Doctrine va alors envoyer une requête à ta base pour charger ses propriétés.

              -
              Edité par Anonyme 7 avril 2020 à 14:48:01

              • Partager sur Facebook
              • Partager sur Twitter

              Relation ManyToOne non fonctionnelle

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown