diff --git a/Controller/SingleTaskController.php b/Controller/SingleTaskController.php
index 4e3662a9e..2125bb2f3 100644
--- a/Controller/SingleTaskController.php
+++ b/Controller/SingleTaskController.php
@@ -338,11 +338,7 @@ class SingleTaskController extends Controller
*
* @Route(
* "/{_locale}/task/singletask/list",
- * name="chill_task_singletask_list",
- * options={ "menus": {
- * "person" : { "order": 400, "label": "Associated tasks" } ,
- * "section": { "order": 400, "label": "Tasks", "icons": "tasks" }
- * }}
+ * name="chill_task_singletask_list"
* )
*/
public function listAction(
diff --git a/Menu/PersonMenuBuilder.php b/Menu/PersonMenuBuilder.php
new file mode 100644
index 000000000..199645aa5
--- /dev/null
+++ b/Menu/PersonMenuBuilder.php
@@ -0,0 +1,81 @@
+
+ *
+ * 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\TaskBundle\Menu;
+
+use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
+use Knp\Menu\MenuItem;
+use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
+use Chill\TaskBundle\Security\Authorization\TaskVoter;
+use Symfony\Component\Translation\TranslatorInterface;
+
+/**
+ *
+ *
+ * @author Julien Fastré
+ */
+class PersonMenuBuilder implements LocalMenuBuilderInterface
+{
+ /**
+ *
+ * @var TranslatorInterface
+ */
+ protected $translator;
+
+ /**
+ *
+ * @var AuthorizationCheckerInterface
+ */
+ protected $authorizationChecker;
+
+ public function __construct(
+ AuthorizationCheckerInterface $authorizationChecker,
+ TranslatorInterface $translator)
+ {
+ $this->translator = $translator;
+ $this->authorizationChecker = $authorizationChecker;
+ }
+
+
+ public function buildMenu($menuId, MenuItem $menu, array $parameters)
+ {
+ /* @var $person \Chill\PersonBundle\Entity\Person */
+ $person = $parameters['person'] ?? null;
+
+ if ($this->authorizationChecker->isGranted(TaskVoter::SHOW, $person)) {
+ $menu->addChild(
+ $this->translator->trans(
+ $menuId === 'person' ? 'Associated tasks' : 'Tasks'), [
+ 'route' => 'chill_task_singletask_list',
+ 'routeParameters' => $menuId === 'person' ?
+ [ 'person_id' => $person->getId() ]
+ :
+ null,
+ ])
+ ->setExtra('order', 400)
+ ;
+ if ($menuId === 'section') {
+ $menu->setExtra('icons', 'tasks');
+ }
+ }
+ }
+
+ public static function getMenuIds(): array
+ {
+ return ['person'];
+ }
+}
diff --git a/Resources/config/services/menu.yml b/Resources/config/services/menu.yml
index d1c8344aa..cbaded857 100644
--- a/Resources/config/services/menu.yml
+++ b/Resources/config/services/menu.yml
@@ -6,3 +6,10 @@ services:
$translator: '@Symfony\Component\Translation\TranslatorInterface'
tags:
- { name: 'chill.menu_builder' }
+
+ Chill\TaskBundle\Menu\PersonMenuBuilder:
+ arguments:
+ $authorizationChecker: '@Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface'
+ $translator: '@Symfony\Component\Translation\TranslatorInterface'
+ tags:
+ - { name: 'chill.menu_builder' }
diff --git a/Security/Authorization/TaskVoter.php b/Security/Authorization/TaskVoter.php
index c28fcf942..ad8895892 100644
--- a/Security/Authorization/TaskVoter.php
+++ b/Security/Authorization/TaskVoter.php
@@ -28,6 +28,7 @@ use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\Person;
+use Symfony\Component\Security\Core\Role\Role;
/**
*
@@ -80,7 +81,10 @@ class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterf
{
return ($subject instanceof AbstractTask && in_array($attribute, self::ROLES))
||
- ($subject instanceof Person && $attribute === self::CREATE);
+ ($subject instanceof Person && \in_array($attribute, [ self::CREATE, self::SHOW ]))
+ ||
+ (NULL === $subject && $attribute === self::SHOW )
+ ;
}
/**
@@ -105,8 +109,13 @@ class TaskVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterf
}
$person = $subject->getPerson();
- } else {
+ } elseif ($subject instanceof Person) {
$person = $subject;
+ } else {
+ // subject is null. We check that at least one center is reachable
+ $centers = $this->authorizationHelper->getReachableCenters($token->getUser(), new Role($attribute));
+
+ return count($centers) > 0;
}
if (!$this->accessDecisionManager->decide($token, [PersonVoter::SEE], $person)) {