mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Minor fixes for closing accompanying course:
* check that transition can be applyied in menu; * change organisation for activityVoter, and check for authorization in Activity Controller * fix label 'create' in accompanying course document * minor fix in accompanying course document voter * change color when course is closed and show old user, and startdate / enddate
This commit is contained in:
parent
4c1e416a14
commit
0867965d9c
@ -269,8 +269,7 @@ final class ActivityController extends AbstractController
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO revoir le Voter de Activity pour tenir compte qu'une activité peut appartenir a une période
|
$this->denyAccessUnlessGranted(ActivityVoter::CREATE, $entity);
|
||||||
// $this->denyAccessUnlessGranted('CHILL_ACTIVITY_CREATE', $entity);
|
|
||||||
|
|
||||||
$form = $this->createForm(ActivityType::class, $entity, [
|
$form = $this->createForm(ActivityType::class, $entity, [
|
||||||
'center' => $entity->getCenter(),
|
'center' => $entity->getCenter(),
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
namespace Chill\ActivityBundle\DataFixtures\ORM;
|
namespace Chill\ActivityBundle\DataFixtures\ORM;
|
||||||
|
|
||||||
|
use Chill\ActivityBundle\Security\Authorization\ActivityVoter;
|
||||||
use Doctrine\Common\DataFixtures\AbstractFixture;
|
use Doctrine\Common\DataFixtures\AbstractFixture;
|
||||||
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
|
||||||
use Doctrine\Persistence\ObjectManager;
|
use Doctrine\Persistence\ObjectManager;
|
||||||
@ -70,8 +71,11 @@ class LoadActivitytACL extends AbstractFixture implements OrderedFixtureInterfac
|
|||||||
->setScope($scope);
|
->setScope($scope);
|
||||||
$permissionsGroup->addRoleScope($roleScopeUpdate);
|
$permissionsGroup->addRoleScope($roleScopeUpdate);
|
||||||
$roleScopeCreate = (new RoleScope())
|
$roleScopeCreate = (new RoleScope())
|
||||||
->setRole('CHILL_ACTIVITY_CREATE')
|
->setRole(ActivityVoter::CREATE_ACCOMPANYING_COURSE)
|
||||||
->setScope($scope);
|
->setScope($scope);
|
||||||
|
$roleScopeCreate = (new RoleScope())
|
||||||
|
->setRole(ActivityVoter::CREATE_PERSON)
|
||||||
|
->setScope($scope);
|
||||||
$permissionsGroup->addRoleScope($roleScopeCreate);
|
$permissionsGroup->addRoleScope($roleScopeCreate);
|
||||||
$roleScopeDelete = (new RoleScope())
|
$roleScopeDelete = (new RoleScope())
|
||||||
->setRole('CHILL_ACTIVITY_DELETE')
|
->setRole('CHILL_ACTIVITY_DELETE')
|
||||||
|
@ -85,7 +85,8 @@ class ChillActivityExtension extends Extension implements PrependExtensionInterf
|
|||||||
$container->prependExtensionConfig('security', array(
|
$container->prependExtensionConfig('security', array(
|
||||||
'role_hierarchy' => array(
|
'role_hierarchy' => array(
|
||||||
ActivityVoter::UPDATE => array(ActivityVoter::SEE_DETAILS),
|
ActivityVoter::UPDATE => array(ActivityVoter::SEE_DETAILS),
|
||||||
ActivityVoter::CREATE => array(ActivityVoter::SEE_DETAILS),
|
ActivityVoter::CREATE_PERSON => array(ActivityVoter::SEE_DETAILS),
|
||||||
|
ActivityVoter::CREATE_ACCOMPANYING_COURSE => array(ActivityVoter::SEE_DETAILS),
|
||||||
ActivityVoter::DELETE => array(ActivityVoter::SEE_DETAILS),
|
ActivityVoter::DELETE => array(ActivityVoter::SEE_DETAILS),
|
||||||
ActivityVoter::SEE_DETAILS => array(ActivityVoter::SEE),
|
ActivityVoter::SEE_DETAILS => array(ActivityVoter::SEE),
|
||||||
ActivityVoter::FULL => [ActivityVoter::CREATE, ActivityVoter::DELETE,
|
ActivityVoter::FULL => [ActivityVoter::CREATE, ActivityVoter::DELETE,
|
||||||
|
@ -40,7 +40,32 @@ use Symfony\Component\Security\Core\Security;
|
|||||||
*/
|
*/
|
||||||
class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
|
class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* allow to create an activity, which will either be associated to an
|
||||||
|
* accompanying course or person.
|
||||||
|
*
|
||||||
|
* It is safe for usage in template and controller
|
||||||
|
*/
|
||||||
const CREATE = 'CHILL_ACTIVITY_CREATE';
|
const CREATE = 'CHILL_ACTIVITY_CREATE';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* role to allow to create an activity associated win an accompanying course.
|
||||||
|
*
|
||||||
|
* Before using this, check if @link{self::CREATE} is not sufficiant
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
const CREATE_ACCOMPANYING_COURSE = 'CHILL_ACTIVITY_CREATE_ACCOMPANYING_COURSE';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* role to allow to create an activity associated with a person
|
||||||
|
*
|
||||||
|
* Before using this, check if @link{self::CREATE} is not sufficiant
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
const CREATE_PERSON = 'CHILL_ACTIVITY_CREATE_PERSON';
|
||||||
|
|
||||||
const SEE = 'CHILL_ACTIVITY_SEE';
|
const SEE = 'CHILL_ACTIVITY_SEE';
|
||||||
const SEE_DETAILS = 'CHILL_ACTIVITY_SEE_DETAILS';
|
const SEE_DETAILS = 'CHILL_ACTIVITY_SEE_DETAILS';
|
||||||
const UPDATE = 'CHILL_ACTIVITY_UPDATE';
|
const UPDATE = 'CHILL_ACTIVITY_UPDATE';
|
||||||
@ -90,10 +115,22 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
|
|||||||
if (!$this->security->isGranted(PersonVoter::SEE, $subject->getPerson())) {
|
if (!$this->security->isGranted(PersonVoter::SEE, $subject->getPerson())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// change attribute CREATE
|
||||||
|
if (self::CREATE === $attribute) {
|
||||||
|
$attribute = self::CREATE_PERSON;
|
||||||
|
}
|
||||||
} elseif ($subject->getAccompanyingPeriod() instanceof AccompanyingPeriod) {
|
} elseif ($subject->getAccompanyingPeriod() instanceof AccompanyingPeriod) {
|
||||||
if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getAccompanyingPeriod())) {
|
if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getAccompanyingPeriod())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self::CREATE === $attribute) {
|
||||||
|
if (AccompanyingPeriod::STEP_CLOSED === $subject->getAccompanyingPeriod()->getStep()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$attribute = self::CREATE_ACCOMPANYING_COURSE;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new \RuntimeException("could not determine context of activity");
|
throw new \RuntimeException("could not determine context of activity");
|
||||||
}
|
}
|
||||||
@ -113,9 +150,16 @@ class ActivityVoter extends AbstractChillVoter implements ProvideRoleHierarchyIn
|
|||||||
|
|
||||||
public function getRoles()
|
public function getRoles()
|
||||||
{
|
{
|
||||||
return self::ALL;
|
return [
|
||||||
|
self::CREATE_PERSON,
|
||||||
|
self::CREATE_ACCOMPANYING_COURSE,
|
||||||
|
self::UPDATE,
|
||||||
|
self::DELETE,
|
||||||
|
self::FULL
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public function getRolesWithoutScope()
|
public function getRolesWithoutScope()
|
||||||
{
|
{
|
||||||
return [];
|
return [];
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
<li class="create">
|
<li class="create">
|
||||||
<a href="{{ path('accompanying_course_document_new', {'course': accompanyingCourse.id}) }}" class="btn btn-create">
|
<a href="{{ path('accompanying_course_document_new', {'course': accompanyingCourse.id}) }}" class="btn btn-create">
|
||||||
{{ 'Create new document' | trans }}
|
{{ 'Create'|trans }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -71,17 +71,21 @@ class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements Prov
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($subject instanceof AccompanyingCourseDocument
|
|
||||||
&& !$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getCourse())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($subject instanceof AccompanyingPeriod) {
|
if ($subject instanceof AccompanyingPeriod) {
|
||||||
if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) {
|
if (AccompanyingPeriod::STEP_CLOSED === $subject->getStep()) {
|
||||||
if (\in_array($attribute, [self::UPDATE, self::CREATE, self::DELETE])) {
|
if ($attribute === self::CREATE) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} elseif ($subject instanceof AccompanyingCourseDocument) {
|
||||||
|
if (!$this->security->isGranted(AccompanyingPeriodVoter::SEE, $subject->getCourse())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AccompanyingPeriod::STEP_CLOSED === $subject->getCourse()->getStep()
|
||||||
|
&& \in_array($attribute, [self::CREATE, self::DELETE, self::UPDATE])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->voterHelper->voteOnAttribute($attribute, $subject, $token);
|
return $this->voterHelper->voteOnAttribute($attribute, $subject, $token);
|
||||||
|
@ -5,6 +5,7 @@ namespace Chill\PersonBundle\Menu;
|
|||||||
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
use Chill\MainBundle\Routing\LocalMenuBuilderInterface;
|
||||||
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
use Chill\PersonBundle\Entity\AccompanyingPeriod;
|
||||||
use Knp\Menu\MenuItem;
|
use Knp\Menu\MenuItem;
|
||||||
|
use Symfony\Component\Workflow\Registry;
|
||||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -20,10 +21,12 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
* @var TranslatorInterface
|
* @var TranslatorInterface
|
||||||
*/
|
*/
|
||||||
protected $translator;
|
protected $translator;
|
||||||
|
protected Registry $registry;
|
||||||
|
|
||||||
public function __construct(TranslatorInterface $translator)
|
public function __construct(TranslatorInterface $translator, Registry $registry)
|
||||||
{
|
{
|
||||||
$this->translator = $translator;
|
$this->translator = $translator;
|
||||||
|
$this->registry = $registry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function getMenuIds(): array
|
public static function getMenuIds(): array
|
||||||
@ -33,6 +36,7 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
|
|
||||||
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
public function buildMenu($menuId, MenuItem $menu, array $parameters): void
|
||||||
{
|
{
|
||||||
|
/** @var AccompanyingPeriod $period */
|
||||||
$period = $parameters['accompanyingCourse'];
|
$period = $parameters['accompanyingCourse'];
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('Resume Accompanying Course'), [
|
$menu->addChild($this->translator->trans('Resume Accompanying Course'), [
|
||||||
@ -68,13 +72,16 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
|
|||||||
]])
|
]])
|
||||||
->setExtras(['order' => 40]);
|
->setExtras(['order' => 40]);
|
||||||
|
|
||||||
$menu->addChild($this->translator->trans('Close Accompanying Course'), [
|
$workflow = $this->registry->get($period, 'accompanying_period_lifecycle');
|
||||||
'route' => 'chill_person_accompanying_course_close',
|
|
||||||
'routeParameters' => [
|
|
||||||
'accompanying_period_id' => $period->getId()
|
|
||||||
]])
|
|
||||||
->setExtras(['order' => 500]);
|
|
||||||
|
|
||||||
|
if ($workflow->can($period, 'close')) {
|
||||||
|
$menu->addChild($this->translator->trans('Close Accompanying Course'), [
|
||||||
|
'route' => 'chill_person_accompanying_course_close',
|
||||||
|
'routeParameters' => [
|
||||||
|
'accompanying_period_id' => $period->getId()
|
||||||
|
]])
|
||||||
|
->setExtras(['order' => 99999]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,9 +27,17 @@
|
|||||||
</span>
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<span v-else class="text-md-end d-md-block">
|
<span v-else class="text-md-end d-md-block">
|
||||||
<span class="badge bg-primary">
|
<span class="badge bg-danger">
|
||||||
{{ $t('course.step.closed') }}
|
{{ $t('course.step.closed') }}
|
||||||
</span>
|
</span>
|
||||||
|
<span class="d-md-block">
|
||||||
|
<span class="d-md-block ms-3 ms-md-0">
|
||||||
|
<i>{{ $d(accompanyingCourse.openingDate.datetime, 'text') }} - {{ $d(accompanyingCourse.closingDate.datetime, 'text') }}</i>
|
||||||
|
</span>
|
||||||
|
<span v-if="accompanyingCourse.user" class="d-md-block ms-3 ms-md-0">
|
||||||
|
<span class="item-key">{{ $t('course.referrer') }}:</span> <b>{{ accompanyingCourse.user.username }}</b>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
</teleport>
|
</teleport>
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user