diff --git a/Entity/PermissionsGroup.php b/Entity/PermissionsGroup.php
index 95630e120..d3de7e2d5 100644
--- a/Entity/PermissionsGroup.php
+++ b/Entity/PermissionsGroup.php
@@ -49,9 +49,16 @@ class PermissionsGroup
*/
private $roleScopes;
+ /**
+ *
+ * @var \Doctrine\Common\Collections\Collection
+ */
+ private $groupCenters;
+
public function __construct()
{
$this->roleScopes = new \Doctrine\Common\Collections\ArrayCollection();
+ $this->groupCenters = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId()
diff --git a/Entity/RoleScope.php b/Entity/RoleScope.php
index d8a0d2256..fa39052fc 100644
--- a/Entity/RoleScope.php
+++ b/Entity/RoleScope.php
@@ -45,8 +45,15 @@ class RoleScope
*/
private $scope;
+ /**
+ *
+ * @var \Doctrine\Common\Collections\Collection
+ */
+ private $permissionsGroups;
+
public function __construct() {
$this->new = true;
+ $this->permissionsGroups = new \Doctrine\Common\Collections\ArrayCollection();
}
public function getId()
diff --git a/Form/Type/ScopePickerType.php b/Form/Type/ScopePickerType.php
new file mode 100644
index 000000000..838ecaae1
--- /dev/null
+++ b/Form/Type/ScopePickerType.php
@@ -0,0 +1,124 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+namespace Chill\MainBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
+use Doctrine\ORM\EntityRepository;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\OptionsResolver\Options;
+use Chill\MainBundle\Entity\Scope;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Chill\MainBundle\Templating\TranslatableStringHelper;
+
+/**
+ * Allow to pick amongst available scope for the current
+ * user.
+ *
+ * options :
+ *
+ * - `center`: the center of the entity
+ * - `role` : the role of the user
+ *
+ * @author Julien Fastré
+ */
+class ScopePickerType extends AbstractType
+{
+ /**
+ *
+ * @var AuthorizationHelper
+ */
+ protected $authorizationHelper;
+
+ /**
+ *
+ * @var TokenStorageInterface
+ */
+ protected $tokenStorage;
+
+ /**
+ *
+ * @var EntityRepository
+ */
+ protected $scopeRepository;
+
+ /**
+ *
+ * @var TranslatableStringHelper
+ */
+ protected $translatableStringHelper;
+
+ public function __construct(
+ AuthorizationHelper $authorizationHelper,
+ TokenStorageInterface $tokenStorage,
+ EntityRepository $scopeRepository,
+ TranslatableStringHelper $translatableStringHelper
+ ) {
+ $this->authorizationHelper = $authorizationHelper;
+ $this->tokenStorage = $tokenStorage;
+ $this->scopeRepository = $scopeRepository;
+ $this->translatableStringHelper = $translatableStringHelper;
+ }
+
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver
+ // create `center` option
+ ->setRequired('center')
+ ->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class ])
+ // create ``role` option
+ ->setRequired('role')
+ ->setAllowedTypes('role', ['string', \Symfony\Component\Security\Core\Role\Role::class ])
+ ;
+
+ $resolver
+ ->setDefault('class', Scope::class)
+ ->setDefault('placeholder', 'Choose the circle')
+ ->setDefault('choice_label', function(Scope $c) {
+ return $this->translatableStringHelper->localize($c->getName());
+ })
+ ->setNormalizer('query_builder', function(Options $options) {
+ $qb = $this->scopeRepository->createQueryBuilder('s');
+ $qb
+ // jointure to center
+ ->join('s.roleScopes', 'rs')
+ ->join('rs.permissionsGroups', 'pg')
+ ->join('pg.groupCenters', 'gc')
+ //->join('gc.users', 'user')
+ // add center constraint
+ ->where($qb->expr()->eq('IDENTITY(gc.center)', ':center'))
+ ->setParameter('center', $options['center']->getId())
+ // role constraints
+ ->andWhere($qb->expr()->eq('rs.role', ':role'))
+ ->setParameter('role', $options['role'])
+ // user contraint
+ ->andWhere(':user MEMBER OF gc.users')
+ ->setParameter('user', $this->tokenStorage->getToken()->getUser())
+ ;
+
+ return $qb;
+ })
+ ;
+ }
+
+ public function getParent()
+ {
+ return \Symfony\Bridge\Doctrine\Form\Type\EntityType::class;
+ }
+}
diff --git a/Form/Type/UserPickerType.php b/Form/Type/UserPickerType.php
new file mode 100644
index 000000000..9fbc34dac
--- /dev/null
+++ b/Form/Type/UserPickerType.php
@@ -0,0 +1,114 @@
+
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+namespace Chill\MainBundle\Form\Type;
+
+use Symfony\Component\Form\AbstractType;
+use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
+use Doctrine\ORM\EntityRepository;
+use Symfony\Component\OptionsResolver\Options;
+use Symfony\Component\OptionsResolver\OptionsResolver;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+use Chill\MainBundle\Entity\User;
+
+
+/**
+ * Pick a user available for the given role and center.
+ *
+ * Options :
+ *
+ * - `role` : the role the user can reach
+ * - `center`: the center a user can reach
+ *
+ * @author Julien Fastré
+ */
+class UserPickerType extends AbstractType
+{
+ /**
+ *
+ * @var AuthorizationHelper
+ */
+ protected $authorizationHelper;
+
+ /**
+ *
+ * @var TokenStorageInterface
+ */
+ protected $tokenStorage;
+
+ /**
+ *
+ * @var EntityRepository
+ */
+ protected $userRepository;
+
+ public function __construct(
+ AuthorizationHelper $authorizationHelper,
+ TokenStorageInterface $tokenStorage,
+ EntityRepository $userRepository
+ ) {
+ $this->authorizationHelper = $authorizationHelper;
+ $this->tokenStorage = $tokenStorage;
+ $this->userRepository = $userRepository;
+ }
+
+
+ public function configureOptions(OptionsResolver $resolver)
+ {
+ $resolver
+ // create `center` option
+ ->setRequired('center')
+ ->setAllowedTypes('center', [\Chill\MainBundle\Entity\Center::class ])
+ // create ``role` option
+ ->setRequired('role')
+ ->setAllowedTypes('role', ['string', \Symfony\Component\Security\Core\Role\Role::class ])
+ ;
+
+ $resolver
+ ->setDefault('class', User::class)
+ ->setDefault('empty_data', $this->tokenStorage->getToken()->getUser())
+ ->setDefault('choice_label', function(User $u) {
+ return $u->getUsername();
+ })
+ ->setNormalizer('query_builder', function(Options $options) {
+ $qb = $this->userRepository->createQueryBuilder('u');
+ $qb
+ // add center constraint
+ ->join('u.groupCenters', 'ug')
+ ->where($qb->expr()->eq('ug.center', ':center'))
+ ->setParameter('center', $options['center'])
+ // link to permission groups
+ ->join('ug.permissionsGroup', 'pg')
+ // role constraints
+ ->join('pg.roleScopes', 'roleScope')
+ ->andWhere($qb->expr()->eq('roleScope.role', ':role'))
+ ->setParameter('role', $options['role'])
+ // add active constraint
+ ->andWhere('u.enabled = :enabled')
+ ->setParameter('enabled', true)
+ ;
+
+ return $qb;
+ })
+ ;
+ }
+
+ public function getParent()
+ {
+ return \Symfony\Bridge\Doctrine\Form\Type\EntityType::class;
+ }
+}
diff --git a/Resources/config/doctrine/GroupCenter.orm.yml b/Resources/config/doctrine/GroupCenter.orm.yml
index 13b56067d..1fc2cc75d 100644
--- a/Resources/config/doctrine/GroupCenter.orm.yml
+++ b/Resources/config/doctrine/GroupCenter.orm.yml
@@ -19,4 +19,8 @@ Chill\MainBundle\Entity\GroupCenter:
permissionsGroup:
targetEntity: Chill\MainBundle\Entity\PermissionsGroup
cache:
- usage: NONSTRICT_READ_WRITE
\ No newline at end of file
+ usage: NONSTRICT_READ_WRITE
+ manyToMany:
+ users:
+ targetEntity: Chill\MainBundle\Entity\User
+ mappedBy: groupCenters
\ No newline at end of file
diff --git a/Resources/config/doctrine/PermissionsGroup.orm.yml b/Resources/config/doctrine/PermissionsGroup.orm.yml
index 100c2c17e..094bec153 100644
--- a/Resources/config/doctrine/PermissionsGroup.orm.yml
+++ b/Resources/config/doctrine/PermissionsGroup.orm.yml
@@ -17,6 +17,11 @@ Chill\MainBundle\Entity\PermissionsGroup:
manyToMany:
roleScopes:
targetEntity: Chill\MainBundle\Entity\RoleScope
+ inversedBy: permissionsGroups
cache:
usage: NONSTRICT_READ_WRITE
+ oneToMany:
+ groupCenters:
+ targetEntity: Chill\MainBundle\Entity\GroupCenter
+ mappedBy: permissionsGroup
\ No newline at end of file
diff --git a/Resources/config/doctrine/RoleScope.orm.yml b/Resources/config/doctrine/RoleScope.orm.yml
index 983db8712..f9a20f38e 100644
--- a/Resources/config/doctrine/RoleScope.orm.yml
+++ b/Resources/config/doctrine/RoleScope.orm.yml
@@ -21,4 +21,8 @@ Chill\MainBundle\Entity\RoleScope:
nullable: true
cache:
usage: NONSTRICT_READ_WRITE
+ manyToMany:
+ permissionsGroups:
+ targetEntity: Chill\MainBundle\Entity\PermissionsGroup
+ mappedBy: roleScopes
\ No newline at end of file
diff --git a/Resources/config/doctrine/User.orm.yml b/Resources/config/doctrine/User.orm.yml
index acb9b6b50..05b434260 100644
--- a/Resources/config/doctrine/User.orm.yml
+++ b/Resources/config/doctrine/User.orm.yml
@@ -30,6 +30,7 @@ Chill\MainBundle\Entity\User:
manyToMany:
groupCenters:
targetEntity: Chill\MainBundle\Entity\GroupCenter
+ inversedBy: users
cache:
usage: NONSTRICT_READ_WRITE
diff --git a/Resources/config/services/form.yml b/Resources/config/services/form.yml
index 03f244e1d..e205292bd 100644
--- a/Resources/config/services/form.yml
+++ b/Resources/config/services/form.yml
@@ -89,5 +89,24 @@ services:
chill.main.form.date_type:
class: Chill\MainBundle\Form\Type\ChillDateType
+ tags:
+ - { name: form.type }
+
+ chill.main.form.pick_user_type:
+ class: Chill\MainBundle\Form\Type\UserPickerType
+ arguments:
+ - "@chill.main.security.authorization.helper"
+ - "@security.token_storage"
+ - "@chill.main.user_repository"
+ tags:
+ - { name: form.type }
+
+ chill.main.form.pick_scope_type:
+ class: Chill\MainBundle\Form\Type\ScopePickerType
+ arguments:
+ - "@chill.main.security.authorization.helper"
+ - "@security.token_storage"
+ - "@chill.main.scope_repository"
+ - "@chill.main.helper.translatable_string"
tags:
- { name: form.type }
\ No newline at end of file
diff --git a/Resources/config/services/repositories.yml b/Resources/config/services/repositories.yml
index 754d770c7..3f40e82dc 100644
--- a/Resources/config/services/repositories.yml
+++ b/Resources/config/services/repositories.yml
@@ -10,3 +10,9 @@ services:
factory: ["@doctrine.orm.entity_manager", getRepository]
arguments:
- "Chill\\MainBundle\\Entity\\User"
+
+ chill.main.scope_repository:
+ class: Doctrine\ORM\EntityRepository
+ factory: ["@doctrine.orm.entity_manager", getRepository]
+ arguments:
+ - "Chill\\MainBundle\\Entity\\Scope"
\ No newline at end of file