FOSUserBundle Override Roles — Роли свойств в Acme\DemoBundle\Entity\User уже объявлены, но их нужно объявить только один раз.

Мне нравится, что большинство людей пытаются переопределить роли FOSUserBundle, чтобы я мог сопоставить их ManyToMany с ролевой сущностью.

К сожалению, по какой-то причине из-за сопоставления модели/пользователя я получаю следующее:

Property "roles" in "Acme\DemoBundle\Entity\User" was already declared, but it must be declared only once

Кажется, в этой проблеме git, опубликованной в FOSUserBundle, упоминается обходной путь:

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

Я Doctrine ORM и использую аннотации для сопоставления, а не yml или xml. Последняя версия Symfony (2.4) и последняя версия FOSUB.

Я попробовал альтернативный вариант, скопировав все в свой Entity и не расширив, но, честно говоря, это все испортило.

Я пытаюсь попытаться создать свою собственную модель/пользователя, расширяющую FOSUserBundle/Model/User без сопоставлений. А затем расширьте мою сущность/пользователя из этого. Я пытался, но у меня все еще есть та же проблема. Я предполагаю, что сделал это неправильно.

Может кто-нибудь посоветовать/показать, как мне правильно это сделать?

Мне действительно нужно иметь возможность переопределять роли, поскольку, хотя FOSUserBundle великолепен, адаптация ролей не очень хороша. Хотя я понимаю, что в то время это был единственный способ, которым они могли это сделать, и его изменение сейчас ломает BC.

Надеюсь, кто-то может помочь.

С уважением Пол Паундер


person Paul Pounder    schedule 28.03.2014    source источник
comment
Почему бы не использовать функцию групп FOSUserBundle?   -  person Emii Khaos    schedule 28.03.2014
comment
Не используйте пакет пользователя, предоставленный FOS. Это будет адская поездка. Лучше создайте своего собственного пользователя provider. Легко достичь.   -  person mate64    schedule 28.03.2014
comment
Я уже использую группы как часть своего приложения для хранения пользователей в компаниях и применения к ним ролей. Мне по-прежнему нужно иметь возможность применять роли к конкретным пользователям, а не группировать их. @cept0 - согласен, но он идеально подходит для того, для чего он мне нужен (кроме ролей) :)   -  person Paul Pounder    schedule 28.03.2014
comment
Возможно, в конечном итоге я перейду к использованию Групп и изменю способ хранения компаний, но решил сначала изучить этот вопрос. Кроме того, FOSUserBundle хорошо интегрируется с другими пакетами, которые я использую, поэтому не хочу сейчас прерывать эту связь.   -  person Paul Pounder    schedule 28.03.2014
comment
@PaulPounder Что касается вашего комментария о целостности пользовательского пакета FOS: нет особой волшебной интеграции FOS User Bundle. Пакет интегрируется в Symfony, и другие пакеты могут использовать этот мост.   -  person mate64    schedule 28.03.2014
comment
Примерно это я и имел в виду :-)   -  person Paul Pounder    schedule 28.03.2014
comment
У меня были проблемы с решением этого с помощью FOS, но, в конце концов, это не так уж много работы, всего несколько настроек, просто много чтения... :)   -  person juanmf    schedule 07.07.2014


Ответы (1)


У меня была такая же проблема, также с использованием аннотаций.

Примечание. Поскольку у некоторых читателей возникли проблемы со сборкой всего вместе, я создал репозиторий gitHub с моим UserBundle. Если вы обнаружите, что в этом HowTo чего-то не хватает, дайте мне знать, чтобы я добавил это.

В этом посте рассматриваются три аспекта: Роли на основе БД с реализацией древовидной структуры, конфигурация инфраструктуры для поддержки RoleHierarchy (getReachableRoles) для ролей БД. Без которого было бы бесполезно иметь роли в БД. И подписчикам Doctrine для создания ролей при сохранении определенной сущности.

Изменения, которые пришлось внести FOS, были глубокими и хорошо документированными, но я должен сказать, что один пример кода из HowTo Use помешал бы мне много читать (не жалуюсь, по крайней мере, теперь я знаю немного о проходах компилятора).

Роли в БД

Я использую 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

В copmoser.json я обновил пакет доктрины, чтобы он включал необходимые файлы:

"require": {
...
    "doctrine/doctrine-bundle": "~1.3@dev",
...
}

В файле 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
            )
        );
}

Это зависимость, импортированная новой версией доктрины-комплекта:

`\Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass`. 

Я предполагаю, что эта информация о сопоставлении добавлена ​​позже, чем FOSUserBundle, потому что я просто повторил процесс (упрощенный только для ORM), который я видел в FOSUerBundle.php, надеясь, что он будет иметь приоритет, и он это сделал.

Отображения в User.orm.xml являются точной копией ./vendor/friendsofsymfony/user-bundle/FOS/UserBundle/Resources/config/doctrine/model/User.orm.xml с закомментированной строкой #35. Это удаляет конфликтующее сопоставление ролей в сопоставленном суперклассе.

<!--<field name="roles" column="roles" type="array" />-->

Отныне вы просто делаете то, что хотели сделать в первую очередь, реализуете свою идею Ролей. Вот мой: пользовательский класс, который расширяет FOS\UserBundle\Model\User, но теперь с сопоставлениями, которые вы использовали в своем пакете.

src/Application/UsuarioBundle/Entity/Role.php

И класс ролей:

src/Application/UsuarioBundle/Entity/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;

Тем не менее, я не представляю иерархии ролей, которые мне нужны.

Надеюсь, это полезно для кого-то. Я уверен, что вы уже решили эту проблему или потеряли работу :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

Реализация иерархии ролей

Файлы, задействованные в решении:

// 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

вы можете увидеть файлы в этой сути

Или получить доступ к каждому файлу напрямую (поскольку Gist не сохраняет порядок перечисления).

src/Application/UsuarioBundle/Role/RoleHierarchy.php

src/Application/UsuarioBundle/Resources/config/services.xml

src/Application/UsuarioBundle/Entity/Role.php

src/Application/UsuarioBundle/Entity/Usuario.php

app/config/security.yml

src/Application/UsuarioBundle/Controller/RoleController.php

src/Application/UsuarioBundle/Form/RoleType.php

src/Application/UsuarioBundle/Resources/views/Role/edit.html.twig

Документация:

поваренная книга: избиратели безопасности

Компоненты: Безопасность

справка: Приоритеты сервисных тегов

Источник: RoleHierarchyInterface

Подписчики доктрины

Вы зайдете так далеко, чтобы понять, что чего-то не хватает...

Основная причина, по которой я перенес роли в БД, заключается в том, что я имею дело с динамическим (со структурной точки зрения) приложением, которое позволяет пользователю настраивать рабочий процесс. Когда я добавляю новую область с новым процессом, с новым действием (или обновляю либо имя, либо отношения родитель-потомок, либо удаляю их), мне нужно создать новые роли automatically.

Тогда вы думаете о подписчиках Doctrine для LyfeCycleEvents, но добавление новых сущностей в PrePersist/PreUpdate потребует вложенной очистки, что в моем случае все испортит, это проще, когда вам просто нужно обновить некоторые поля в уже "computedChanges" сущностях.

Итак, то, что я использовал для перехвата и создания/редактирования/удаления ролей, — это onFlush, после чего computChangeSet() отлично работает для добавления новых объектов.

В качестве примера я оставлю ProcessRolesSubscriber Gist.

person juanmf    schedule 07.07.2014
comment
Ну, я ценю вашу настойчивость с редактором StackOverflow. Это отличное решение. Я не решил это, если честно, и, к счастью, все еще на работе :-) - person Paul Pounder; 08.07.2014
comment
спасибо, я рад, что вы все еще в своей работе :). Я реализую для этого RoleHierarchyVoter. Я добавлю это к ответу, когда закончу. - person juanmf; 08.07.2014
comment
спасибо, очень полезный пост. Но есть проблема. Когда вы хотите полностью удалить $roles из User, например, если вы храните его в отдельной базе данных, потому что EntityManager загружает метаданные из всех родительских классов, поэтому в результате произойдет сбой, за исключением того, что нет такого столбца «роли». - person Dmytro; 17.07.2014
comment
Спасибо. Вы должны реализовать интерфейс провайдера пользователя, просто убедитесь, что вы реализовали метод getRoles() и rrпереместите поле roles из user. Затем обновите свою схему. Извините, я не могу свериться со своим кодом. Пишу через мобильный. - person juanmf; 17.07.2014
comment
Я следовал точным шагам, но получил это исключение [Doctrine\ORM\Mapping\MappingException] Роли свойств в St\UserBundle\Entity\User уже были объявлены, но они должны быть объявлены только один раз - person vishal; 22.08.2014
comment
Странно, вы закомментировали XML-сопоставления ролей? Если это так, вы можете поиграться с порядком загрузки пакетов в appKernel.php. проверить репозиторий git со всем USerBndle. - person juanmf; 22.08.2014
comment
Взяв идеи тут и там, я создал свой собственный репозиторий UserBundle для обработки иерархических ролей, прикрепленных к группам, и пользователей в них без прямого отношения к ролям, чтобы управлять ими в пакетном режиме. Панель администратора все еще находится на рассмотрении, отзывы и запросы на включение приветствуются: D github.com/matheo/UserBundle - person Mateo Tibaquira; 30.09.2014
comment
Мне нужно было заменить FOS\UserBundle\Entity на путь к папке, содержащей мой пользовательский объект, чтобы он работал, но тогда да, спасибо !! оно работает ! - person Sébastien; 09.01.2015