我有一个返回JSON响应的函数:
public function getUsersAction()
{
$response = array();
$em = $this->getDoctrine()->getManager();
$entities = $em->getRepository("UserBundle:User")->findAll();
$roles = array(
"ROLE_PROFILE_ONE" => "Facturación y Entrega",
"ROLE_PROFILE_TWO" => "Envío",
"ROLE_ADMIN" => "Administrador",
"ROLE_USER" => "No posee roles asignados"
);
$users = array();
foreach ($entities as $entity)
{
$user = array();
$user[] = $entity->getUsername();
$user[] = $entity->getEmailCanonical();
$user[] = $entity->getRoles();
$user[] = $entity->getGroupNames() != NULL ? $entity->getGroupNames() : "-";
$users[] = $user;
}
$response[ 'data' ] = $users;
return new JsonResponse($response);
}
我通过Ajax调用通过Twig模板访问它,这就是工作!现在,由于User
(FOSUser)模型中的getRoles()
按照示例返回DB值:ROLE_PROFILE_ONE
、ROLE_ADMIN
、ROLE_USER
,我如何格式化输出以显示基于$roles
定义的数组的友好名称?我试图在foreach ($entities as $entity) ...
中执行foreach
循环并设置一个新数组,但由于我的Apache出现故障,嵌套调用过大。有什么帮助吗?
试图通过输入/输出示例更加清晰
好吧,这就是我们的输入(函数返回的内容,我做了一个ladybug_dump($entities)
来获得输出):
array(6)
[0]: object(Tanane'UserBundle'Entity'User)
>> Properties
...
# [roles]: array(1)
[0]: string (16) "ROLE_PROFILE_ONE"
...
[1]: object(Tanane'UserBundle'Entity'User)
>> Properties
...
# [roles]: array(2)
[0]: string (16) "ROLE_PROFILE_TWO"
[1]: string (16) "ROLE_PROFILE_ONE"
...
当我在Twig上访问该模板时,我得到了:
User1 ROLE_PROFILE_ONE
User2 ROLE_PROFILE_TWO, ROLE_PROFILE_ONE
但我需要这个输出:
User1 Facturación y Entrega
User2 Envío, Facturación y Entrega
现在更清楚了?
如果您的角色总是要转换为那些特定的字符串,那么您可以将它们添加到用户模型中,并在getTransformedRoles()
方法中构建角色列表,如。。
User.php
class User extends BaseUser implements UserInterface
{
const ROLE_PROFILE_ONE = 'Facturación y Entrega';
const ROLE_PROFILE_TWO = 'Envío';
const ROLE_ADMIN = 'Administrador';
const ROLE_USER = 'No posee roles asignados';
...
public function getTransformedRoles()
{
$transformed = array();
foreach ($this->getRoles() as $role) {
$role = strtoupper($role);
$const = sprintf('self::%s', $role);
// Do not add if is $role === ROLE_USER
if (FOS'UserBundle'Model'UserInterface::ROLE_DEFAULT === $role) {
continue;
}
if (!defined($const)) {
throw 'Exception(sprintf('User does not have the role constant "%s" set', $role));
}
$transformed[] = constant($const);
)
// If no roles add self::ROLE_USER
if (empty($transformed)) {
$transformed[] = self::ROLE_USER;
}
return $transformed;
}
....
}
然后,这将返回完全转换的角色数组(使用$user->getTransformedRoles()
),而不是只返回单个用例。
或者,您可以使用一个进行相同类型转换的服务,但使用一组不同的角色和转换,这些角色和转换可以通过config.yml.设置
更新
要将其用作app/config/config
中指定的角色转换的服务,可以执行以下操作。。
Acme/SomethingBundle/DependencyInjection/Configuration
$rootNode
->children()
->arrayNode('role_transformations')
->defaultValue(array())
->useAttributeAsKey('name')
->prototype('scalar')->cannotBeEmpty()->end()
->end()
->end()
->end();
Acme/SomethingBundle/DependencyInjection/AcmeSomethingExtension
$container->setParameter(
'acme.something.role_transformations',
$config['role_transformations']
);
然后在app/config/config.yml中
// For an empty array
role_transformations: ~ // Or not even at all, it defaults to an empty array
// For transformation
role_transformations:
ROLE_PROFILE_ONE: 'Facturación y Entrega'
ROLE_PROFILE_TWO: 'Envío'
ROLE_ADMIN: 'Administrador'
ROLE_USER: 'No posee roles asignados'
创建您的服务并注入角色转换
parameters:
acme.something.role_transformer.class: Acme/SomethingBundle/Transformer/RoleTransformer
services:
acme.something.role_transformer:
class: %acme.something.role_transformer.class%
arguments:
- %acme.something.role_transformations%
然后在您的服务文件(Acme/SomethingBundle/Transformer/RoleTransformer)
class RoleTransformer implements RoleTransformerInterface
{
const ROLE_DEFAULT = 'ROLE_USER';
protected $rolesTransformations;
public function __construct(array $roleTransformations)
{
$this->roleTransformations = $roleTransformations;
}
public function getTransformedRolesForUser($user)
{
if (!method_exists($user, 'getRoles')) {
throw new 'Exception('User object has no "getRoles" method');
// Alternatively you could add an interface to you user object specifying
// the getRoles method or depend on the Symfony security bundle and
// type hint Symfony'Component'Security'Core'User'UserInterface
}
return $this->getTransformedRoles($user->getRoles();
}
public function getTransformedRoles(array $roles)
{
$transformedRoles = array()
foreach ($roles as $role) {
$role = strtoupper($role);
if (null !== $transformedRole = $this->getTransformedRole($role)) {
$transformedRoles[] = $transformedRole;
}
}
return $transformedRoles;
}
public function getTransformedRole($role)
{
if (self::ROLE_USER === $role) {
return null;
}
if (!array_key_exists($role, $this->roleTransformations)) {
throw 'Exception(sprintf(
'Role "%s" not found in acme.something.role_transformations', $role)
);
}
return $this->roleTransformations[$role];
}
}
然后可以将其注入服务或控制器中,并像一样使用
$transformer = $this->container->get('acme.something.role_transformer');
// Or injected via the DI
$roles = $transformer->getTransformedRolesForUser($user);
// For all of a users roles
$roles = $transformer->getTransformedRoles($user->getRoles());
// For an array of roles
$role = $transformer->getTransformedRole('ROLE_PROFILE_ONE');
// For a single role, or null if ROLE_USER
嗯,您已经尝试过执行嵌套循环来创建一个新数组,类似于以下内容?:
$users = array();
foreach ($entities as $entity)
{
$user = array();
$user[] = $entity->getUsername();
$user[] = $entity->getEmailCanonical();
$rolearray = [];
foreach ($entity->getRoles() as $role)
{
$rolearray[] = $roles[$role];
}
$user[] = $rolearray;
$user[] = $entity->getGroupNames() != NULL ? $entity->getGroupNames() : "-";
$users[] = $user;
}
我就是这么做的。你可以用array_map
代替,但我不明白为什么会有很大的不同。这似乎不太可能是资源密集型的,以至于导致服务器瘫痪,如果发生这种情况,我会强烈怀疑还有其他问题。