0

Here is my problem: In fact when I retrieve the logged in user data with $currentUser = $this->getUser(); Afterwards I cannot access the method->getNewPassword(). I am told that it is not defined yet I have previously defined it on the User entity. Could this be due to my version of symfony ?

I don't understand why this error occurs when everything seems very normal.

Here's my User entity file:

   <?php

namespace App\Entity;
use App\Repository\UserRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;

#[ORM\Entity(repositoryClass: UserRepository::class)]
#[UniqueEntity(fields:"email", message:"Email déjà pris")]
class User implements UserInterface, PasswordAuthenticatedUserInterface {
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column(type: 'integer')]
    private $id;// par défault

    #[ORM\Column(type: 'string', length: 180, unique: true)]
    #[Assert\Email(message:'Veuillez entrer un email valide.')]
    #[Assert\NotBlank(message:'Veuillez renseigner votre email.')]
    private $email; // par défault

    #[ORM\Column(type: 'json')]
    private $roles = []; // par défault

    #[ORM\Column(type: 'string')]
    #[Assert\Length(min: 6, minMessage:'Le mot de passe doit avoir au moins 6 caractères.')]
    #[Assert\NotBlank(message:'Veuillez renseigner un mot de passe.')]
    private $password; // par défault

    #[Assert\Length(min: 6, minMessage:'Le mot de passe doit avoir au moins 6 caractères.')]
    private $newPassword;
    
    #[ORM\Column(type: 'string', length: 255)]
    #[Assert\NotBlank(message:'Veuillez renseigner votre prénom.')]
    private $firstname;

    #[ORM\Column(type: 'string', length: 255)]
    #[Assert\NotBlank(message:'Veuillez renseigner votre nom.')]
    private $lastname;

    #[ORM\OneToMany(mappedBy: 'author', targetEntity: Question::class, orphanRemoval: true)]
    private $questions;

    #[ORM\OneToMany(mappedBy: 'author', targetEntity: Comment::class, orphanRemoval: true)]
    private $comments;

    #[ORM\Column(type: 'string', length: 255)]
    #[Assert\Url(message:'Veuillez renseigner une Url.')]
    #[Assert\NotBlank(message:'Veuillez renseigner une image de profil.')]
    private $picture;

    #[ORM\OneToMany(mappedBy: 'author', targetEntity: Vote::class, orphanRemoval: true)]
    private $votes;

    public function __construct()
    {
        $this->Questions = new ArrayCollection();
        $this->comments = new ArrayCollection();
        $this->votes = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getEmail(): ?string
    {
        return $this->email;
    }

    public function setEmail(string $email): self
    {
        $this->email = $email;

        return $this;
    }

    /**
     * A visual identifier that represents this user.
     *
     * @see UserInterface
     */
    public function getUserIdentifier(): string
    {
        return (string) $this->email;
    }

    public function getRoles():array
    {
        return $this->roles;
    }

    public function setRoles(array $roles): self
    {
        $this->roles = $roles;

        return $this;
    }

    public function getPassword(): ?string 
    {
        return $this->password;
    }

    public function setPassword(string $password): self
    {
        $this->password = $password;

        return $this;
    }
    public function getNewPassword(): ?string 
    {
        return $this->newPassword;
    }

    public function setNewPassword(string $password): self
    {
        $this->newPassword = $password;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function eraseCredentials()
    {
        // If you store any temporary, sensitive data on the user, clear it here
        // $this->plainPassword = null;
    }

    public function getFirstname(): ?string
    {
        return $this->firstname;
    }

    public function setFirstname(string $firstname): self
    {
        $this->firstname = $firstname;

        return $this;
    }

    public function getLastname(): ?string
    {
        return $this->lastname;
    }

    public function setLastname(string $lastname): self
    {
        $this->lastname = $lastname;

        return $this;
    }

    /**
     * @return Collection|Question[]
     */
    public function getQuestions(): Collection
    {
        return $this->questions;
    }

    public function addQuestion(Question $question): self
    {
        if (!$this->questions->contains($question)) {
            $this->questions[] = $question;
            $question->setAuthor($this);
        }

        return $this;
    }

    public function removeQuestion(Question $question): self
    {
        if ($this->Questions->removeElement($question)) {
            // set the owning side to null (unless already changed)
            if ($question->getAuthor() === $this) {
                $question->setAuthor(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|Comment[]
     */
    public function getComments(): Collection
    {
        return $this->comments;
    }

    public function addComment(Comment $comment): self
    {
        if (!$this->comments->contains($comment)) {
            $this->comments[] = $comment;
            $comment->setAuthor($this);
        }

        return $this;
    }

    public function removeComment(Comment $comment): self
    {
        if ($this->comments->removeElement($comment)) {
            // set the owning side to null (unless already changed)
            if ($comment->getAuthor() === $this) {
                $comment->setAuthor(null);
            }
        }

        return $this;
    }

    public function getPicture(): ?string
    {
        return $this->picture;
    }

    public function setPicture(string $picture): self
    {
        $this->picture = $picture;

        return $this;
    }

    public function getFullname(): ?string {

        return $this->firstname.' '.$this->lastname;
    }

    /**
     * @return Collection|Vote[]
     */
    public function getVotes(): Collection
    {
        return $this->votes;
    }

    public function addVote(Vote $vote): self
    {
        if (!$this->votes->contains($vote)) {
            $this->votes[] = $vote;
            $vote->setAuthor($this);
        }

        return $this;
    }

    public function removeVote(Vote $vote): self
    {
        if ($this->votes->removeElement($vote)) {
            // set the owning side to null (unless already changed)
            if ($vote->getAuthor() === $this) {
                $vote->setAuthor(null);
            }
        }

        return $this;
    }
}

Here's my UserController.php file:

<?php

namespace App\Controller;

use App\Entity\User;
use App\Form\UserType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Doctrine\ManagerRegistry;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;

class UserController extends AbstractController
{
    #[Route('/user/{id}', name: 'user')]
    #[IsGranted('IS_AUTHENTICATED_REMEMBERED')]
    public function userProfile(User $user): Response {
        $currentUser = $this->getUser();

        if($currentUser === $user) {
            return $this->redirectToRoute('current_user');
        }
        return $this->render('user/show.html.twig', [
            'user' => $user,
        ]);
    }

    #[Route('/myprofile', name: 'current_user')]
    #[IsGranted('IS_AUTHENTICATED_FULLY')]
    public function currentUserProfile(Request $request, EntityManagerInterface $em, UserPasswordHasherInterface $passwordHasher): Response
    {   
        $currentUser = $this->getUser(); // on récupère l'utilisateur connecté.
        $userForm = $this->createForm(UserType::class, $currentUser); // création du formulaire
        $userForm->remove('password'); // suppression du champ password
        $userForm->add('newPassword', PasswordType::class, ['label' => 'Nouveau mot de passe']);
        $userForm->handleRequest($request);
        if($userForm->isSubmitted() && $userForm->isValid()) {
            // dump($currentUser);
            $newPassword = $currentUser->getNewPassword();
            if($newPassword) {
                $hash = $passwordHasher->hashPassword($currentUser, $newPassword);
                $currentUser->setPassword($hash);
            }
            $em->flush();
            // dump($currentUser);
        }
        return $this->render('user/index.html.twig', [
            'form' => $userForm->createView(),
        ]);
    }
}

Here is my UserType form:

   <?php

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('email', null, ['label' =>'*Email'])
            ->add('firstname', null, ['label' =>'*Prénom'])
            ->add('lastname', null, ['label' =>'*Nom'])
            ->add('picture', null, ['label' =>'*Image'])
            ->add('password', PasswordType::class, ['label' =>'*Mot de passe','empty_data' => ''])
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => User::class,
        ]);
    }
}

I think I was clear about my question. If you need additional information to help me please leave it in the comments. Please I am waiting for answers to my question.

  • Recommendation: There is a [forgot/update password bundle](https://symfony.com/doc/current/security/passwords.html#reset-password) for this. You can then run `php bin/console make:reset-password` and all the files will be created for you. – Bossman Mar 17 '22 at 12:49
  • Doubtful it's related to Symfony version. When you executed dump($currentUser) did you get your App\Entity\User class? Just for future reference, your question could be improved by not posting as much code. We don't really need to see the complete User code. – Cerad Mar 17 '22 at 12:50
  • @Bossman In fact, the code consists of modifying his information (email, first name, last name or password when he clicks on his profile picture) and not resetting his information. – Hervé Sonkeng Mar 17 '22 at 13:23
  • @Cerad Of course I have a display of the object $currentUser with the following error message: (Warning: Cannot modify header information - headers already sent by ) when I uncomment the line of code $userForm->add('newPassword ', PasswordType::class, ['label' => 'New password']). – Hervé Sonkeng Mar 17 '22 at 13:57
  • The modifier `of course` has no place on stackoverflow. I was trying to confirm that you were indeed getting the expected user object. It's entirely possible that you may have gotten a different User type depending on how the security system is configured. Far stranger things have happened. – Cerad Mar 17 '22 at 14:15

0 Answers0