Simple process,
Need to create Users with mapped Roles.
I followed the step from link
http://symfony.com/doc/current/cookbook/security/entity_provider.html
User and Roles table generated but users_roles table is not generated in MySql...
Will i need to create it manually?
Second
I have configured with User table for Authentication
After login it redirects to Error page,
FatalErrorException: Error: Call to a member function toArray() on a non-object in /var/www/vibilling_3/src/ViBillingPortal/AuthenticationBundle/Entity/users.php line 130
I searched, but i cant find any solutions... Below my code
Bill/PortalBundle/Entity/users.php
namespace ViBillingPortal\AuthenticationBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* users
*/
class users implements UserInterface, \Serializable
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $username;
/**
* #var string
*/
private $password;
/**
* #var string
*/
private $created_date;
/**
* #ORM\ManyToMany(targetEntity="roles", inversedBy="users")
* #ORM\JoinTable(name="user_roles")
*/
private $userroles;
public function __construct()
{
$this->userroles = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
* #return users
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* #param string $password
* #return users
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set created_date
*
* #param string $created_date
* #return users
*/
public function setCreated_date($password)
{
$this->password = $created_date;
return $this;
}
/**
* Get Created_date
*
* #return string
*/
public function getCreated_date()
{
return $this->created_date;
}
/**
* Get Roles
*/
public function getRoles()
{
return $this->userroles->toArray();
}
/**
* #inheritDoc
*/
public function getSalt()
{
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
}
}
Bill/PortalBundle/Entity/roles.php
namespace ViBillingPortal\AuthenticationBundle\Entity;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* roles
*/
class roles implements RoleInterface, \Serializable
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $name;
/**
* #ORM\Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* #ORM\ManyToMany(targetEntity="users", mappedBy="userroles")
*/
protected $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return roles
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #see RoleInterface
*/
public function getRole()
{
return $this->role;
}
/**
* #see \Serializable::serialize()
*/
public function serialize()
{
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
}
}
You should use a ManyToMany relation, not a ManyToOne if you want to use a join table : http://docs.doctrine-project.org/en/2.0.x/reference/association-mapping.html#many-to-many-bidirectional
For the second error, it's strange as you initialize usersroles as an ArrayCollection in your construct method, it should work.
Could you add a var_dump to look what is stored in this property ?
Why don't you get any setter/getter for usersroles ?
I think you should also read Symfony coding standards : http://symfony.com/doc/current/contributing/code/standards.html. You coding style is not consistent.
Related
And Sorry I'm French :)
For my diploma I have to make a Tickets/Reports app and I'm stuck at the Doctrine mapping.
Clone project on GitHUB
Here is my 'Transaction.php' class:
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\TransactionRepository")
*/
class Transaction
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
************************** PROBLEM STARTS HERE *************************
/**
* #ORM\OneToOne(targetEntity="User")
*/
private $sender;
/**
* #ORM\OneToOne(targetEntity="User")
*/
private $receiver;
************************** PROBLEM ENDS HERE *************************
/**
* #ORM\Column(type="integer")
*/
private $amount;
/**
* #ORM\Column(type="datetime",nullable=true)
*/
private $date;
/**
* #ORM\Column(type="text")
*/
private $comment;
/**
* #return mixed
*/
public function getComment()
{
return $this->comment;
}
/**
* #param mixed $comment
*/
public function setComment($comment): void
{
$this->comment = $comment;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #return mixed
*/
public function getSender()
{
return $this->sender;
}
/**
* #param mixed $sender
*/
public function setSender($sender): void
{
$this->sender = $sender;
}
/**
* #return mixed
*/
public function getReceiver()
{
return $this->receiver;
}
/**
* #param mixed $receiver
*/
public function setReceiver($receiver): void
{
$this->receiver = $receiver;
}
/**
* #return mixed
*/
public function getAmount()
{
return $this->amount;
}
/**
* #param mixed $amount
*/
public function setAmount($amount): void
{
$this->amount = $amount;
}
/**
* #return mixed
*/
public function getDate()
{
return $this->date;
}
/**
* #param mixed
*/
public function setDate()
{
$this->date = new \DateTime("now");
}
}
And my 'User.php' class
<?php
// src/Entity/User.php
namespace App\Entity;
use App\Repository\TransactionRepository;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Validator\Constraints as Assert;
/**
* #ORM\Entity
* #UniqueEntity(fields="email", message="Email already taken")
* #UniqueEntity(fields="username", message="Username already taken")
*/
class User implements UserInterface
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=255, unique=true)
* #Assert\NotBlank()
* #Assert\Email()
*/
private $email;
/**
* #ORM\Column(type="string", length=255, unique=true)
* #Assert\NotBlank()
*/
private $username;
/**
* #Assert\NotBlank()
* #Assert\Length(max=4096)
*/
private $plainPassword;
/**
* The below length depends on the "algorithm" you use for encoding
* the password, but this works well with bcrypt.
*
* #ORM\Column(type="string", length=64)
*/
private $password;
/**
* #var Monycks
*/
private $monycks = 10000;
/**
* #var Skill
* #ORM\ManyToOne(targetEntity="Skill",inversedBy="users")
*/
private $skill;
/**
* #return Skill
*/
public function getSkill()
{
return $this->skill;
}
/**
* #param mixed $skill
*/
public function setSkill(Skill $skill): void
{
$this->skill = $skill;
$skill->addUser($this);
}
/**
* #return Monycks
*/
public function getMonycks()
{
return $this->monycks;
}
/**
* #param Monycks $monycks
*/
public function setMonycks($monycks): void
{
$this->monycks = $monycks;
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
// other properties and methods
public function getEmail()
{
return $this->email;
}
public function setEmail($email)
{
$this->email = $email;
}
public function getUsername()
{
return $this->username;
}
public function setUsername($username)
{
$this->username = $username;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function setPlainPassword($password)
{
$this->plainPassword = $password;
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password)
{
$this->password = $password;
}
public function getSalt()
{
// The bcrypt algorithm doesn't require a separate salt.
// You *may* need a real salt if you choose a different encoder.
return null;
}
public function getRoles()
{
if($this->getUsername()=='admin')
return array('ROLE_ADMIN', 'ROLE_USER');
return array('ROLE_USER');
}
public function eraseCredentials()
{
}
/** #see \Serializable::serialize() */
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt,
));
}
/** #see \Serializable::unserialize() */
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized);
}
public function isSender()
{
return $this->getId();
}
public function isReceiver()
{
return $this->getId();
}
}
My problem is that Users can have multiple Transactions as sender or receiver an Transaction have at least 2 user (Send & receive)
With this config, I can add one transaction for each user....
I still do not manage very well Doctrine relation yet...
So somedy can EXPLAIN me how to do the tricks and how it works....
Clone project on GitHUB
I finaly found a workinf solution but I don't now if it's the right way to do
it...
I make a contrustor with two ArrayCollection(); in my User.php class and I put users_id into.
And in my Transaction.php class #ORM\JoinColumn
In my 'Transaction.php' class I put:
Everything is working now, but I don't really understand what's appened...
Someone can explain me correctly what was the problem .??
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="senders")
* #ORM\JoinColumn(nullable=true)
*/
private $sender;
/**
* #ORM\ManyToOne(targetEntity="User", inversedBy="receivers")
* #ORM\JoinColumn(nullable=true)
*/
private $receiver;
public function getSender()
{
return $this->sender;
}
public function setSender(User $user)
{
$this->sender = $user;
}
public function getReceiver()
{
return $this->receiver;
}
public function setReceiver(User $user)
{
$this->receiver = $user;
}
And in my 'User.php' class:
/**
* #ORM\OneToMany(targetEntity="Transaction", mappedBy="receiver")
*/
private $receivers;
/**
* #ORM\OneToMany(targetEntity="Transaction", mappedBy="receiver")
*/
private $receivers;
/**
* #ORM\OneToMany(targetEntity="Transaction", mappedBy="sender")
*/
private $senders;
public function __construct()
{
$this->senders = new ArrayCollection();
$this->receivers = new ArrayCollection();
}
/**
* #return Collection|Transaction[]
*/
public function getReceivers()
{
return $this->receivers;
}
/**
* #return Collection|Transaction[]
*/
public function getSenders()
{
return $this->senders;
}
i have a big problem implementing JWT Tokens on symfony.
I already make work the JWT token, but i need to add to the token info the User roles too. i am doing this using a Listener (JWTCreatedListener):
public function onJWTCreated(JWTCreatedEvent $event)
{
$request = $this->requestStack->getCurrentRequest();
$payload = $event->getData();
$payload['ip'] = $request->getClientIp();
$payload['roles'] = $event->getUser()->getRoles();
$event->setData($payload);
}
I implemented the Role.php (AppBundle/Entity/Role.php) on this way:
<?php
namespace AppBundle\Entity;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="acme_role")
* #ORM\Entity()
*/
class Role implements RoleInterface
{
/**
* #ORM\Column(name="id", type="integer")
* #ORM\Id()
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="name", type="string", length=30)
*/
private $name;
/**
* #ORM\Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* #ORM\ManyToMany(targetEntity="User", mappedBy="roles")
*/
private $users;
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* #see RoleInterface
*/
public function getRole()
{
return $this->role;
}
// ... getters and setters for each property
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
*
* #return Role
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set role
*
* #param string $role
*
* #return Role
*/
public function setRole($role)
{
$this->role = $role;
return $this;
}
/**
* Add user
*
* #param \AppBundle\Entity\User $user
*
* #return Role
*/
public function addUser(\AppBundle\Entity\User $user)
{
$this->users[] = $user;
return $this;
}
/**
* Remove user
*
* #param \AppBundle\Entity\User $user
*/
public function removeUser(\AppBundle\Entity\User $user)
{
$this->users->removeElement($user);
}
/**
* Get users
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
}
And my User class:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Table(name="users")
* #ORM\Entity
*/
class User implements AdvancedUserInterface, \Serializable
{
/**
* #ORM\Column(type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(type="string", length=25, unique=true)
*/
private $username;
/**
* #ORM\Column(type="string", length=500)
*/
private $password;
/**
* #ORM\Column(name="is_active", type="boolean")
*/
private $isActive;
/**
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users")
*
*/
private $roles;
public function __construct($username)
{
$this->isActive = true;
$this->username = $username;
$this->roles = new ArrayCollection();
}
public function getUsername()
{
return $this->username;
}
public function getSalt()
{
return null;
}
public function getPassword()
{
return $this->password;
}
public function setPassword($password)
{
$this->password = $password;
}
public function getRoles()
{
return $this->roles->toArray();
}
public function eraseCredentials()
{
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set username
*
* #param string $username
*
* #return User
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Set isActive
*
* #param boolean $isActive
*
* #return User
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Add role
*
* #param \AppBundle\Entity\Role $role
*
* #return User
*/
public function addRole(\AppBundle\Entity\Role $role)
{
$this->roles[] = $role;
return $this;
}
/**
* Remove role
*
* #param \AppBundle\Entity\Role $role
*/
public function removeRole(\AppBundle\Entity\Role $role)
{
$this->roles->removeElement($role);
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->isActive;
}
// serialize and unserialize must be updated - see below
public function serialize()
{
return serialize(array(
// ...
$this->isActive
));
}
public function unserialize($serialized)
{
list (
// ...
$this->isActive
) = unserialize($serialized);
}
}
The problem is that this method getRole() always returns empty.
This is my db data:
[users]
id username password is_active
1 abriceno $2y$13$NW6uNOKJGUQTSXirej4HKOwIa6mWzYqFxzz1ppWQjyp... 1
[acme_role]
id name role
1 admin ROLE_ADMIN
[user_role]
user_id user_role
1 1
Also, i try to call the data from a controller test using doctrine:
public function indexAction(Request $request)
{
$repository = $this->getDoctrine()->getRepository('AppBundle:User');
$user = $repository->findOneByusername('abriceno');
$username = $user->getUsername();
$roles = $user->getRoles();
$arr = array(
'username' => $user->getUsername(),
'password' => $user->getPassword(),
'roles' => $user->getRoles()
);
return new JsonResponse($arr);
this returns:
{"username":"abriceno","password":"$2y$13$NW6uNOKJGUQTSXirej4HKOwIa6mWzYqFxzz1ppWQjypQJLIgUGJ.m","roles":[{}]}
I am so desperate... thanks for all the help that you can provide to me.
UPDATE 1
If i do print_r($role) this prints a huuuuuge list of values:
array(1) { [0]=> object(AppBundle\Entity\Role)#624 (4) { ["id":"AppBundle\Entity\Role":private]=> int(1) ["name":"AppBundle\Entity\Role":private]=> string(5) "admin" ["role":"AppBundle\Entity\Role":private]=> string(10) "ROLE_ADMIN" ["users":"AppBundle\Entity\Role":private]=> object(Doctrine\ORM\PersistentCollection)#626 (9) { ["snapshot":"Doctrine\ORM\PersistentCollection":private]=> array(0) { } ["owner":"Doctrine\ORM\PersistentCollection":private]=> *RECURSION*
... and keeps going... very strange!!
Seems that the join table is not handled directly by doctrine, so you need do specify to doctrine howto map the referenced fied with the JoinTable annotation (See the default mapping section.)
In your case, try to modify the roles relation definition in the User entity as follow:
/**
* #ORM\ManyToMany(targetEntity="Role", inversedBy="users")
* #ORM\JoinTable(name="user_role",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="user_role", referencedColumnName="id")})
*
*/
private $roles;
Hope this help
Finally i fix this with this code:
// Work of roles
$roles = $event->getUser()->getRoles();
$role_length = count($roles);
$role_list = array();
for ($i=0; $i <$role_length ; $i++) {
array_push($role_list,$roles[$i]->getRole());
}
$payload = $event->getData();
$payload['ip'] = $request->getClientIp();
$payload['roles'] = $role_list;
The problem (i guess) is on the ->getRoles(); code. This returns a array of Entity\Role class, not an array of roles.
Now the dump is:
{
"token": "eyJhbGciOiJSUzI1NiJ9.....",
"data": {
"roles": [
"ROLE_ADMIN"
]
}
}
my nightmare of a day continues.....
after implimenting a successful solution in an earlier thread where I need to alter my inter-entity relationships I am now getting this error when I try to log a user into the app:
CRITICAL - Uncaught PHP Exception Symfony\Component\Debug\Exception\UndefinedMethodException: "Attempted to call method "getRole" on class "Closure"." at C:\Dropbox\xampp\htdocs\etrack3\src\Ampisoft\Bundle\etrackBundle\Entity\Users.php line 234
I changed from a manyToMany relationship, to a manyToOne/OneToMany between a Users/Roles entity.
Ive read that serialize could cause the issue but Ive taken it out and it didnt make any difference. The remnants of the serialize required methods are still in there so please ignore (unless they are the issue).
Please could someone tell me what Ive done wrong? Im wondering if its best to scrap all the database tables and start again!!!!
here is the entity class.
/**
* user
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="Ampisoft\Bundle\etrackBundle\Entity\UsersRepository")
*/
class Users implements UserInterface
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=25, unique=true)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=64)
*/
private $password;
/**
* #ORM\Column(name="firstname", type="string", length=25)
*/
private $firstname;
/**
* #ORM\Column(name="surname", type="string", length=25)
*/
private $lastname;
/**
* #var boolean
*
* #ORM\Column(name="isActive", type="boolean")
*/
private $isActive = 1;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, unique=true)
*/
private $email;
/**
* #var \DateTime
*
* #ORM\Column(name="lastLogged", type="string")
*/
private $lastLogged = '-0001-11-30 00:00:00';
/**
* #var string;
*
* #ORM\Column(name="salt", type="string", length=255)
*/
private $salt;
/**
* #ORM\ManyToOne(targetEntity="Roles", inversedBy="users")
*
*/
private $roles;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set Id
*
* #return integer
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Set username
*
* #param string $username
* #return user
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* #param string $password
* #return user
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set isActive
*
* #param boolean $isActive
* #return user
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Set email
*
* #param string $email
* #return user
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set lastLogged
*
* #param \DateTime $lastLogged
* #return user
*/
public function setLastLogged($lastLogged)
{
$this->lastLogged = $lastLogged;
return $this;
}
/**
* Get lastLogged
*
* #return \DateTime
*/
public function getLastLogged()
{
return $this->lastLogged;
}
public function __construct()
{
$this->roles = new ArrayCollection();
$this->isActive = true;
}
/**
* #inheritDoc
*/
public function getRoles()
{
$roles = array();
foreach ($this->roles as $role) {
$roles[] = $role->getRole();
}
return $roles;
}
/**
* #param $roles
* #return $this
*/
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
/**
* #inheritDoc
*/
public function getSalt()
{
return $this->salt;
}
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->isActive;
}
/**
* Add roles
*
* #param \Ampisoft\Bundle\etrackBundle\Entity\Roles $roles
* #return users
*/
public function addRoles(Roles $roles)
{
$this->roles[] = $roles;
return $this;
}
/**
* Remove roles
*
* #param \Ampisoft\Bundle\etrackBundle\Entity\Roles $roles
*/
public function removeRoles(Roles $roles)
{
$this->roles->removeElement($roles);
}
/**
* Set firstname
*
* #param string $firstname
* #return users
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return users
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* #see \Serializable::serialize()
*/
/**
* Serializes the content of the current User object
* #return string
*/
public function serialize()
{
return \json_encode(
array($this->username, $this->password, $this->salt,
$this->roles, $this->id));
}
/**
* Unserializes the given string in the current User object
* #param serialized
*/
public function unserialize($serialized)
{
list($this->username, $this->password, $this->salt,
$this->roles, $this->id) = \json_decode(
$serialized);
}
}
update 1
this has worked but produced a new error Im going to move it to a new question when the post timer lets me.
Catchable Fatal Error: Argument 4 passed to Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::__construct() must be of the type array, object given, called in C:\Dropbox\xampp\htdocs\etrack3\vendor\symfony\symfony\src\Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider.php on line 96 and defined
HI I think what you want is not this
public function getRoles()
{
$roles = array();
foreach ($this->roles as $role) {
$roles[] = $role->getRole();
}
return $roles;
}
but this
public function getRoles()
{
return $this->roles;
}
Roles should be an ArrayCollection already, so calling getRole on the ( I assume ) Role class seems to be possible the issue.
If you are using an IDE such as Eclipse then the class is Doctrine\Common\Collections\ArrayCollection; this should be your collection of Roles, I would suggest also is you are using an IDE to do something like this ( for type hinting )
//... at the top of the class file before the class deceleration
use Doctrine\Common\Collections\ArrayCollection;
/**
* #param ArrayCollection $roles
*/
public function setRoles(ArrayCollection $roles)
{
//.. type cast the input to allow only use of ArrayCollection class
$this->roles = $roles;
}
/**
* #return ArrayCollection
*/
public function getRoles()
{
return $this->roles;
}
Also there is a good chance you are setting $this->roles to be a standard array at some point. You should always type cast your input to a specific class if it can only accept that type of class to rule out errors such as using a plain array.
Last thing, is generally protected for the properties are preferred because latter you can extend the class, it's not accessible outside the class much like private, but unlike private it is accessible in inheriting classes.
I am getting above error when login. With property option in security.yml it is working. I have added the #ORM\Entity(repositoryClass="versionR\userBundle\Entity\UserRepository") line on my entity class, dobule checked path, cleared cache but no luck.
User entity class
<?php
namespace versionR\userBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
//use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* #ORM\Table(name="user")
* #ORM\Entity(repositoryClass="versionR\userBundle\Entity\UserRepository")
*/
class User implements UserInterface, \Serializable
{
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=40, nullable=false)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=255, nullable=false)
*/
private $password;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, nullable=false)
*/
private $email;
/**
* #var string
*
* #ORM\Column(name="address", type="string", length=255, nullable=false)
*/
private $address;
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #var \Doctrine\Common\Collections\Collection
*
* #ORM\ManyToMany(targetEntity="versionR\userBundle\Entity\Role", inversedBy="user")
* #ORM\JoinTable(name="user_role",
* joinColumns={
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
* },
* inverseJoinColumns={
* #ORM\JoinColumn(name="role_id", referencedColumnName="id")
* }
* )
*/
private $role;
/**
* Constructor
*/
public function __construct()
{
$this->role = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* #param string $address
*/
public function setAddress($address)
{
$this->address = $address;
}
/**
* #return string
*/
public function getAddress()
{
return $this->address;
}
/**
* #param string $email
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* #param int $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* #param string $password
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* #param string $username
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* #param \Doctrine\Common\Collections\Collection $role
*/
public function setRole($role)
{
$this->role->add($role);
}
/**
* #return \Doctrine\Common\Collections\Collection
*/
public function getRole()
{
return $this->role;
}
/**
*/
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt,
));
}
/**
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
// see section on salt below
// $this->salt
) = unserialize($serialized);
}
/**
* Returns the roles granted to the user.
*/
public function getRoles()
{
return $this->role->toArray();
}
/**
*/
public function getSalt()
{
return null;
}
/**
*/
public function eraseCredentials()
{
// TODO: Implement eraseCredentials() method.
}
}
User repository class
<?php
namespace versionR\userBundle\Entity;
use Doctrine\ORM\EntityRepository;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
/**
* UserRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class UserRepository extends EntityRepository implements UserProviderInterface
{
/**
* #param string $username
* #return \versionR\userBundle\Entity\User
*/
public function loadUserByUsername($username)
{
return $this->findOneBy(array('username' => $username));
}
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if (!$this->supportsClass($class)) {
throw new UnsupportedUserException(
sprintf(
'Instances of "%s" are not supported.',
$class
)
);
}
return $this->find($user->getId());
}
public function supportsClass($class)
{
return $this->getEntityName() === $class
|| is_subclass_of($class, $this->getEntityName());
}
}
Both classes are in Entity directory. Any suggestions to solve this problem. I am using symfony 2.5.2
I am in a bit of a problem...
Folowed the handbook of Symfony2 and now i am stuck with logging myself in :s
Any help would be welcome for this newbie.
so this is my users entity:
<?php
namespace SocialGeo\BackendBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;
use Doctrine\Common\Collections\ArrayCollection;
/**
* SocialGeo\BackendBundle\Entity\Users
*/
class Users implements AdvancedUserInterface
{
/**
* #var integer $userId
*/
private $userId;
/**
* #var string $username
*/
private $username;
/**
* #ORM\Column(type="string", length=60)
*/
private $salt;
/**
* #var string $userPassword
*/
private $userPassword;
/**
* #var string $userEmail
*/
private $userEmail;
/**
* #var boolean $userActive
*/
private $userActive;
/**
* #var string $userFavourites
*/
private $userFavourites;
/**
* #var integer $userScore
*/
private $userScore;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $rolesRole;
/**
* Constructor
*/
public function __construct()
{
$this->rolesRole = new ArrayCollection();
$this->salt = md5(uniqid(null, true));
}
/**
* Get userId
*
* #return integer
*/
public function getUserId()
{
return $this->userId;
}
/**
* Set username
*
* #param string $username
* #return Users
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set userPassword
*
* #param string $userPassword
* #return Users
*/
public function setUserPassword($userPassword)
{
$this->userPassword = $userPassword;
return $this;
}
/**
* Get userPassword
*
* #return string
*/
public function getUserPassword()
{
return $this->userPassword;
}
/**
* Set userEmail
*
* #param string $userEmail
* #return Users
*/
public function setUserEmail($userEmail)
{
$this->userEmail = $userEmail;
return $this;
}
/**
* Get userEmail
*
* #return string
*/
public function getUserEmail()
{
return $this->userEmail;
}
/**
* Set userActive
*
* #param boolean $userActive
* #return Users
*/
public function setUserActive($userActive)
{
$this->userActive = $userActive;
return $this;
}
/**
* Get userActive
*
* #return boolean
*/
public function getUserActive()
{
return $this->userActive;
}
/**
* Set userFavourites
*
* #param string $userFavourites
* #return Users
*/
public function setUserFavourites($userFavourites)
{
$this->userFavourites = $userFavourites;
return $this;
}
/**
* Get userFavourites
*
* #return string
*/
public function getUserFavourites()
{
return $this->userFavourites;
}
/**
* Set userScore
*
* #param integer $userScore
* #return Users
*/
public function setUserScore($userScore)
{
$this->userScore = $userScore;
return $this;
}
/**
* Get userScore
*
* #return integer
*/
public function getUserScore()
{
return $this->userScore;
}
/**
* Add rolesRole
*
* #param SocialGeo\BackendBundle\Entity\Roles $rolesRole
* #return Users
*/
public function addRolesRole(\SocialGeo\BackendBundle\Entity\Roles $rolesRole)
{
$this->rolesRole[] = $rolesRole;
return $this;
}
/**
* Remove rolesRole
*
* #param SocialGeo\BackendBundle\Entity\Roles $rolesRole
*/
public function removeRolesRole(\SocialGeo\BackendBundle\Entity\Roles $rolesRole)
{
$this->rolesRole->removeElement($rolesRole);
}
/**
* Get rolesRole
*
* #return Doctrine\Common\Collections\Collection
*/
public function getRolesRole()
{
return $this->rolesRole->toArray();
}
public function eraseCredentials()
{
}
public function getPassword()
{
return $this->userPassword;
}
public function getRoles()
{
//return $this->groups->toArray();
return $this->getRolesRole();
}
public function getSalt()
{
return $this->salt;
}
public function isEqualTo(UserInterface $users)
{
return $this->username === $users->getUsername();
}
public function isAccountNonExpired() {
return true;
}
public function isAccountNonLocked() {
return true;
}
public function isCredentialsNonExpired() {
return true;
}
public function isEnabled() {
return $this->userActive;
}
}
my roles entity:
<?php
namespace SocialGeo\BackendBundle\Entity;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* SocialGeo\BackendBundle\Entity\Roles
*/
class Roles implements RoleInterface
{
/**
* #var integer $roleId
*/
private $roleId;
/**
* #var string $roleName
*/
private $roleName;
/**
* #ORM\Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* #var string $roleDescription
*/
private $roleDescription;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $usersUser;
/**
* Constructor
*/
public function __construct()
{
$this->usersUser = new ArrayCollection();
}
/**
* Get roleId
*
* #return integer
*/
public function getRoleId()
{
return $this->roleId;
}
/**
* Set roleName
*
* #param string $roleName
* #return Roles
*/
public function setRoleName($roleName)
{
$this->roleName = $roleName;
return $this;
}
/**
* Get roleName
*
* #return string
*/
public function getRoleName()
{
return $this->roleName;
}
/**
* Set roleDescription
*
* #param string $roleDescription
* #return Roles
*/
public function setRoleDescription($roleDescription)
{
$this->roleDescription = $roleDescription;
return $this;
}
/**
* Get roleDescription
*
* #return string
*/
public function getRoleDescription()
{
return $this->roleDescription;
}
/**
* Add usersUser
*
* #param SocialGeo\BackendBundle\Entity\Users $usersUser
* #return Roles
*/
public function addUsersUser(\SocialGeo\BackendBundle\Entity\Users $usersUser)
{
$this->usersUser[] = $usersUser;
return $this;
}
/**
* Remove usersUser
*
* #param SocialGeo\BackendBundle\Entity\Users $usersUser
*/
public function removeUsersUser(\SocialGeo\BackendBundle\Entity\Users $usersUser)
{
$this->usersUser->removeElement($usersUser);
}
/**
* Get usersUser
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUsersUser()
{
return $this->usersUser;
}
public function getRole() {
return $this->role;
}
}
userrepository entity:
<?php
namespace SocialGeo\BackendBundle\Entity;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* SocialGeo\BackendBundle\Entity\Roles
*/
class Roles implements RoleInterface
{
/**
* #var integer $roleId
*/
private $roleId;
/**
* #var string $roleName
*/
private $roleName;
/**
* #ORM\Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* #var string $roleDescription
*/
private $roleDescription;
/**
* #var \Doctrine\Common\Collections\ArrayCollection
*/
private $usersUser;
/**
* Constructor
*/
public function __construct()
{
$this->usersUser = new ArrayCollection();
}
/**
* Get roleId
*
* #return integer
*/
public function getRoleId()
{
return $this->roleId;
}
/**
* Set roleName
*
* #param string $roleName
* #return Roles
*/
public function setRoleName($roleName)
{
$this->roleName = $roleName;
return $this;
}
/**
* Get roleName
*
* #return string
*/
public function getRoleName()
{
return $this->roleName;
}
/**
* Set roleDescription
*
* #param string $roleDescription
* #return Roles
*/
public function setRoleDescription($roleDescription)
{
$this->roleDescription = $roleDescription;
return $this;
}
/**
* Get roleDescription
*
* #return string
*/
public function getRoleDescription()
{
return $this->roleDescription;
}
/**
* Add usersUser
*
* #param SocialGeo\BackendBundle\Entity\Users $usersUser
* #return Roles
*/
public function addUsersUser(\SocialGeo\BackendBundle\Entity\Users $usersUser)
{
$this->usersUser[] = $usersUser;
return $this;
}
/**
* Remove usersUser
*
* #param SocialGeo\BackendBundle\Entity\Users $usersUser
*/
public function removeUsersUser(\SocialGeo\BackendBundle\Entity\Users $usersUser)
{
$this->usersUser->removeElement($usersUser);
}
/**
* Get usersUser
*
* #return Doctrine\Common\Collections\Collection
*/
public function getUsersUser()
{
return $this->usersUser;
}
public function getRole() {
return $this->role;
}
}
and last one: security.yml:
security:
encoders:
SocialGeo\BackendBundle\Entity\Users:
algorithm: sha1
encode_as_base64: false
iterations: 1
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ ROLE_USER, ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH ]
providers:
users:
entity: { class: SocialGeoBackendBundle:Users }
firewalls:
admin_area:
pattern: ^/users
http_basic: ~
access_control:
- { path: ^/login, roles: ROLE_ADMIN }
The problem is that my app keeps asking me to log in everytime, but i can't get in (everytimei go to /users page). Home is accesible.
So when i go to /users a basic http: pops out of the browser and asks me my credentials, when i fill them in and press enter, i get the same popup of the browser, asking me to log in...
edit: my salt in the database for evey user is: 7308e59b97f6957fb42d66f894793079
and my password for everyuser is 'pass' hashed with sha1 to : 9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684
Your password is hashed incorrectly. You're supposed to use the salt together with the cleartext password. Try prefixing your password with the salt before hashing it.
update users set password = sha1(concat('7308e59b97f6957fb42d66f894793079', 'pass'))