Symfony角色层次结构

时间:2016-09-04 10:34:06

标签: security symfony

目前我正在构建基于旧数据库的应用程序。 在此数据库中有UserClasses,例如:

UserclassEntity:

  • ID
  • 类名
    • UserclassEntity

所以我重写了核心服务并将我的自定义选民添加到security.voter:

security.role_hierarchy:
  class: AppBundle\Security\Role\RoleHierarchy
  arguments:
    - '%security.role_hierarchy.roles%'
    - '@app.user_class_repository'

security.access.admin_voter:
  class: AppBundle\Security\Voter\AdminVoter
  arguments: ['@security.role_hierarchy']
  tags:
    - { name: security.voter, priority: 400 }
  public: false

所以我基于Original RoleHierarchy Class实现了所有需要的方法:

class RoleHierarchy extends orig_RoleHierarchy
{
  /**
   * @var array
   */
  private $hierarchy;
  /**
   * @var UserclassRepository
   */
  private $userClassRepository;
  /**
   * @var RoleManager
   */
  private $manager;
  /**
   * @var UserclassRepository
   */
  private $userclassRepository;

  /**
   * @param UserclassRepository $userclassRepository
   * @param array               $hierarchy
   */
  public function __construct(UserclassRepository $userclassRepository, array $hierarchy)
  {
      $this->hierarchy = $hierarchy;
      $this->userclassRepository = $userclassRepository;
      $map = $this->buildRolesTree($this->hierarchy);
      parent::__construct($map);
  }

  /**
   * Here we build an array with roles. It looks like a two-levelled tree -   just
   * like original Symfony roles are stored in security.yml
   *
   * @param array $hierarchy
   *
   * @return array
   */
  private function buildRolesTree(array $hierarchy = [])
  {
      $userclasses = $this->userclassRepository->findAll();
      foreach ($userclasses as $userclass) {
          /** @var $userclass Userclass */
          if ($userclass->getParent()) {
              if (!isset($hierarchy['ROLE_' . $userclass->getName()])) {
                  $hierarchy['ROLE_' . $userclass->getName()] = array();
              }
              $hierarchy['ROLE_' . $userclass->getName()][] = 'ROLE_' .   $userclass->getParent()->getName();
          } else {
              if (!isset($hierarchy['ROLE_' . $userclass->getName()])) {
                  $hierarchy['ROLE_' . $userclass->getName()] = array();
              }
          }
      }
      return $hierarchy;
  }
}

但是当我清除prod环境的缓存时,我收到一个错误:

[Symfony\Component\Debug\Exception\FatalErrorException]
Compile Error: require(): Failed opening required   'E:\projects\sf2\app\var\cache\pro_/doctrine/orm/Proxies\__CG__AppBundleEntityUserclass.php' (include_path='.;C:\php\pear')

此异常因为缺少代理类而抛出,但我真的不知道如何以另一种方式执行此操作。我需要这个实体,我需要基于此实体的Role_Hierarchy。

有关如何解决此问题的任何建议吗?

建议更多文件: doctrine是config.yml的一部分

doctrine:
dbal:
    driver:   pdo_mysql
    host:     "%database_host%"
    port:     "%database_port%"
    dbname:   "%database_name%"
    user:     "%database_user%"
    password: "%database_password%"
    charset:  LATIN1
    mapping_types:
      enum: string
orm:
    auto_generate_proxy_classes: "%kernel.debug%"
    entity_managers:
      default:
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        dql:
          string_functions:
            COLLATE: AppBundle\DQL\CollateFunction

Doctrine ORM:

<?xml version="1.0" encoding="utf-8"?>
<doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd">
  <entity name="AppBundle\Entity\Userclass" table="userclass" repository-class="AppBundle\Repository\UserclassRepository">
    <indexes>
      <index name="name" columns="name,classname,class,color"/>
    </indexes>
    <id name="id" type="integer" column="id">
      <generator strategy="AUTO"/>
    </id>
    <field name="name" type="string" column="name" length="50" nullable="false">
      <options>
        <option name="fixed"/>
      </options>
    </field>
    <field name="classname" type="string" column="classname" length="50" nullable="false">
      <options>
        <option name="fixed"/>
      </options>
    </field>
    <field name="class" type="integer" column="class" nullable="false">
      <options>
        <option name="unsigned"/>
      </options>
    </field>
    <field name="color" type="string" column="color" length="10" nullable="false">
      <options>
        <option name="fixed"/>
      </options>
    </field>
    <many-to-one field="parent" target-entity="AppBundle\Entity\Userclass">
        <join-column name="parent_id" referenced-column-name="id" />
    </many-to-one>
  </entity>
</doctrine-mapping>

1 个答案:

答案 0 :(得分:1)

我尝试了很多东西,但没有真正奏效。正如我发现的那样,代理从doctrine生成Task:orm在与Symfony 3.1.x兼容的最新VErsion中被删除。

如果有人为此奋斗,最好的方法(我能找到)就是设置 来自&#34;%kernel.debug%&#34;的auto_generate_proxy_classes;真的

orm:
   auto_generate_proxy_classes: "%kernel.debug%"

就像地狱一样简单,只有在dev环境中这个参数才是真的。在生产模式下运行应用程序,将此显示为false,因此不会根据需要生成Proxyclasses。在教义有机会生成所需代理之前,角色层次结构以某种方式被触发。

通过启用此auto_generate-option,可以根据需要生成这些代理,并缓存这些代理。所以任何最小的性能中断都只会发生一次。在生成之后,这些类也会缓存。

在我的应用程序中,我无法找到任何相关甚至很少的性能问题。