Symfony / Doctrine / аутентификация, я не могу восстановить роли - PullRequest
0 голосов
/ 12 февраля 2020

У меня проблема, когда я хочу подключиться. Позвольте мне объяснить, у меня есть две сущности User и Role, которые связаны с отношением ManyToMany, поэтому у меня есть динамическая таблица c user_role. Я хотел бы связаться с пользователем, у которого есть ROLE_ADMIN, но проблема в том, что я не могу прочитать объект, чтобы он читал эту роль. Это показывает мне эту ошибку.

Предупреждение: недопустимый тип смещения в isset или пусто

Я думаю, что проблема исходит из строки "$ role = $ this-> role-> toArray ();» в getRoles.

Вот код для пользователя. php

class User implements UserInterface, \Serializable
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

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

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

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

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

    /**
     * @ORM\ManyToMany(targetEntity="Role", inversedBy="users", fetch="LAZY")
     * @ORM\JoinTable(name="user_role",
     *     joinColumns={
     *      @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORM\JoinColumn(name="role_id", referencedColumnName="id")
     *   }
     *  )
     */
    private $role;

    public function __construct()
    {
        //$this->repository = $repository;
        $this->role = new ArrayCollection();
        //$this->roles = new Role();
    }

    /**
     * Add userRoles
     *
     * @param \App\Entity\Role $roles
     * @return User
     */
    public function addRoles(\App\Entity\Role $role)
    {
        $this->role[] = $role;

        return $this;
    }


    /**
     * Remove userRoles
     *
     * @param \App\Entity\Role $roles
     */
    public function removeRoles(\App\Entity\Role $role)
    {
        $this->role->removeElement($role);
    }

    /**
     * Get Role
     */
    public function getRoles() : array //Role return
    {
        //$role = $this->repository->find($this->getId());
        //$role = $role->getName();
        $role = $this->role->toArray();

        //$roles = ['ROLE_ADMIN'];
        //$role = $this->serialize($role);
        var_dump($role);
        //$role = $role[0]['name'];

        if (empty($role)) {
            $role[] = ['ROLE_ADMIN'];
        }
        return array_unique($role);
    }

    public function setRoles($role): self
    {
        //$this->roles = $roles;
        if (is_array($role)) {
            $this->role = $role;
        } else {
            $this->role->clear();
            $this->role->add($role);
        }
        return $this;
    }

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

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

    public function setUsername(string $username): self
    {
        $this->username = $username;

        return $this;
    }




    /**
     * @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 getIsActive(): ?bool
    {
        return $this->isActive;
    }

    public function setIsActive(bool $isActive): self
    {
        $this->isActive = $isActive;

        return $this;
    }

    public function getToken(): ?string
    {
        return $this->token;
    }

    public function setToken(string $token): self
    {
        $this->token = $token;

        return $this;
    }

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

    public function setExpiresAt(\DateTimeInterface $expiresAt): self
    {
        $this->expiresAt = $expiresAt;

        return $this;
    }

    public function isExpired(): bool
    {
        return $this->getExpiresAt() <= new \DateTime();
    }

    public function createToken()
    {
        return substr(str_replace(['+', '/'], ['-', '_'], base64_encode(random_bytes(50))), 0, 63);
    }


    /**
     * String representation of object
     * @link https://php.net/manual/en/serializable.serialize.php
     * @return string the string representation of the object or null
     * Transform object to string
     */
    public function serialize()
    {
        return serialize([
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            $this->token,
            $this->expiresAt
        ]);
    }

    /**
     * @param string $serialized
     * Transform string to object
     */
    public function unserialize($serialized)
    {
        list(
            $this->id,
            $this->username,
            $this->password,
            $this->isActive,
            $this->token,
            $this->expiresAt
            ) = unserialize($serialized, ['allowed_classes' => false]);
    }

}

А вот код для роли. php

class Role implements \Serializable
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

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

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

    /**
     * @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
     */
    private $users;

    public function __construct()
    {
        $this->users = new ArrayCollection();
    }

    public function getUsers()
    {
        return $this->users;
    }

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

    public function getRole(): ?string
    {
        return $this->role;
    }

    public function setRole($role)
    {
        $this->role = $role;

        return $this;
    }

    public function getDescription(): ?string
    {
        return $this->description;
    }

    public function setDescription(string $description): self
    {
        $this->description = $description;

        return $this;
    }

    /*
    * methods for RoleInterface
    */
    /*public function getRoles()
    {
        return $this->getRole();
    }*/

    /**
     * Add users
     *
     * @param \App\Entity\User $users
     * @return Role
     */
    public function addUser(\App\Entity\User $users)
    {
        $this->users[] = $users;

        return $this;
    }

    /**
     * Remove users
     *
     * @param \App\Entity\User $users
     */
    public function removeUser(App\Entity\User $users)
    {
        $this->users->removeElement($users);
    }



    /**
     * String representation of object
     * @link https://php.net/manual/en/serializable.serialize.php
     * @return string the string representation of the object or null
     * Transform object to string
     */
    public function serialize()
    {
        return serialize([
            $this->id,
            $this->role,
            $this->description
        ]);
    }

    /**
     * @param string $serialized
     * Transform string to object
     */
    public function unserialize($serialized)
    {
        list(
            $this->id,
            $this->role,
            $this->description
            ) = unserialize($serialized, ['allowed_classes' => false]);
    }
}

затем в моем контроллере я нашел findAll

/**
* @Route("/admin/user", name="admin_user_index")
* @return \Symfony\Component\HttpFoundation\Response
*/
public function listUser(UserRepository $user)
{
return $this->render('admin/security_user/list_user.html.twig', ['user' => $user->findAll()]);
}

var_dump ($ role)

/var/www/api/symfony/src/Entity/User.php:108:
array (size=1)
  0 => 
    object(App\Entity\Role)[423]
      private 'id' => int 2
      private 'role' => string '['ROLE_ADMIN']' (length=14)
      private 'description' => string 'administrateur' (length=14)
      private 'users' => 
        object(Doctrine\ORM\PersistentCollection)[425]
          private 'snapshot' => 
            array (size=0)
              ...
          private 'owner' => 
            &object(App\Entity\Role)[423]
          private 'association' => 
            array (size=16)
              ...
          private 'em' => 
            object(Doctrine\ORM\EntityManager)[205]
              ...
          private 'backRefFieldName' => string 'roles' (length=5)
          private 'typeClass' => 
            object(Doctrine\ORM\Mapping\ClassMetadata)[262]
              ...
          private 'isDirty' => boolean false
          protected 'collection' => 
            object(Doctrine\Common\Collections\ArrayCollection)[426]
              ...
          protected 'initialized' => boolean false

Вот код списка пользователей:

{% extends '/admin/base_admin.html.twig' %}

{% block style %}
    <style>
        h1#titlelist{
            float: left;
        }
        button#edit {
            float: right;
        }
        button#create{
            float: right;
            margin-left: 15px;
        }
    </style>
{% endblock %}

{% block logout %}
    <a style="color: grey" href="{{ path('security_logout') }}">Deconnexion</a>
{% endblock %}

{% block body %}
    <br /><br />
    <h1 id="titlelist" class="h3 mb-3 font-weight-normal">Liste des utilisateurs</h1>
    {% for message in app.flashes('success') %}
        <div class="alert alert-success">
            {{ message }}
        </div>
    {% endfor %}
    <a href="{{ path('admin_index') }}">
        <button id="create" class="btn btn-lg btn-primary">
            Annuler
        </button>
    </a>
    <a href="{{ path('admin_user_create') }}">
        <button id="create" class="btn btn-lg btn-primary">
            Ajouter
        </button>
    </a>

    <br />
    <br />
    <br />
    <TABLE  class="table table-striped">
        <thead>
        <TR>
            <TH>ID</TH>
            <TH>Utilisateur</TH>
            <TH>Password</TH>
            <TH>Rôles</TH>
            <TH>Actif</TH>
            <TH>Editer</TH>
        </TR>
        </thead>
        <tbody>
        {% for list in user %}
            <TR>
                <TD>{{ list.id }}</TD>
                <TD>{{ list.username }}</TD>
                <TD>{{ list.password }}</TD>
                <TD>
                    {% for role in list.roles %}
                        {{ role.name }},
                    {% endfor %}
                </TD>
                <TD>{{ list.isActive }}</TD>

                <TD>
                    <a href="{{ path('admin_user_edit', {id: list.id}) }}" class="btn btn-primary">Editer</a>
                    <form method="post" action="{{ path('admin_user_delete', {id: list.id}) }}" style="display: inline-block"
                          onsubmit="return confirm('Voulez-vous vraiment supprimer l\'utilisateur ?')">
                        <input type="hidden" name="_method" value="DELETE">
                        <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ list.id) }}">
                        <button class="btn btn-primary">Supprimer</button>
                    </form>
                </TD>
            </TR>
        {% endfor %}
        </tbody>
    </TABLE>
{% endblock %}

Я бы хотел бы получить хранилище ролей в таблице ролей.

Если кто-то из вас сможет меня просветить, заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2020

Для тех, кто хочет добавить несколько ролей для модулей, например

public function getRoles() : array //Role return
    {
        $role = [];
        $name = [];
        $roles = $this->roles;

        $tab = $roles->toArray();
        dump($tab);
        $longTab = count($tab);

        for ($i = 0; $i < $longTab; $i++){
            $role[] = $roles->get($i)->getRole();
            $name[] = $roles->get($i)->getName();
        }

        $role = [$role, $name];

        if (empty($roles)){
            $role = ['ROLE_USER'];
        }
        return $role;
    }
0 голосов
/ 17 февраля 2020

С небольшой помощью, вот решение

/**
 * Get Role
 * @return array
 */
public function getRoles() : array
{
    $roles = $this->roles;
    $name = $roles;
    $name = $name->first()->getName();

    $roles = $roles->first()->getRole();
    $roles = [$roles, $name];

    //dump($roles);
    if (empty($roles)){
        $roles = ['ROLE_USER'];
    }
    return $roles;
}

И код для ветки

{% for list in user %}
        <TR>

            <TD>{{ list.id }}</TD>
            <TD>{{ list.username }}</TD>
            <TD>{{ list.password }}</TD>
            <TD>{{ list.roles[1] }}</TD>
            <TD>{{ list.isActive }}</TD>

            <TD>
                <a href="{{ path('admin_user_edit', {id: list.id}) }}" class="btn btn-primary">Editer</a>
                <form method="post" action="{{ path('admin_user_delete', {id: list.id}) }}" style="display: inline-block"
                      onsubmit="return confirm('Voulez-vous vraiment supprimer l\'utilisateur ?')">
                    <input type="hidden" name="_method" value="DELETE">
                    <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ list.id) }}">
                    <button class="btn btn-primary">Supprimer</button>
                </form>
            </TD>
        </TR>
    {% endfor %}
...