У меня была такая же проблема, также с использованием аннотаций.
Примечание. Поскольку у некоторых читателей возникли проблемы со сборкой всего вместе, я создал репозиторий 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
provider
. Легко достичь. - person mate64   schedule 28.03.2014