FOSUserBundle覆盖角色 - 已声明"Acme\DemoBundle\Entity\User"中的属性"角色",但必须仅声明一次

Pau*_*der 2 php symfony doctrine-orm fosuserbundle symfony-2.4

我喜欢大多数人试图覆盖FOSUserBundle角色,因此我可以将ManyToMany映射到角色实体.

不幸的是由于某些原因,由于模型/用户的映射,我得到以下内容:

Property "roles" in "Acme\DemoBundle\Entity\User" was already declared, but it must be declared only once
Run Code Online (Sandbox Code Playgroud)

在FOSUserBundle中发布的这个git问题中似乎提到了一些解决方法:

https://github.com/FriendsOfSymfony/FOSUserBundle/pull/1081#issuecomment-19027818

我是Doctrine ORM并使用Annotations映射而不是yml或xml.最新的Symfony(2.4)和最新的FOSUB.

我通过将所有内容复制到我的实体而不是扩展来尝试替代选项,但说实话,这搞砸了所有内容.

我试图创建我自己的模型/用户扩展FOSUserBundle/Model/User没有映射的想法.然后从中扩展我的实体/用户.我试过但我仍然遇到同样的问题.我假设我做错了.

有人可以建议/展示我将如何正确地做到这一点?

我真的需要能够覆盖角色,因为尽管FOSUserBundle很棒,角色的适应性也不是很好.虽然我当时很欣赏这是他们能够做到这一点的唯一方法,现在改变它现在打破BC.

希望有人能提供帮助.

亲切的问候Paul Pounder

jua*_*nmf 16

我也有同样的问题,也使用Annotations.

注意:由于一些读者将所有问题放在一起,我使用UserBundle创建了一个gitHub repo.如果您发现此HowTo中缺少某些内容,请告知我,以便我添加它.

本文包括三个方面,基于数据库的角色与树结构实现,框架配置也支持DB角色的RoleHierarchy(getReachableRoles).没有它,毕竟在DB中扮演角色是没用的.并且Doctrine订阅者在某些实体上持久化时创建角色.

FOS必须做出的更改很深入,并且有很好的文档记录,但我必须说单个HowTo Use示例代码会阻止我阅读很多内容(不抱怨,至少我现在对编译器通过了一点了解.)

对DB的角色

我正在使用Sf 2.4,但这应该从2.3开始工作.这是我的解决方案涉及的文件,考虑每个文件一步:

./:
composer.json

src/Application/UsuarioBundle/:
ApplicationUsuarioBundle.php

src/Application/UsuarioBundle/Resources/config/doctrine/model/:
User.orm.xml

src/Application/UsuarioBundle/Entity/:
Role.php  Usuario.php
Run Code Online (Sandbox Code Playgroud)

copmoser.json我升级的doctrine-bundle中,它包含了所需的文件:

"require": {
...
    "doctrine/doctrine-bundle": "~1.3@dev",
...
}
Run Code Online (Sandbox Code Playgroud)

Bundle.php文件中,您必须注册编译器传递

namespace Application\UsuarioBundle;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;

class ApplicationUsuarioBundle extends Bundle
{

    public function build(ContainerBuilder $container)
    {
        parent::build($container);
        $mappings = array(
            realpath(__DIR__ . '/Resources/config/doctrine/model') => 'FOS\UserBundle\Model',
            realpath(__DIR__ . '/Resources/config/doctrine/model') => 'FOS\UserBundle\Entity', 
        );

        $container->addCompilerPass(
            DoctrineOrmMappingsPass::createXmlMappingDriver(
                $mappings, array('fos_user.model_manager_name'), false
            )
        );
}
Run Code Online (Sandbox Code Playgroud)

这是新版本的doctrine-bundle导入的依赖项:

`\Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass`. 
Run Code Online (Sandbox Code Playgroud)

我假设这个映射信息是在FOSUSerBundle之后添加的,因为我只是重复了我在FOSUerBundle.php中看到的过程(仅针对ORM进行了简化),希望它优先使用它.

映射User.orm.xml./vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/config/doctrine/model/User.orm.xml第35行注释掉的完全副本.这将删除映射的超类中角色的冲突映射.

<!--<field name="roles" column="roles" type="array" />-->
Run Code Online (Sandbox Code Playgroud)

从现在开始,你只需要在第一名做你想做的事,实现你对角色的想法.这是我的:扩展FOS\UserBundle\Model\User的用户类,但现在使用您在捆绑中使用的映射.

SRC /应用/ UsuarioBundle /实体/ Role.php

和角色类:

SRC /应用/ UsuarioBundle /实体/ Usuario.php

执行此操作后,您可以看到正确的SQL更改由架构更新--dump-sql转储.

$ php app/console doctrine:schema:update --dump-sql --complete
CREATE TABLE fos_usuario_role (usuario_id INT NOT NULL, role_id INT NOT NULL, INDEX IDX_6DEF6B87DB38439E (usuario_id), INDEX IDX_6DEF6B87D60322AC (role_id), PRIMARY KEY(usuario_id, role_id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
CREATE TABLE fos_role (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(30) NOT NULL, role VARCHAR(20) NOT NULL, UNIQUE INDEX UNIQ_4F80385A57698A6A (role), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci ENGINE = InnoDB;
ALTER TABLE fos_usuario_role ADD CONSTRAINT FK_6DEF6B87DB38439E FOREIGN KEY (usuario_id) REFERENCES fos_user (id) ON DELETE CASCADE;
ALTER TABLE fos_usuario_role ADD CONSTRAINT FK_6DEF6B87D60322AC FOREIGN KEY (role_id) REFERENCES fos_role (id) ON DELETE CASCADE;
ALTER TABLE fos_user DROP roles;
Run Code Online (Sandbox Code Playgroud)

不过,我并不代表我需要的角色层次结构.

希望它对某人有用.我相信你已经解决了这个问题,或者失去了工作:p.

我遵循的文档:

https://github.com/symfony/symfony/pull/7599
https://github.com/FriendsOfSymfony/FOSUserBundle/pull/1081
http://symfony.com/doc/2.4/cookbook/doctrine/mapping_model_classes.html
http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html
Run Code Online (Sandbox Code Playgroud)

RoleHierarchy实现

解决方案中涉及的文件:

// The Magician, for I just re-instantiated RoleHierarchyVoter & ExpressionVoter 
// classes as ApplicationUsuarioBundle services; passing my RoleHierarchy 
// implementation. 
src/Application/UsuarioBundle/Role/RoleHierarchy.php

// duplicating security.access.expression_voter && 
// application_usuario.access.role_hierarchy_voter BUT WITH NEW 
// RoleHierarchy ARGUMENT
src/Application/UsuarioBundle/Resources/config/services.xml

// Entities, important methods are collection related
src/Application/UsuarioBundle/Entity/Role.php
src/Application/UsuarioBundle/Entity/Usuario.php

// Edited, commented out regular hardcoded roleHierarchy
app/config/security.yml

// CRUD related, sample files will add dependencies to lexik/form-filter-bundle; 
// docdigital/filter-type-guesser; white-october/pagerfanta-bundle
src/Application/UsuarioBundle/Controller/RoleController.php
src/Application/UsuarioBundle/Form/RoleType.php
src/Application/UsuarioBundle/Resources/views/Role/edit.html.twig
src/Application/UsuarioBundle/Resources/views/Role/index.html.twig
src/Application/UsuarioBundle/Resources/views/Role/new.html.twig
src/Application/UsuarioBundle/Resources/views/Role/show.html.twig
Run Code Online (Sandbox Code Playgroud)

你可以在这个要点中看到文件

或直接访问每个文件,(因为Gist不保留列表顺序).

SRC /应用/ UsuarioBundle /角色/ RoleHierarchy.php

SRC /应用/ UsuarioBundle /资源/配置/的services.xml

SRC /应用/ UsuarioBundle /实体/ Role.php

SRC /应用/ UsuarioBundle /实体/ Usuario.php

应用程序/配置/ security.yml

SRC /应用/ UsuarioBundle /控制器/ RoleController.php

SRC /应用/ UsuarioBundle /表格/ RoleType.php

SRC /应用/ UsuarioBundle /资源/视图/角色/ edit.html.twig

随后的文件:

食谱:安全选民

组件:安全性

reference:服务标签优先级

Souce:RoleHierarchyInterface

学说订阅者

你会发现这很远,意识到缺少了一些东西......

我将Roles移植到数据库的主要原因是因为我正在处理动态(从Structural透视图)应用程序,该应用程序使用户能够配置工作流.当我添加一个新的区域,一个新的进程,一个新的Activity(或更新名称或父子关系,或删除任何),我需要生成新的角色automatically.

然后你想到了LyfeCycleEvents的Doctrine订阅者,但是在PrePersist/PreUpdate中添加新实体将要求嵌套刷新,在我的情况下会弄乱,当你只需更新已经"computedChanges"实体的某些字段时它就更容易了.

所以我用来挂钩和创建/编辑/删除角色的是onFlush,此时computeChangeSet()适用于添加新实体.

我将以ProcessRolesSubscriber Gist为例.

  • 好吧,我感谢您对StackOverflow编辑器的坚持不懈.这是一个很好的解决方案.说实话,我没有解决它,幸好还是在工作中:-) (2认同)