Skip to content
Advertisement

Symfony/Doctrine/authentication, I can’t recover the roles

I have a problem when i want to connect. Let me explain, I have two User and Role entities that are linked to a ManyToMany relationship, so I have a dynamic user_role table. I would like to connect with the user who has the ROLE_ADMIN but the problem is that I cannot read the object so that it reads this role. This shows me this error.

Warning: Illegal offset type in isset or empty

I think the problem comes from the line “$ role = $ this-> roles-> toArray ();” in getRoles.

Here is the code for User.php

class User implements UserInterface, Serializable
{
    /**
     * @ORMId()
     * @ORMGeneratedValue()
     * @ORMColumn(type="integer")
     */
    private $id;

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

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

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

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

    /**
     * @ORMColumn(type="datetime")
     */
    private $expiresAt;

    /**
     * @ORMManyToMany(targetEntity="Role", inversedBy="users", fetch="LAZY")
     * @ORMJoinTable(name="user_role",
     *     joinColumns={
     *      @ORMJoinColumn(name="user_id", referencedColumnName="id")
     *   },
     *   inverseJoinColumns={
     *     @ORMJoinColumn(name="role_id", referencedColumnName="id")
     *   }
     *  )
     */
    private $role;

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

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

        return $this;
    }


    /**
     * Remove userRoles
     *
     * @param AppEntityRole $roles
     */
    public function removeRoles(AppEntityRole $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]);
    }

}

And here is the code for Role.php

class Role implements Serializable
{
    /**
     * @ORMId()
     * @ORMGeneratedValue()
     * @ORMColumn(type="integer")
     */
    private $id;

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

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

    /**
     * @ORMManyToMany(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 AppEntityUser $users
     * @return Role
     */
    public function addUser(AppEntityUser $users)
    {
        $this->users[] = $users;

        return $this;
    }

    /**
     * Remove users
     *
     * @param AppEntityUser $users
     */
    public function removeUser(AppEntityUser $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]);
    }
}

then in my controller I did a findAll

/**
* @Route("/admin/user", name="admin_user_index")
* @return SymfonyComponentHttpFoundationResponse
*/
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(AppEntityRole)[423]
      private 'id' => int 2
      private 'role' => string '['ROLE_ADMIN']' (length=14)
      private 'description' => string 'administrateur' (length=14)
      private 'users' => 
        object(DoctrineORMPersistentCollection)[425]
          private 'snapshot' => 
            array (size=0)
              ...
          private 'owner' => 
            &object(AppEntityRole)[423]
          private 'association' => 
            array (size=16)
              ...
          private 'em' => 
            object(DoctrineORMEntityManager)[205]
              ...
          private 'backRefFieldName' => string 'roles' (length=5)
          private 'typeClass' => 
            object(DoctrineORMMappingClassMetadata)[262]
              ...
          private 'isDirty' => boolean false
          protected 'collection' => 
            object(DoctrineCommonCollectionsArrayCollection)[426]
              ...
          protected 'initialized' => boolean false

Here is the user list code:

{% 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 %}

I would like to retrieve the role store in the role table.

If any of you can enlighten me, thank you in advance.

Advertisement

Answer

With little help, Here is the solution

/**
 * 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;
}

And the code for the twig

{% 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 %}
User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement