Reputation: 89
I'm new to doctrine entities but I have a user table and a role table and the roles are linked to user using bit masking. Like so
+----+----------+------+
| id | username | role |
+----+----------+------+
| 1 | admin | 1022 |
+----+----------+------+
+----+------------+------------+
| id | role | permission |
+----+------------+------------+
| 1 | ROLE_ADMIN | 2 |
| 2 | ROLE_DEV | 4 |
+----+------------+------------+
How do I setup my User entity class to load the User::$roles
property so that Symfony
can retrieve them with User::getRoles()
function? Preferably by loading and array of the Role entity.
Equivalent to this:
SELECT r.*
FROM user u
LEFT JOIN role r
ON (u.role & r.permission)
WHERE u.id = :id
Upvotes: 1
Views: 162
Reputation: 803
The roles can be stored in some class, for example (treat code below as pseudo code because):
class Roles
{
static private $roles = array(
'ROLE_ADMIN',
'ROLE_DEV'
);
public static function getRoleName($index)
{
return (isset($roles[$value]) ? $roles[$value] : false);
}
public static function getIndex($value)
{
return array_search($value, $roles);
}
}
This can be generated somewhere if you need it from database (look at Life cycle events in doctrine)
Then you can define your custom mapping doctrine type let's say "role" Custom mapping types
Something like this (not tested, and you have to make some checks to not overflow integer size):
class RoleType extends Type
{
const ROLE_TYPE = 'role';
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
{
return 'INT'; //your sql type
}
public function convertToPHPValue($value, AbstractPlatform $platform)
{
// ensure to requrie your role class in bootstrap
$roles = array();
$index = 0;
while ($value) {
$role = $value & 1;
if ($role && $roleName = Roles::getRoleName($index)) {
$roles[] = $roleName;
}
if ($roleName === false) {
break;
}
$value = $value >> 2;
++$index;
}
return $roles;
}
public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
$roleValue = 0;
foreach ($value as $roleName) {
$role = Roles::getIndex($roleName);
if ($role !== false) {
$roleValue |= pow(2, $role);
}
}
return $roleValue;
}
public function getName()
{
return self::ROLE_TYPE;
}
}
And to register type in Symfony Registering Custom Mapping Types
Anyway I think the best option is to make relation between user and roles.
Upvotes: 1