将参数传递给Entity

时间:2015-05-13 15:29:42

标签: php symfony

我是symfony的新手。我希望能够将管理员角色名称配置到我的应用程序中。我需要做一些事情:(在控制器中)

if($this->getUser()->isAdmin()) {
   //..
}

在用户实体中,我可以将isAdmin定义为:

function isAdmin()
{
   $this->hasRole('ROLE_ADMIN');
}

但是这样,无法配置ROLE_ADMIN。请注意,我不想将“角色名称”作为param(或默认参数)传递给isAdmin函数。我希望它像我可以将对象传递给用户实体:

public function __construct(AuthConfiguration $config)
{
   $this->config = $config;
}

public function isAdmin()
{
   return $this->hasRole($this->config->getAdminRoleName());
}

但是如何将对象传递给用户实体,因为用户创建是由存储库处理的?

2 个答案:

答案 0 :(得分:0)

您可以使用此捆绑包为角色设置自定义Doctrine DBAL ENUM类型:https://github.com/fre5h/DoctrineEnumBundle

// Augment the 'Window' type
interface Window {
    parentFunc(): void;
}

window.opener.parentFunc();

在config.yml中注册新类型:

<?php

namespace AppBundle\DBAL\Types;

use Fresh\Bundle\DoctrineEnumBundle\DBAL\Types\AbstractEnumType;

class RoleType extends AbstractEnumType
{
    const ROLE_USER          = 'ROLE_USER';
    const ROLE_ADMIN         = 'ROLE_ADMIN';
    const ROLE_SUPER_ADMIN   = 'ROLE_SUPER_ADMIN';
    const ROLE_PROJECT_OWNER = 'ROLE_PROJECT_OWNER';

    /**
     * @var array Readable choices
     * @static
     */
    protected static $choices = [
        self::ROLE_USER          => 'role.user',
        self::ROLE_ADMIN         => 'role.administrator',
        self::ROLE_SUPER_ADMIN   => 'role.super_administrator',
        self::ROLE_PROJECT_OWNER => 'role.project_owner',
    ];
}

将用户的角色字段配置为ENUM RoleType类型:

doctrine:
    dbal:
        mapping_types:
            enum: string
        types:
            RoleType: AppBundle\DBAL\Types\RoleType

并在您的实体或存储库或其他任何地方使用它:

use Fresh\Bundle\DoctrineEnumBundle\Validator\Constraints as DoctrineAssert;

...

/**
 * @DoctrineAssert\Enum(entity="AppBundle\DBAL\Types\RoleType")
 * @ORM\Column(name="role", type="RoleType")
 */
protected $role = RoleType::ROLE_USER;

答案 1 :(得分:0)

只有在使用关键字new创建对象的新实例时,才会调用构造函数。即使它是hydrates个实体,Doctrine也不会调用构造函数。

您可以创建own entity hydrator并调用实体的构造函数,但我还没有尝试过此解决方案。它可能不那么可维护。

我想提供一个我更喜欢的替代方案(你可能不会)。

在我的所有项目中,架构如下: Controller <-> Service <-> Repository <-> Entity

这种架构的优点是使用dependency injection with services

在您的services.yml

services:
    my.user:
        class: Acme\HelloBundle\Service\MyUserService
        arguments:
            # First argument
            # You could also define another service that returns
            # a list of roles.
            0:
                admin: ROLE_ADMIN
                user: ROLE_USER

在您的服务中:

namespace Acme\HelloBundle\Service;

use Symfony\Component\Security\Core\User\UserInterface;

class MyUserService {

    protected $roles = array();

    public function __constructor($roles)
    {
        $this->roles = $roles;
    }

    public function isAdmin(UserInterface $user = null)
    {
        if ($user === null) {
            // return current logged-in user
        }

        return $user->hasRole($this->roles['admin']);
    }
}

在您的控制器中:

// Pass a user
$this->get('my.user')->isAdmin($this->getUser());

// Use current logged-in user
$this->get('my.user')->isAdmin();

它远离您正在寻找的解决方案,但在我看来,它似乎更符合Symfony2提供的内容。

另一个优点是您可以扩展管理员的定义。 例如,在我的项目中,我的用户服务有一个isAdmin() method,它有额外的逻辑。