I use symfony2 in my project, i have an entity employee that includes all informations of the emlpolyee and also the username and password to do the login to his session. i want to create a secured authentification to the employee but when i check the documentation of FOS Userbundle and SonataUserBundle i see that i should create a new entity USER that includes new usernames and passwords. but i want to use usernames and passwords stored in my entity employee. this is my entity:
employee.php
class employee
{
private $codeEmployee;
//////
private $username;
private $password;
public function getCodeEmployee()
{
return $this->codeEmployee;
}
/////
public function setusername($username)
{
$this->username = $username;
return $this;
}
public function getusername()
{
return $this->username;
}
public function setPassword($password)
{
$this->password = $password;
return $this;
}
public function getPassword()
{
return $this->password;
}
////////
}
how to do that??
The official documentation explains the procedure to do that.
Your Employee class must extend the base User class :
<?php
namespace Foo\BarBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="employees")
*/
class Employee extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\Column(type="string", length=255)
*/
protected $codeEmployee;
// Optional
public function __construct()
{
parent::__construct();
// your own logic
}
public function getCodeEmployee()
{
return $this->codeEmployee;
}
public function setCodeEmployee($codeEmployee)
{
$this->codeEmployee = $codeEmployee;
return $this;
}
}
Don't forget to configure FOSUserBundle to choose your user class :
# app/config/config.yml
fos_user:
db_driver: orm
firewall_name: main
user_class: Foo\BarBundle\Entity\Employee
The rest of the configuration (security.yml file, the FOSUserBundle routing files and the other commands to launch) is explained is the documentation.
The documentation also explain how to extend the User entity and to override the form.
Related
I want to recover the date of the last time a user logged in my Symfony 5 website, I created a LoginListener and did the right settings (So-think-I ?) to make it work but in the class Login Listener :
namespace App\Event;
use App\Entity\User;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
class LoginListener
{
private $em;
public function __construct(EntityManagerInterface $em)
{
$this->em = $em;
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event)
{
// Get the User entity.
$user = $event->getAuthenticationToken()->getUser();
// Update your field here.
$user->setLastLogin(new \DateTime());
// Persist the data to database.
$this->em->persist($user);
$this->em->flush();
}
}
The setLastLogin(new \DateTime()) is described as an undefined method. Yet this method is in the entity User.php and it is properly called in the loginlistener. And the "use App\Entity\User :
/**
* {#inheritdoc}
*/
public function setLastLogin(\DateTime $time = null)
{
$this->lastLogin = $time;
return $this;
}
/**
* Gets the last login time.
*
* #return \DateTime|null
*/
public function getLastLogin()
{
return $this->lastLogin;
}
/**
* #var \DateTime $lastLogin
*
* #ORM\Column(type="datetime")
*/
private $lastLogin;
And when I try to make a exit(var_dump($user), nothing appears. Here is my services.yaml :
App\EventListener\LoginListener:
- tags:
- { name: 'kernel.event_listener', event: 'security.interactive_login', entity: 'App\Entity\User' }
Can someone help me please ? Thank you.
My doubt is about Api Platform. (https://api-platform.com)
I have two entities. Question and Answer. And I want to have a POST call to create a question with one answer. I show my entities.
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* #ApiResource(
* normalizationContext={"groups"={"question"}},
* denormalizationContext={"groups"={"question"}})
* #ORM\Entity
*/
class Question
{
/**
* #Groups({"question"})
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*/
private $id;
/**
* #Groups({"question"})
* #ORM\Column
* #Assert\NotBlank
*/
public $name = '';
/**
* #Groups({"question"})
* #ORM\OneToMany(targetEntity="Answer", mappedBy="question", cascade={"persist"})
*/
private $answers;
public function getAnswers()
{
return $this->answers;
}
public function setAnswers($answers): void
{
$this->answers = $answers;
}
public function __construct() {
$this->answers = new ArrayCollection();
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getId(): int
{
return $this->id;
}
}
And a Answer Entity
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Serializer\Annotation\Groups;
/**
*
* #ApiResource
* #ORM\Entity
*/
class Answer
{
/**
* #Groups({"question"})
* #ORM\Id
* #ORM\Column(type="guid")
*/
public $id;
/**
* #Groups({"question"})
* #ORM\Column
* #Assert\NotBlank
*/
public $name = '';
/**
* #ORM\ManyToOne(targetEntity="Question", inversedBy="answers")
* #ORM\JoinColumn(name="question_id", referencedColumnName="id")
*/
public $question;
public function getQuestion()
{
return $this->question;
}
public function setQuestion($question): void
{
$this->question = $question;
}
public function getName(): string
{
return $this->name;
}
public function setName(string $name): void
{
$this->name = $name;
}
public function getId(): string
{
return $this->id;
}
public function __toString()
{
return $this->getName();
}
}
Now I can create from dashboard of nelmio a question and into an answer. But in database, my answer doesnt have saved the relation with question.
{
"name": "my new question number 1",
"answers": [
{
"id": "ddb66b71-5523-4158-9aa3-2691cae9d473",
"name": "my answer 1 to question number 1"
}
]
}
And other question is... I've changed my id of answer by a guid, because I get and error when I create and answer into question without id. Can I create a question, and answers without to specify an id ?
Thanks in advance
Well, I see some errors in your entities... first since the relation between Question and Answer entity is a OneToMany, your Qestion entity should have this implemented, the:
use ApiPlatform\Core\Annotation\ApiProperty;
//..... the rest of your code
/**
* #ApiProperty(
* readableLink=true
* writableLink=true
* )
* #Groups({"question"})
* #ORM\OneToMany(targetEntity="Answer", mappedBy="question", cascade={"persist"})
*/
private $answers;
public function __construct()
{
//....
$this->answers = new ArrayCollection();
//...
}
public function addAnswer(Answer $answer): self
{
if (!$this->answers->contains($answer)) {
$this->answers[] = $answer;
$answer->setQuestion($this)
}
return $this;
}
public function removeAnswer(Answer $answer): self
{
if ($this->answers->contains($answer)) {
$this->answers->removeElement($answer);
}
return $this;
}
the command
PHP bin/console make:entity
allows you to create a field in your entity of type relation and it creates these methods for you just follow the instructions (after both entities are created, use the command for update Question entity...)
the readableLink ApiProperty annotation is for see embedded object on GET request, is the same if you use serialization groups, if you set it on false then the response will look like this:
{
"name": "my new question number 1",
"answers": [
"/api/answers/1",
"/api/answers/2",
....
]
}
it is used to make responses smaller (among other things)... and the writableLink is for allowing POST request like this (see this example for more info here):
{
"name": "my new question number 1",
"answers": [
{
"id": "ddb66b71-5523-4158-9aa3-2691cae9d473",
"name": "my answer 1 to question number 1"
}
]
}
of course, using the corresponding serialization groups in each entity...
in ApiPlatform the embedded objects are persisted through setters and getters method but also add and remove methods for OneToMany relations, and the ORM does the rest of the work.
let me know if this helps. Cheers!
For the first point, it should persist in database without problem. Anyway, you could create a PostValidateSubscriber for Question entity and check if the relation is there.
<?php /** #noinspection PhpUnhandledExceptionInspection */
namespace App\EventSubscriber;
use ApiPlatform\Core\EventListener\EventPriorities;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
final class QuestionPostValidateSubscriber implements EventSubscriberInterface
{
private $tokenStorage;
public function __construct(
TokenStorageInterface $tokenStorage
) {
$this->tokenStorage = $tokenStorage;
}
/**
* {#inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::VIEW => ['checkQuestionData', EventPriorities::POST_VALIDATE]
];
}
/**
* #param GetResponseForControllerResultEvent $event
*/
public function checkQuestionData(GetResponseForControllerResultEvent $event)
{
$bid = $event->getControllerResult();
$method = $event->getRequest()->getMethod();
if (!$question instanceof Question || (Request::METHOD_POST !== $method && Request::METHOD_PUT !== $method))
return;
$currentUser = $this->tokenStorage->getToken()->getUser();
if (!$currentUser instanceof User)
return;
}
}
And do an echo or use xdebug for check question.
For the second point, you can add these annotations for the id of entities, so the id's will generate theirself.
#ORM\GeneratedValue()
#ORM\Column(type="integer")
I am learning Symfony 4, and I am lost with user roles and I don't know where to start.
Because it will be an intranet like website Users will not register themselves, the admin will register them and set the role. The admin can also create new roles dynamically.
I would like to store user roles in database. I have 2 entities User and Role. (Relations are not defined yet, that´s normal)
Here is my User entity :
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* #ORM\Entity(repositoryClass="App\Repository\UserRepository")
* #UniqueEntity(fields="email", message="Email already taken")
* #UniqueEntity(fields="username", message="Username already taken")
*/
class User implements UserInterface, \Serializable
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer", unique=true)
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $firstname;
/**
* #ORM\Column(type="string", length=255)
*/
private $lastname;
/**
* #ORM\Column(type="string", length=255)
*/
private $email;
/**
* #ORM\Column(type="date")
*/
private $birthdate;
/**
* #ORM\Column(type="integer", nullable=true)
*/
private $roleId;
/**
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $username;
/**
* #Assert\NotBlank()
* #Assert\Length(max=4096)
*/
private $plainPassword;
/**
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $password;
/**
* #ORM\Column(name="is_active", type="boolean", nullable=true)
*/
private $isActive;
// GETTERS
public function getId()
{
return $this->id;
}
public function getFirstname()
{
return $this->firstname;
}
public function getLastname()
{
return $this->lastname;
}
public function getBirthdate()
{
return $this->birthdate;
}
public function getEmail()
{
return $this->email;
}
public function getRoleId()
{
return $this->roleId;
}
public function getRoles()
{
return array('ROLE_USER');
}
public function getUsername()
{
return $this->username;
}
public function getPlainPassword()
{
return $this->plainPassword;
}
public function getPassword()
{
return $this->password;
}
public function getSalt()
{
return null;
}
// SETTERS
public function setFirstname($firstname)
{
$this->firstname = $firstname;
}
public function setLastname($lastname)
{
$this->lastname = $lastname;
}
public function setEmail($email)
{
$this->email = $email;
}
public function setBirthdate($birthdate)
{
$this->birthdate = $birthdate;
}
public function setRoleId($roleId)
{
$this->roleId = $roleId;
}
public function setUsername($username)
{
$this->username = $username;
}
public function setPlainPassword($password)
{
$this->plainPassword = $password;
}
public function setPassword($password)
{
$this->password = $password;
}
// FUNCTIONS
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 eraseCredentials()
{
}
}
Here is my Role entity :
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\RoleRepository")
*/
class Role
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer", unique=true)
*/
private $id;
/**
* #ORM\Column(type="string", length=255, nullable=false)
*/
private $type;
// GETTERS
public function getId()
{
return $this->id;
}
public function getType()
{
return $this->type;
}
// SETTERS
public function setType($type): void
{
$this->type = $type;
}
}
Is it a good practice to do so ??
On the Symfony documentation, we can read everywhere the "macros" ROLE_USER, ROLE_ADMIN... Where are they defined ? Can we customize this ?
Symfony used to support role entities with a RoleInterface, much like with your user implementing the UserInterface. It was decided that this is unnecessary as the roles-table will usually only contain 2 fields (id, name) which means we might just as well store the roles directly in the users table.
So, if you want to follow Symfony best practices you would just have your roles in the user, for example like this:
class User implements UserInterface
{
/** #Column(type="json") */
private $roles = [];
public function getRoles(): array
{
return array_unique(array_merge(['ROLE_USER'], $this->roles));
}
public function setRoles(array $roles)
{
$this->roles = $roles;
}
public function resetRoles()
{
$this->roles = [];
}
}
If you don't want to store the roles as JSON-encoded string you can also use #Column(type="array") */ or write a custom DBAL type, e.g some kind of EnumType. You might also want to secure the setter against invalid data or add validation.
Regarding the second question about the roles used in the documentation: Symfony has some predefined roles and pseudo-roles for certain features:
IS_AUTHENTICATED_ANONYMOUSLY
IS_AUTHENTICATED_REMEMBERED
IS_AUTHENTICATED_FULLY
ROLE_ALLOWED_TO_SWITCH (for user switching)
The other roles like ROLE_USER and ROLE_ADMIN are purely exemplary and you may use them as you see fit. You do not even have to start your own roles with a ROLE_ (although some security features rely on this convention and things will not work as expected for those roles unless you do some manual changes).
Recommended Reading from current Symfony Documentation (version 4 at the time of this answer):
https://symfony.com/doc/current/security.html#hierarchical-roles
Symfony recommends defining role inheritance, please see if it helps; from the link just above,
"
Instead of giving many roles to each user, you can define role inheritance rules by creating a role hierarchy:
# config/packages/security.yaml
security:
# ...
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
Users with the ROLE_ADMIN role will also have the ROLE_USER role. And users with ROLE_SUPER_ADMIN, will automatically have ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH and ROLE_USER (inherited from ROLE_ADMIN).
For role hierarchy to work, do not try to call $user->getRoles() manually. For example, in a controller extending from the base controller:
// BAD - $user->getRoles() will not know about the role hierarchy
$hasAccess = in_array('ROLE_ADMIN', $user->getRoles());
// GOOD - use of the normal security methods
$hasAccess = $this->isGranted('ROLE_ADMIN');
$this->denyAccessUnlessGranted('ROLE_ADMIN');
" end of copying
I think storing the role as a string is enough if inheritance fits your needs.
Hello Silex (and Symfony) experts,
I need to implement a database authentification User/Role model via Doctrine /ORM.
This is my silex composer setup:
"require": {
"silex/web-profiler": "^2.0",
"monolog/monolog": "1.13.*",
"symfony/twig-bridge": "^3.2",
"symfony/monolog-bridge": "^3.2",
"symfony/console": "^3.2",
"symfony/yaml": "^3.2",
"symfony/security-bundle": "^3.2",
"doctrine/orm": "^2.5",
"dflydev/doctrine-orm-service-provider": "^2.0",
"symfony/form": "^3.2",
"symfony/validator": "^3.2",
"symfony/config": "^3.2",
"symfony/doctrine-bridge": "^3.2",
"doctrine/migrations": "^1.5"
},
Users can register. Registered users can login and logout. Non registered visitors have anonymous role.
The symfony profiler is working, so I can see the security status (authentification/authoriszation). I also track the apache logfile for php errors.
I started from here https://github.com/fredjuvaux/silex-orm-user-provider (User from db, roles as array) and tried to expand it to get user roles from database via doctrine many-to-many relation.
There are:
class MyUserController (different user actions like user,edit, register,... )
class MyUserManager implements UserProviderInterface (loadUserByUsername, ...)
class MyUserServiceProvider implements ServiceProviderInterface, ControllerProviderInterface, BootableProviderInterface (controller routing and template setting)
The ORM entities are:
User:
/**
* MyUser
*
* #Entity
* #Table(name="myuser")
*/
class MyUser implements UserInterface, \Serializable
{
....
/**
* #ManyToMany(targetEntity="MyRole", inversedBy="users")
*
*/
private $roles;
...
* Constructor.
*
* #param string $email
*/
public function __construct($email)
{
$this->email = $email;
$this->created = time();
$this->salt = base_convert(sha1(uniqid(mt_rand(), true)), 16, 36);
$this->roles = new ArrayCollection();
}
...
/**
*
* #return ArrayCollection list of the user's roles.
*/
public function getRoles()
{
$result = $this->roles->toArray(); // throws error for login:
// $result = $this->roles; // test // thhrows error : null object
dump($this->roles);
// $result = array("ROLE_USER", "ROLE_OTHER"); // static setting and
works for login
return $result;
}
...
}
Roles (implements Roleinterface)
/**
* MyRole
*
* #Entity
* #Table(name="myrole")
*/
class MyRole implements RoleInterface
{
/**
* #var string
* #Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/**
* #ManyToMany(targetEntity="MyUser", mappedBy="roles")
*/
private $users;
...
/*
* methods for RoleInterface
* #return string|null A string representation of the role, or null
*/
public function getRole()
{
$result = $this->role;
return $result;
}
}
When a user registers, he gets for that session the ROLE_USER role,
authentification and authorisation are ok and a user is created in the
database.
Then I can assign new roles ("role_test1", "role_test2") in the controller for the new user, the many-to-many table myuser_myrole is filled (myuser_id myrole_id).
When I change the roles, they are correctly updated by the entity manager.
When I access the user Entity from the userController to work on it, I can access the assigned roles:
// MyUserController.php
$user = $em->getRepository('MyEntities\MyUser')->find($id);
$roles= $user->getRoles()
$role_length = count($roles);
$role_list = array();
for ($i=0; $i <$role_length ; $i++)
{
array_push($role_list,$roles[$i]->getRole()); // MyRole::getRole() prints out something to screen.
}
printf("<br> role-list:"); dump($role_list);
Calling this controller prints out the assigned roles via MyRole::getRole(), so ORM access works here.
Now comes the strange:
I want to login the new user with the login form.
When I use
// MyUser::getRoles()
return $this->roles;
It throws:
Argument 4 passed to Symfony\\Component\\Security\\Core\\Authentication\\Token\\UsernamePasswordToken::__construct() must be of the type array, object given,
Ok, makes maybe sense because the $roles is an Doctrine ArrayCollection.
When I use
// MyUser::getRoles()
return $this->roles->toArray();
I can login with user password,but am not authenticated (yellow status). Dumping out the roles, I receive an empty array ArrayCollection.
roles:
ArrayCollection {#388 ▼
-elements: []
}
The UsernamePasswordToken has an empty role-array.
When I use
// MyUser::getRoles()
return array("ROLE_HELLO1", "ROLE_HELLO2"); // static role array with strings
I can login and am authenticated with these roles:
Roles
array:2 [▼
0 => "ROLE_HELLO1"
1 => "ROLE_HELLO2"
]
There are old docs about this (Managing Roles in the Database) for symfony 2 http://symfony.com/doc/2.0/cookbook/security/entity_provider.html, but it doesnt work in symfony3.
Here they use
//class User
public function getRoles()
{
return $this->groups->toArray();
}
//class Group extends Role (not RoleInterface, old?)
public function getRole()
{
return $this->role;
}
The actual symfony docs for user management do not show how to use roles stored in database.
In summary:
Login and user/role do not work as expected:
MyUser::getRoles()
does not receive the Roles from database via doctrine ORM.
has to return a string array of roles for login.
delivers the correct role association in another controller.
Questions:
(1) Is this a Silex specific issue?
(2) How to use it correctly or where is a good link/doc for a workaround?
(3) Does the method LoadUserByUsername() interfere with all this?
(4) Do I need a class MyUserRepository extends EntityRepository {} to do the query and get the Role List?
(5) Do I need to use the Role Hierarchy service?
(6) Are there special naming conventions(tablename or class name) for "user" and "role"?
I found many posts asking the same/similar but they do not help here.
Thank you for help, I am really stuck on that!
dirk
Try this:
public function getRoles()
{
return $this->roles->map(function (MyRole $role) {
return $role->getRole();
})->toArray();
}
You should also check if the relationship is correctly saved in database.
If there is ManyToMany relationship between MyUser and MyRole, you have to ensure that relationship is saved in both entities.
//class MyUser
public function addRole(MyRole $role)
{
$this-roles->add($role);
$role->users->add($user);
}
I had a break on this, but now it seems to work. Thank you miikes for the addRole() suggestion!
finally I have: MyUser.php:
//Myuser.php
/**
* MyUser
*
* #Entity
* #Table(name="myuser")
*/
class MyUser implements UserInterface, \Serializable //, ObjectManagerAware
{
...
/**
* #ManyToMany(targetEntity="MyRole", inversedBy="users")
*/
private $roles;
public function __construct($email)
{
(...)
$this->roles = new ArrayCollection();
/**
*
* #return ArrayCollection list of the user's roles.
*/
public function getRoles()
{
$result = $this->roles->toArray();
return $result;
}
public function assignToRole($role)
{
$this->roles[] = $role;
}
public function setRole($myrole)
{
$this->roles= $myrole;
}
public function hasRole($role)
{
return in_array(strtoupper($role), $this->getRoles(), true);
}
public function addRole(MyRole $role)
{
$this->roles->add($role);
//$role->users->addRole($this); // could not access roles->user->...
// because private variable in MyRole but it works
}
/**
* Remove the given role from the user.
*
* #param string $role
*/
public function removeRole($role)
{
dump($role);
$this->roles->removeElement($role);
}
(...) // other setters getters
public function serialize()
{
return serialize(array(
$this->id,
$this->username,
$this->password,
$this->salt,
));
}
/**
* #see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
$this->username,
$this->password,
$this->salt,
) = unserialize($serialized);
}
}
and MyRole.php:
// MyRole.php
/**
* MyRole
*
* #Entity
* #Table(name="myrole")
*/
class MyRole implements RoleInterface
{
(...)
/**
* #ManyToMany(targetEntity="MyUser", mappedBy="roles")
*/
private $users;
/**
* #var string
* #Column(name="role", type="string", length=20, unique=true)
*/
private $role;
/*
* methods for RoleInterface
* #return string|null A string representation of the role, or null
*/
public function getRole()
{
$result = $this->role;
return ($result);
}
public function setRole($role)
{
$this->role= $role;
return $this;
}
(...)
/**
* Constructor
*/
public function __construct()
{
$this->users = new ArrayCollection();
}
/**
* Add user
* #param \MyEntities\MyUser $user
* #return MyRole
*/
public function addUser($user)
{
$this->users[] = $user;
return $this;
}
public function setUser($user)
{
$this->users[] = $user;
return $this;
}
/**
* Remove user
*
* #param \MyEntities\MyUser $user
*/
public function removeUser($user)
{
$this->users->removeElement($user);
}
/**
* Get users
*
* #return ArrayCollection $users
*/
public function getUsers()
{
return $this->users;
}
/**
* __toString()
*
* #return string
*/
public function __toString()
{
return $this->bezeichnung;
}
}
With the help of the doctrine orm commands
vendor/bin/doctrine orm:validate-schema
vendor/bin/doctrine orm:schema-tool:update --dump-sql
the correct manyToMany table myuser_myrole was generated and the role setting works at login of a user.
I think, the most important was the correct use of the function addRole() (with this->roles->add($role), and not something like this->roles->addRole($role) ) to let doctrine do the magic stuff in the background.
Thanks for any help and comments!
dirk
I set up my entities same as https://github.com/KnpLabs/DoctrineBehaviors#translatable . Also configs same as http://a2lix.fr/bundles/translation-form/ . Also I add __call method and try to implement How to print translatable data in sonata admin with DoctrineBehaviors from kpnlabs. First I get error that $name doesn't exist at Category.php. So I add it, now I have error:
Neither the property "name" nor one of the methods "addName()"/"removeName()", "setName()", "name()", "__set()" or "__call()" exist and have public access in class.
Question is how they remove setters/getters from main Entity, for me it's caused errors. Maybe someone have proper magic for all of this?
Category.php
class MyClass
{
use \Knp\DoctrineBehaviors\Model\Translatable\Translatable;
private $name; //added after error
public function __call($method, $arguments)
{
return $this->proxyCurrentLocaleTranslation($method, $arguments);
}
public function getName() {
return $this->translate()->getName(); //added after error
}
#public function getName() {
# return ($this->getTranslations()); // also trying like this
#}
// ...
CategoryTranslation.php
use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
/**
* CategoryTranslation
*/
class CategoryTranslation
{
use ORMBehaviors\Translatable\Translation;
/**
* #var string
*/
private $name;
/**
* Set name
*
* #param string $name
* #return CategoryTranslation
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
}
In sonata category admin:
$formMapper->add('name', 'a2lix_translations');
When I added my category(access message) I see in database "name" looks like
Doctrine\Common\Collections\ArrayCollection#000000006cb11474000000002980d54f
Remove setters and getters from main class then doctrine:schema:update.
Also in sonata category admin:
$formMapper->add('translations', 'a2lix_translations');