Управление ролями в базе данных - PullRequest
1 голос
/ 05 апреля 2020

В Symfony 5 у меня возникают трудности с управлением ролями в базе данных. Моя цель, наконец, получить соответствующую роль, спросив

У меня есть объект Profil, связанный с базой данных с некоторыми логическими полями, которые определены для указания c доступа:

$this->isGranted('ROLE_ADMIN')

А также, определите иерархию, как описано в официальной документации .

Ниже мой Profil объект:

namespace App\Entity;

use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\ProfilRepository")
 * 
 * @UniqueEntity(fields="name", message="A profil with this name already exist.")
 */
class Profil
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

    /**
     * @ORM\Column(type="boolean")
     */
    private $editMetadatas;

    /**
     * @ORM\Column(type="boolean")
     */
    private $editVisas;

    /**
     * @ORM\Column(type="boolean")
     */
    private $isAdmin;

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

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getEditMetadatas(): ?bool
    {
        return $this->editMetadatas;
    }

    public function setEditMetadatas(bool $editMetadatas): self
    {
        $this->editMetadatas = $editMetadatas;

        return $this;
    }

    public function getIsAdmin(): ?bool
    {
        return $this->isAdmin;
    }

    public function setIsAdmin(bool $isAdmin): self
    {
        $this->isAdmin = $isAdmin;

        return $this;
    }

    public function __toString()
    {
        return $this->getName();
    }
}

Объект Profil связан с сущностью User через классическое отношение ManyToOne.

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use App\Entity\Profil;

/**
 * @ORM\Entity(repositoryClass="App\Repository\UserRepository")
 */
class User implements UserInterface
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

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

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

    /**
     * @ORM\Column(type="string", length=5, columnDefinition="ENUM('en_GB', 'fr_FR')", options={"default": "fr_FR"})
     */
    private $locale;

    /**
     * @ORM\Column(type="boolean", options={"default": false})
     */
    private $activated;

    /**
     * @ORM\Column(type="datetime")
     */
    private $lastConnected;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Profil", inversedBy="users")
     * @ORM\JoinColumn(nullable=false)
     */
    private $profil;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Company", inversedBy="users")
     * @ORM\JoinColumn(nullable=false)
     */
    private $company;

    private $roles = [];

    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 getUsername(): string
    {
        return (string) $this->email;
    }


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

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

        return $this;
    }

    /**
     * @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 getName(): ?string
    {
        return $this->name;
    }

    public function setName(string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getLocale(): ?string
    {
        return $this->locale;
    }

    public function setLocale(string $locale): self
    {
        $this->locale = $locale;
        return $this;
    }

    public function getActivated(): ?bool
    {
        return $this->activated;
    }

    public function setActivated(bool $activated): self
    {
        $this->activated = $activated;

        return $this;
    }

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

    public function setLastConnected(\DateTimeInterface $lastConnected): self
    {
        $this->lastConnected = $lastConnected;

        return $this;
    }

    public function getProfil(): ?profil
    {
        return $this->profil;
    }

    public function setProfil(?profil $profil): self
    {
        $this->profil = $profil;

        return $this;
    }

    public function getRoles(): array
    {
        $roles = $this->roles;
        if (empty($roles))
        {
            $roles = ['ROLE_USER'];
            if ($profil->getProfil()->getEditMetadatas()) array_push($roles, 'ROLE_METADATAS');
        }
        return array_unique($roles);
    }

    public function __toString()
    {
        return $this->getName();
    }
}

Что касается метода getRoles(), я думаю, что я не поступаю правильно, потому что я не могу получить данные о getRoles() функция по загрузке. getProfil, загруженный во время регистрации, отправляет обратно пустой массив, потому что он еще не загружен.

Я думаю, что это довольно распространенная особенность: как я должен предполагать загрузку данных Profil?

1 Ответ

0 голосов
/ 06 апреля 2020

Я наконец-то нашел решение, но не уверен, что оно лучшее.

public function getRoles(): array
{ 
    if (empty($this->roles)) {
        if ($this->getProfil()->getEditMetadatas()) $this->roles[] = 'ROLE_METADATAS';
    }
    $this->roles[] = 'ROLE_USER';
    return array_unique($this->roles);
}

Свойство roles определяется впервые. Свойство getProfil может правильно заполнить объект Profil. Это довольно удивительно, потому что я не понимаю, почему я получаю пустой массив с предыдущим кодом. Что бы это ни было, оно работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...