EasyCorp / EasyAdminBundle

EasyAdmin is a fast, beautiful and modern admin generator for Symfony applications.
MIT License
4.07k stars 1.02k forks source link

create manualy a encoded password from controller crud #4168

Closed Sananda-KUMARA closed 3 years ago

Sananda-KUMARA commented 3 years ago

Describe the bug

I want to know where to put my call to UserPasswordEncoderInterface to manually encrypt my unencrypted password, it is clear. Is there a way to do it properly in easyadmin?

  public function edit(Request $request, Personne $personne, UserPasswordEncoderInterface $encoder): Response
    {
        $cryptpassword = $encoder->encodePassword($personne, $personne->getPassword());
        $personne->setPassword($cryptpassword);

To Reproduce easyadmin v.3.2.2

(OPTIONAL) Additional context If they are useful, include logs, code samples, screenshots, etc. image

vic-blt commented 3 years ago

In your CRUD controller :

Sananda-KUMARA commented 3 years ago

Thank you very much for your help, you got it right. it works perfectly but I would like to display the password in the password field on the edit form. I do not persist the plain_password field in the database for security reasons. On the other hand, the empty string value throws an error when submitting the form, and I don't understand why because in my entity it is : ` /**

Thank you for your time ...

vic-blt commented 3 years ago

I need more details, can you post your entity please ? If you want to display the password, then you can remove ->setFormType(PasswordType::class).

Here's my entity:

<?php

namespace App\Entity;

use App\Entity\Traits\IdTrait;
use App\Entity\Traits\ToggleableTrait;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity
 * @ORM\Table(name="user")
 */
class User implements UserInterface
{
    use IdTrait;
    use ToggleableTrait;

    const DEFAULT_ROLE = 'ROLE_USER';
    const ADMIN_ROLE = 'ROLE_ADMIN';
    const SUPER_ADMIN_ROLE = 'ROLE_SUPER_ADMIN';

    const ROLES = [
        'admin.user.roles.default' => self::DEFAULT_ROLE,
        'admin.user.roles.admin' => self::ADMIN_ROLE,
        'admin.user.roles.super_admin' => self::SUPER_ADMIN_ROLE,
    ];

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private $firstName;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private $lastName;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private $email;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private $username;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    private $password;

    /**
     * @var string
     */
    private $plainPassword;

    /**
     * @var string
     */
    private $salt;

    /**
     * @var array
     * @ORM\Column(type="array")
     */
    private $roles = [self::DEFAULT_ROLE];

    /**
     * @return string
     */
    public function __toString()
    {
        return "$this->firstName $this->lastName";
    }

    /**
     * @return string
     */
    public function getFirstName()
    {
        return $this->firstName;
    }

    /**
     * @param string $firstName
     */
    public function setFirstName(string $firstName)
    {
        $this->firstName = $firstName;
    }

    /**
     * @return string
     */
    public function getLastName()
    {
        return $this->lastName;
    }

    /**
     * @param string $lastName
     */
    public function setLastName(string $lastName)
    {
        $this->lastName = $lastName;
    }

    /**
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }

    /**
     * @param string $email
     */
    public function setEmail(string $email)
    {
        $this->email = $email;
    }

    /**
     * @return string
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * @param string $username
     */
    public function setUsername(string $username)
    {
        $this->username = $username;
    }

    /**
     * @return string
     */
    public function getPassword()
    {
        return $this->password;
    }

    /**
     * @param string $password
     */
    public function setPassword(string $password)
    {
        $this->password = $password;
    }

    /**
     * @return string
     */
    public function getPlainPassword()
    {
        return $this->plainPassword;
    }

    /**
     * @param string $plainPassword
     */
    public function setPlainPassword(?string $plainPassword)
    {
        $this->plainPassword = $plainPassword;
    }

    /**
     * @return array
     */
    public function getRoles()
    {
        return $this->roles;
    }

    /**
     * @param array $roles
     */
    public function setRoles(array $roles)
    {
        $this->roles = $roles;
    }

    /**
     * @return string
     */
    public function getSalt()
    {
        return $this->salt;
    }

    /**
     * @param string $salt
     */
    public function setSalt(string $salt)
    {
        $this->salt = $salt;
    }

    public function hasRole(string $role)
    {
        return in_array(strtoupper($role), $this->roles, true);
    }

    public function addRole(string $role)
    {
        $role = strtoupper($role);
        if (!in_array($role, $this->roles, true)) {
            $this->roles[] = $role;
        }
    }

    public function removeRole(string $role)
    {
        if (false !== $key = array_search(strtoupper($role), $this->roles, true)) {
            unset($this->roles[$key]);
            $this->roles = array_values($this->roles);
        }
    }

    public function eraseCredentials()
    {
    }
}
Sananda-KUMARA commented 3 years ago

Good evening, as requested I am sending you my person entity class. You can see that I have two password fields: one persisted and the other not (cf: plainPassword). I also attach my crud class and a piece of security.yaml file for encoders

<?php

namespace App\Entity;

use App\Entity\Adresse;
use App\Entity\Config;
use App\Entity\Conversation;
use App\Entity\Photo;
use App\Entity\RendezVous;
use App\Entity\SignalementAbus;
use App\Entity\Video;
use App\Repository\PersonneRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Query\AST\Functions\LengthFunction;

use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;

use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Normalizer\GetSetMethodNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

/**
 * @ORM\Entity(repositoryClass=PersonneRepository::class)
 */
class Personne implements UserInterface
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=180, unique=true)
     */
    private $login;

    /**
     * @ORM\Column(type="json", nullable=true)
     */
    private $roles;

    /**
     * @ORM\Column(type="string", nullable=true))
     */
    private $password;

    private $plain_password;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $nom;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $prenom;
    /**
     * @ORM\Column(type="array", nullable=true)
     */
    private $type_personne;

    /**
     * @ORM\Column(type="date")
     */
    private $date_naissance;

    /**
     * @ORM\Column(type="string", length=1, nullable=true)
     */
    private $sexe;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $status_marital;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $langue_maternelle;

    /**
     * @ORM\Column(name="email", type="string", length=255, unique=true)
     */
    private $email;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $tel_fixe;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $tel_portable;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $fax;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $langue;

    /**
     * Une personne a une et une seule adresse
     * @ORM\OneToOne(targetEntity=Adresse::class, mappedBy="personne", cascade={"remove","persist"})
     */
    private $adresse;

    /**
     * @ORM\OneToMany(targetEntity=RendezVous::class, mappedBy="personnes")
     */
    private $rendezVous;

    /**
     * @ORM\OneToMany(targetEntity=SignalementAbus::class, mappedBy="personneDesignee")
     */
    private $signalementAuteurAbus;

    /**
     * @ORM\OneToMany(targetEntity=SignalementAbus::class, mappedBy="personneDesignant")
     */
    private $signalementDenonciateurAbus;

    /**
     * @ORM\OneToMany(targetEntity=Conversation::class, mappedBy="personne")
     */
    private $faire_post;

    /**
     * @ORM\OneToMany(targetEntity=Video::class, mappedBy="personne")
     */
    private $videos;

    /**
     * @ORM\OneToMany(targetEntity=Photo::class, mappedBy="personne")
     */
    private $photos;

    /**
     * @ORM\ManyToMany(targetEntity=Config::class, mappedBy="personnes")
     */
    private $config;

    public function __construct()
    {
        $this->rendezVous = new ArrayCollection();
        $this->signalementAuteurAbus = new ArrayCollection();
        $this->signalementDenonciateurAbus = new ArrayCollection();
        $this->faire_post = new ArrayCollection();
        $this->videos = new ArrayCollection();
        $this->photos = new ArrayCollection();
        $this->config = new ArrayCollection();
    }

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

    /**
     * @see UserInterface
     */
    public function getRoles(): array
    {
        $roles = $this->roles;
        //dd($roles);
        $serializer = new Serializer([], [new JsonEncoder()]);

        //Parcours tableau JSON
        $roles_selection = [];

        if (is_array($roles) && count($roles) > 1) { //si tableau je parcours la valeur renvoyée par $this->roles
            foreach ($roles as $key => $value) {
                $value = str_replace("\\", "", $value);  //fix le bug suivant : '{"ROLE": "ROLE_ADMIN"}' -> marche au decode, on suppreime les \
                // var_dump($value);
                $data = $serializer->decode($value, 'json', ['json_decode_options' => \JSON_HEX_APOS]); //Json string vers array php ...
                //var_dump($data);
                $roles_selection[] = $data["ROLE"];
            }
        }
        $roles_selection[] = "ROLE_USER"; // on ajoute celle ligne pour être sûr que l'utilisateur ait au moins le ROLE USER
        $roles_selection = array_unique($roles_selection); //filtrage des valeurs en doublon ...
        //dd($roles_selection);
        return $roles_selection;
    }

    /**
     * @see UserInterface
     */
    public function setRoles(array $roles): self
    {
        $this->roles = $roles;

        return $this;
    }

    /**
     * @see UserInterface
     */
    public function getPassword(): string
    {
        return (string) $this->password;
    }

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

        return $this;
    }

    public function getPlainPassword(): string
    {
        return (string) $this->plain_password;
    }

    public function setPlainPassword(string $plain_password): self
    {
        $this->plain_password = $plain_password;

        return $this;
    }

    /*  public function cryptPassword($this, UserPasswordEncoderInterface $encoder)
    {
        $encoded = $encoder->encodePassword($this, $this->password); //on appelle la méthode de cryptage definie dans security.yaml
        $this->password = $encoded;
    } */

    /**
     * @see UserInterface
     */
    public function getSalt()
    {
        // not needed when using the "bcrypt" algorithm in security.yaml
    }

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

    public function  __toString()
    {
        return (string) '(Login : ' . $this->login . ')  /  ' . $this->nom . '  ' . $this->prenom;
    }

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

    public function getLogin(): ?string
    {
        return $this->login;
    }

    public function setLogin(string $login): self
    {
        $this->login = $login;

        return $this;
    }

    public function getNom(): ?string
    {
        return $this->nom;
    }

    public function setNom(string $nom): self
    {
        $this->nom = $nom;

        return $this;
    }

    public function getPrenom(): ?string
    {
        return $this->prenom;
    }

    public function setPrenom(string $prenom): self
    {
        $this->prenom = $prenom;

        return $this;
    }

    public function getTypePersonne(): ?array
    {
        return $this->type_personne;
    }

    public function setTypePersonne(array $type_personne): self
    {
        $this->type_personne = $type_personne;

        return $this;
    }

    public function getDateNaissance(): ?\DateTimeInterface
    {
        return $this->date_naissance;
    }

    public function setDateNaissance(\DateTimeInterface $date_naissance): self
    {
        $this->date_naissance = $date_naissance;

        return $this;
    }

    public function getSexe(): ?string
    {
        return $this->sexe;
    }

    public function setSexe(?string $sexe): self
    {
        $this->sexe = $sexe;

        return $this;
    }

    public function getStatusMarital(): ?string
    {
        return $this->status_marital;
    }

    public function setStatusMarital(?string $status_marital): self
    {
        $this->status_marital = $status_marital;

        return $this;
    }

    public function getLangueMaternelle(): ?string
    {
        return $this->langue_maternelle;
    }

    public function setLangueMaternelle(?string $langue_maternelle): self
    {
        $this->langue_maternelle = $langue_maternelle;

        return $this;
    }

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

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

        return $this;
    }

    public function getTelFixe(): ?string
    {
        return $this->tel_fixe;
    }

    public function setTelFixe(?string $tel_fixe): self
    {
        $this->tel_fixe = $tel_fixe;

        return $this;
    }

    public function getTelPortable(): ?string
    {
        return $this->tel_portable;
    }

    public function setTelPortable(?string $tel_portable): self
    {
        $this->tel_portable = $tel_portable;

        return $this;
    }

    public function getFax(): ?string
    {
        return $this->fax;
    }

    public function setFax(?string $fax): self
    {
        $this->fax = $fax;

        return $this;
    }

    public function getLangue(): ?string
    {
        return $this->langue;
    }

    public function setLangue(string $langue): self
    {
        $this->langue = $langue;

        return $this;
    }

    public function getAdresse(): ?Adresse
    {
        return $this->adresse;
    }

    public function setAdresse(?Adresse $adresse): self
    {
        // unset the owning side of the relation if necessary
        if ($adresse === null && $this->adresse !== null) {
            $this->adresse->setPersonne(null);
        }

        // set the owning side of the relation if necessary
        if ($adresse !== null && $adresse->getPersonne() !== $this) {
            $adresse->setPersonne($this);
        }

        $this->adresse = $adresse;

        return $this;
    }

    /**
     * @return Collection|RendezVous[]
     */
    public function getRendezVous(): Collection
    {
        return $this->rendezVous;
    }

    public function addRendezVous(RendezVous $rendezVous): self
    {
        if (!$this->rendezVous->contains($rendezVous)) {
            $this->rendezVous[] = $rendezVous;
            $rendezVous->setPersonnes($this);
        }

        return $this;
    }

    public function removeRendezVous(RendezVous $rendezVous): self
    {
        if ($this->rendezVous->removeElement($rendezVous)) {
            // set the owning side to null (unless already changed)
            if ($rendezVous->getPersonnes() === $this) {
                $rendezVous->setPersonnes(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|SignalementAbus[]
     */
    public function getSignalementAuteurAbus(): Collection
    {
        return $this->signalementAuteurAbus;
    }

    public function addSignalementAuteurAbu(SignalementAbus $signalementAuteurAbu): self
    {
        if (!$this->signalementAuteurAbus->contains($signalementAuteurAbu)) {
            $this->signalementAuteurAbus[] = $signalementAuteurAbu;
            $signalementAuteurAbu->setPersonneDesignee($this);
        }

        return $this;
    }

    public function removeSignalementAuteurAbu(SignalementAbus $signalementAuteurAbu): self
    {
        if ($this->signalementAuteurAbus->removeElement($signalementAuteurAbu)) {
            // set the owning side to null (unless already changed)
            if ($signalementAuteurAbu->getPersonneDesignee() === $this) {
                $signalementAuteurAbu->setPersonneDesignee(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|SignalementAbus[]
     */
    public function getSignalementDenonciateurAbus(): Collection
    {
        return $this->signalementDenonciateurAbus;
    }

    public function addSignalementDenonciateurAbus(SignalementAbus $signalementDenonciateurAbus): self
    {
        if (!$this->signalementDenonciateurAbus->contains($signalementDenonciateurAbus)) {
            $this->signalementDenonciateurAbus[] = $signalementDenonciateurAbus;
            $signalementDenonciateurAbus->setPersonneDesignant($this);
        }

        return $this;
    }

    public function removeSignalementDenonciateurAbus(SignalementAbus $signalementDenonciateurAbus): self
    {
        if ($this->signalementDenonciateurAbus->removeElement($signalementDenonciateurAbus)) {
            // set the owning side to null (unless already changed)
            if ($signalementDenonciateurAbus->getPersonneDesignant() === $this) {
                $signalementDenonciateurAbus->setPersonneDesignant(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|Conversation[]
     */
    public function getFairePost(): Collection
    {
        return $this->faire_post;
    }

    public function addFairePost(Conversation $fairePost): self
    {
        if (!$this->faire_post->contains($fairePost)) {
            $this->faire_post[] = $fairePost;
            $fairePost->setPersonne($this);
        }

        return $this;
    }

    public function removeFairePost(Conversation $fairePost): self
    {
        if ($this->faire_post->removeElement($fairePost)) {
            // set the owning side to null (unless already changed)
            if ($fairePost->getPersonne() === $this) {
                $fairePost->setPersonne(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|Video[]
     */
    public function getVideos(): Collection
    {
        return $this->videos;
    }

    public function addVideo(Video $video): self
    {
        if (!$this->videos->contains($video)) {
            $this->videos[] = $video;
            $video->setPersonne($this);
        }

        return $this;
    }

    public function removeVideo(Video $video): self
    {
        if ($this->videos->removeElement($video)) {
            // set the owning side to null (unless already changed)
            if ($video->getPersonne() === $this) {
                $video->setPersonne(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|Photo[]
     */
    public function getPhotos(): Collection
    {
        return $this->photos;
    }

    public function addPhoto(Photo $photo): self
    {
        if (!$this->photos->contains($photo)) {
            $this->photos[] = $photo;
            $photo->setPersonne($this);
        }

        return $this;
    }

    public function removePhoto(Photo $photo): self
    {
        if ($this->photos->removeElement($photo)) {
            // set the owning side to null (unless already changed)
            if ($photo->getPersonne() === $this) {
                $photo->setPersonne(null);
            }
        }

        return $this;
    }

    /**
     * @return Collection|Config[]
     */
    public function getConfig(): Collection
    {
        return $this->config;
    }

    public function addConfig(Config $config): self
    {
        if (!$this->config->contains($config)) {
            $this->config[] = $config;
            $config->addPersonne($this);
        }

        return $this;
    }

    public function removeConfig(Config $config): self
    {
        if ($this->config->removeElement($config)) {
            $config->removePersonne($this);
        }

        return $this;
    }
}

`security:
enable_authenticator_manager: false

encoders:
   App\Entity\Personne:
      algorithm: bcrypt
   App\Controller\Admin\PersonneCrudController:
      algorithm: bcrypt

providers:
    users_in_memory: { memory: ~ }
    users:
       entity: 
          class: App\Entity\Personne     # the class of the entity that represents users
          property: login                # the property to query by - e.g. username, email, etc  # used to reload user from session & other features (e.g. switch_user)
    app_user_provider:
        entity:
            class: App\Entity\Personne
            property: login
    # used to reload user from session & other features (e.g. switch_user)

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false

    main:
        anonymous: false
        lazy: true
        provider: users

        form_login:
           login_path: login
           check_path: login

        logout:
            path: app_logout  # where to redirect after logout # target: app_any_route
        guard:
            authenticators:
                - App\Security\AppLoginAdminAuthenticator
               # - App\Security\UserAuthenticator
            #entry_point: App\Security\UserAuthenticator

access_control:
    # require ROLE_ADMIN for /admin*
    - { path: '^/admin', roles: ROLE_ADMIN }
    `
<?php

namespace App\Controller\Admin;

use App\Entity\Personne;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
use EasyCorp\Bundle\EasyAdminBundle\Field\ChoiceField;
use EasyCorp\Bundle\EasyAdminBundle\Field\CollectionField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateField;
use EasyCorp\Bundle\EasyAdminBundle\Field\EmailField;
use EasyCorp\Bundle\EasyAdminBundle\Field\Field;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\IntegerField;
use EasyCorp\Bundle\EasyAdminBundle\Field\LanguageField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TelephoneField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextEditorField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoder;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;

class PersonneCrudController extends AbstractCrudController
{

    private $passwordEncoder;

    public function __construct(UserPasswordEncoderInterface $passwordEncoder)
    {
        $this->passwordEncoder = $passwordEncoder;
    }

    public static function getEntityFqcn(): string
    {
        return Personne::class;
    }

    public function configureCrud(Crud $crud): Crud
    {
        return $crud
            ->setEntityLabelInSingular('Personne')
            ->setEntityLabelInPlural('Personnes')
            ->setSearchFields([
                'id',
                'login',
                'password',
                'nom',
                'prenom',
                'type_personne',
                'date_naissance',
                'sexe',
                'status_marital',
                'langue_maternelle',
                'email',
                'tel_fixe',
                'tel_portable',
                'fax',
                'langue',
                'adresse',
            ])
            ->setDateTimeFormat('dd/M/yy hh:mm:ss')
            ->setDateFormat('d/m/y')
            ->setDefaultSort(
                [
                    'id' => 'ASC',
                    'login' => 'ASC',
                    'password' => 'ASC',
                    'nom' => 'ASC',
                    'prenom' => 'ASC',
                    'type_personne' => 'ASC',
                    'date_naissance' => 'ASC',
                    'sexe' => 'ASC',
                    'status_marital' => 'ASC',
                    'langue_maternelle' => 'ASC',
                    'email' => 'ASC',
                    'tel_fixe' => 'ASC',
                    'tel_portable' => 'ASC',
                    'fax' => 'ASC',
                    'langue' => 'ASC',
                    // 'adresse' => 'ASC' //!!!!!!! attention bug sur le tri des colonnes de jointure, surement en cas d'absence d'adresse !!!!!!!
                ]
            )
            ->showEntityActionsAsDropdown(true)
            ->setPaginatorPageSize(10);
    }

    public function configureFields(string $pageName): iterable
    {
        // id de la personne
        $id = IdField::new('id', 'ID')->hideOnForm();

        // Login de la personne
        $login = TextField::new('login', 'Login');

        // Roles dans symfony
        $roles = ChoiceField::new('roles', "ROLES SYNFONY")
            ->setChoices(['Administrateur (symfony)' => '{"ROLE":"ROLE_ADMIN"}', 'Utilisateur (symfony)' => '{"ROLE":"ROLE_USER"}'])
            ->allowMultipleChoices(true);

        // Password de la personne
        $password = TextField::new('plain_password', 'Mot de passe (crypté BDD, algo : bcrypt)')
            ->setFormType(PasswordType::class)
            ->setRequired($pageName === Crud::PAGE_NEW)
            ->onlyOnForms();

        // Nom de la personne
        $nom = TextField::new('nom', 'Nom');

        // Pernom de la personne
        $prenom = TextEditorField::new('prenom', 'Prenom');

        // Type de Personne de la personne
        //$typePersonneBDD = TextField::new('type_personne', 'Type Personne');
        $typePersonne = ChoiceField::new('type_personne', 'Type Personne')->setChoices(['Utilisateur' => 'U', 'Administrateur' => 'A'])
            ->allowMultipleChoices(true);

        // Date de naissance de la personne
        $dateNaissance = DateField::new('date_naissance', 'Date De Naissance');

        // Sexe de la personne
        $sexe = ChoiceField::new('sexe', 'Sexe')->setChoices(['Homme' => 'H', 'Femme' => 'F']);

        // Status Marital de la personne
        $statusMarital = ChoiceField::new('status_marital', 'Status Marital')->setChoices(['Célibataire' => 'U', 'En couple' => 'C', 'Marié' => 'M', 'Divorcé' => 'D', 'Veuf/Veuve' => 'V']);

        // Langue maternele de la personne
        $langueMaternelle = ChoiceField::new('langue_maternelle', 'Langue Maternelle')->setChoices(['Français' => 'FR', 'Anglais' => 'EN', 'Espagnol' => 'ES', 'Italien' => 'IT', 'Allemand' => 'DE']);

        // Adresse email de la personne
        $email = EmailField::new('email', 'Adresse Email');

        // Telephone fixe de la personne
        $telFixe = TelephoneField::new('tel_fixe', 'Telephone Fixe');

        // Telephone portable de la personne
        $telPortable = TelephoneField::new('tel_portable', 'Telephone Portable');

        // Fax de la personne
        $fax = TextField::new('fax', 'Fax');

        // Langue de la personne
        $langue = ChoiceField::new('langue', 'Langue')->setChoices(['Français' => 'FR', 'Anglais' => 'EN', 'Espagnol' => 'ES', 'Italien' => 'IT', 'Allemand' => 'DE']);

        // Assosiation adresse id
        $adresse = AssociationField::new('adresse', 'Adresse');

        // Affichage CRUD de la classe Personne

        if (Crud::PAGE_INDEX === $pageName) {
            return [$id, $login, $roles,  $password, $nom, $prenom, $typePersonne, $dateNaissance, $sexe, $statusMarital, $langueMaternelle, $email, $telFixe, $telPortable, $fax, $langue, $adresse];
        } elseif (Crud::PAGE_DETAIL === $pageName) {
            return [$id, $login, $roles,  $password, $nom, $prenom, $typePersonne, $dateNaissance, $sexe, $statusMarital, $langueMaternelle, $email, $telFixe, $telPortable, $fax, $langue, $adresse];
        } elseif (Crud::PAGE_NEW === $pageName) {
            return [$id, $login, $roles, $password, $nom, $prenom, $typePersonne, $dateNaissance, $sexe, $statusMarital, $langueMaternelle, $email, $telFixe, $telPortable, $fax, $langue];
        } elseif (Crud::PAGE_EDIT === $pageName) {
            return [$id, $login, $roles, $password, $nom, $prenom, $typePersonne, $dateNaissance, $sexe, $statusMarital, $langueMaternelle, $email, $telFixe, $telPortable, $fax, $langue];
        }
    }

    public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
    {
        $this->encodePassword($entityInstance);
        parent::persistEntity($entityManager, $entityInstance);
    }

    public function updateEntity(EntityManagerInterface $entityManager, $entityInstance): void
    {
        $this->encodePassword($entityInstance);
        parent::updateEntity($entityManager, $entityInstance);
    }

    private function encodePassword(Personne $personne)
    {
        if ($personne->getPassword() !== null) {
            //$user->setSalt(base_convert(bin2hex(random_bytes(20)), 16, 36));
            // This is where you use UserPasswordEncoderInterface
            $personne->setPassword($this->passwordEncoder->encodePassword($personne, $personne->getPlainPassword()));
        }
    }
}

To conclude, do you have any ideas for this bug #4165 ? (ChoiceField in a JSON DC2Type in Database doesn't work)

vic-blt commented 3 years ago
    private function encodePassword(Personne $personne)
    {
        if ($personne->getPassword() !== null) {
            //$user->setSalt(base_convert(bin2hex(random_bytes(20)), 16, 36));
            // This is where you use UserPasswordEncoderInterface
            $personne->setPassword($this->passwordEncoder->encodePassword($personne, $personne->getPlainPassword()));
        }
    }

Your if condition is wrong, you need to check if plainPassword is not null then you encrypt and persist the password.

this is the error when the password field is empty on submitting ....

As plainPassword can be null, you have to use a nullable type

    /**
     * @param string $plainPassword
     */
    public function setPlainPassword(?string $plainPassword)
    {
        $this->plainPassword = $plainPassword;
    }
Sananda-KUMARA commented 3 years ago

ok, I hadn't seen it, and it works. I still have a problem with the "roles" field of my entity, the values ​​in the database are not filled in when the form is loaded : in the database it is JSON.

I noticed that you use an array type and I use a json type (auto generated), do you know the best practice for this type of field?

image

bug #4165 (ChoiceField in a JSON DC2Type in Database doesn't work)

vic-blt commented 3 years ago

The variable roles is a simple array, hence no need of json here. Use the methods of my entity addRole and removeRole. In the CRUD controller, set roles :

ChoiceField::new('roles', 'Roles')
     ->setChoices(User::ROLES)
     ->allowMultipleChoices(true);
Sananda-KUMARA commented 3 years ago

ok, it's works ! thanks a lot. I close this bug ...