0
votes

How can I store roles in DB? I tried this method http://blog.jmoz.co.uk/symfony2-fosuserbundle-role-entities/

USER.php

/**
 * @ORM\Entity
 * @ORM\Table(name="`user`")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * @ORM\OneToMany(targetEntity="Post", mappedBy="author")
     */
    public $article;

    /**
     * @var string
     *
     * @ORM\Column(name="full_name", type="string", length=255, nullable=true)
     */
    public $name;

    /**
     * @ORM\ManyToMany(targetEntity="Role")
     * @ORM\JoinTable(name="users_roles")
     */
    protected $roles;

    public function __construct()
    {
        parent::__construct();
        $this->roles = new ArrayCollection();
    }

    ....settings...

    /**
     * Returns an ARRAY of Role objects with the default Role object appended.
     * @return array
     */
    public function getRoles()
    {
        return array_merge($this->roles->toArray(), array(new Role(parent::ROLE_DEFAULT)));
    }

    /**
     * Returns the true ArrayCollection of Roles.
     * @return ArrayCollection
     */
    public function getRolesCollection()
    {
        return $this->roles;
    }

    /**
     * Pass a string, get the desired Role object or null.
     * @param string $role
     * @return Role|null
     */
    public function getRole($role)
    {
        foreach ($this->getRoles() as $roleItem) {
            if ($role == $roleItem->getRole()) {
                return $roleItem;
            }
        }
        return null;
    }

    /**
     * Pass a string, checks if we have that Role. Same functionality as getRole() except returns a real boolean.
     * @param string $role
     * @return boolean
     */
    public function hasRole($role)
    {
        if ($this->getRole($role)) {
            return true;
        }
        return false;
    }

    /**
     * Adds a Role OBJECT to the ArrayCollection. Can't type hint due to interface so throws Exception.
     * @throws Exception
     * @param Role $role
     */
    public function addRole($role)
    {
        if (!$role instanceof Role) {
            throw new \Exception("addRole takes a Role object as the parameter");
        }

        if (!$this->hasRole($role->getRole())) {
            $this->roles->add($role);
        }
    }

    /**
     * Pass a string, remove the Role object from collection.
     * @param string $role
     */
    public function removeRole($role)
    {
        $roleElement = $this->getRole($role);
        if ($roleElement) {
            $this->roles->removeElement($roleElement);
        }
    }

    /**
     * Pass an ARRAY of Role objects and will clear the collection and re-set it with new Roles.
     * Type hinted array due to interface.
     * @param array $roles Of Role objects.
     */
    public function setRoles(array $roles)
    {
        $this->roles->clear();
        foreach ($roles as $role) {
            $this->addRole($role);
        }
    }

    /**
     * Directly set the ArrayCollection of Roles. Type hinted as Collection which is the parent of (Array|Persistent)Collection.
     * @param Collection $role
     */
    public function setRolesCollection(Collection $collection)
    {
        $this->roles = $collection;
    }
}

ROLE.php

/**
 * Role Entity
 *
 * @ORM\Entity
 * @ORM\Table(name="roles")
 */
class Role implements RoleInterface
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer", name="id")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;
    /**
     * @ORM\Column(type="string", name="role", unique=true, length=70)
     */
    private $role;

    /**
     * Populate the role field
     * @param string $role ROLE_FOO etc
     */
    public function __construct($role)
    {
        $this->role = $role;
    }

    /**
     * Return the role field.
     * @return string
     */
    public function getRole()
    {
        return $this->role;
    }

    /**
     * Return the role field.
     * @return string
     */
    public function __toString()
    {
        return (string)$this->role;
    }
}

I'm always getting this error.

[Doctrine\ORM\Mapping\MappingException]
Property "roles" in "***\Entity\User" was already declared, but it must be declared only once

Could someone help me please?

Thanks

1
you are following an out dated article, find the latest article on FosUserBundle and follow that. The bundle supports role out of the box you should not be defining it anywhere.Shairyar
That's the problem, I can't find latest articles, almost everyone linking to that out dated one.user3703456
Then share your Entity so people can have a look and helpShairyar
Done, hope someone will help :)user3703456

1 Answers

0
votes

You need to get rid of everything related to roles inside your User Entity. Roles are supported by the bundle out of the box.

I just setup the bundle and everything is working fine. This is what my User Entity looks like which extends the BaseUser

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Model\User as BaseUser;
/**
 * User
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 */
class User extends BaseUser
{
    /**
     * @var int
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;
    public function __construct()
    {
        parent::__construct();
        // your own logic
    }

    /**
     * Get id
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

}

Once the bundle was setup, I ran the schema update command.

As you can see the roles column is added automatically via the bundle.

enter image description here

You can play around with bundle using the command is comes with to create the user.

The documentation of the bundle can be found here. Here is another good resource to get you started.