Documents can be added/viewed/edited for an accompanyingCourse + menu entry added

This commit is contained in:
Julie Lenaerts 2021-09-14 15:44:06 +02:00
parent 88c192c22e
commit 2e5c2de363
11 changed files with 142 additions and 92 deletions

View File

@ -72,11 +72,6 @@ class DocumentAccompanyingCourseController extends AbstractController
$this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $course);
// $reachableScopes = $this->authorizationHelper
// ->getReachableScopes(
// $this->getUser(), new Role(PersonDocumentVoter::SEE),
// $person->getCenter());
$documents = $em
->getRepository("ChillDocStoreBundle:AccompanyingCourseDocument")
->findBy(
@ -84,15 +79,6 @@ class DocumentAccompanyingCourseController extends AbstractController
['date' => 'DESC']
);
// dump($course);
// dump($documents);
// $event = new PrivacyEvent($course, [
// 'element_class' => AccompanyingCourseDocument::class,
// 'action' => 'index'
// ]);
// $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render(
'ChillDocStoreBundle:AccompanyingCourseDocument:index.html.twig',
[
@ -121,9 +107,9 @@ class DocumentAccompanyingCourseController extends AbstractController
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $this->denyAccessUnlessGranted(
// 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE', $document,
// 'creation of this activity not allowed');
$this->denyAccessUnlessGranted(
'CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE', $document,
'creation of this activity not allowed');
$em = $this->getDoctrine()->getManager();
$em->persist($document);
@ -151,13 +137,6 @@ class DocumentAccompanyingCourseController extends AbstractController
$this->denyAccessUnlessGranted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', $course);
$this->denyAccessUnlessGranted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE', $document);
// $event = new PrivacyEvent($person, array(
// 'element_class' => PersonDocument::class,
// 'element_id' => $document->getId(),
// 'action' => 'show'
// ));
// $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render(
'ChillDocStoreBundle:AccompanyingCourseDocument:show.html.twig',
['document' => $document, 'accompanyingCourse' => $course]);
@ -169,7 +148,7 @@ class DocumentAccompanyingCourseController extends AbstractController
public function edit(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
{
$this->denyAccessUnlessGranted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', $course);
$this->denyAccessUnlessGranted('CHILL_PERSON_DOCUMENT_UPDATE', $document);
$this->denyAccessUnlessGranted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', $document);
$document->setUser($this->getUser());
$document->setDate(new \DateTime('Now'));
@ -183,28 +162,14 @@ class DocumentAccompanyingCourseController extends AbstractController
$this->addFlash('success', $this->translator->trans("The document is successfully updated"));
// $event = new PrivacyEvent($person, array(
// 'element_class' => PersonDocument::class,
// 'element_id' => $document->getId(),
// 'action' => 'update'
// ));
// $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->redirectToRoute(
'accompanying_course_document_edit',
['id' => $document->getId(), 'accompanyingCourse' => $course->getId()]);
['id' => $document->getId(), 'course' => $course->getId()]);
} elseif ($form->isSubmitted() and !$form->isValid()) {
$this->addFlash('error', $this->translator->trans("This form contains errors"));
}
// $event = new PrivacyEvent($person, array(
// 'element_class' => PersonDocument::class,
// 'element_id' => $document->getId(),
// 'action' => 'edit'
// ));
// $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event);
return $this->render(
'ChillDocStoreBundle:AccompanyingCourseDocument:edit.html.twig',
[
@ -220,7 +185,7 @@ class DocumentAccompanyingCourseController extends AbstractController
public function delete(Request $request, AccompanyingPeriod $course, AccompanyingCourseDocument $document): Response
{
$this->denyAccessUnlessGranted('CHILL_PERSON_ACCOMPANYING_PERIOD_SEE', $course);
$this->denyAccessUnlessGranted('CHILL_PERSON_DOCUMENT_DELETE', $document);
$this->denyAccessUnlessGranted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE', $document);
if ($this->isCsrfTokenValid('delete'.$document->getId(), $request->request->get('_token'))) {
$em = $this->getDoctrine()->getManager();

View File

@ -16,12 +16,7 @@ class AccompanyingCourseDocument extends Document
* @ORM\ManyToOne(targetEntity=AccompanyingPeriod::class)
* @ORM\JoinColumn(nullable=false)
*/
private $course;
public function getId(): ?int
{
return $this->id;
}
private ?AccompanyingPeriod $course = null;
public function getCourse(): ?AccompanyingPeriod
{

View File

@ -66,6 +66,7 @@ class AccompanyingCourseDocumentType extends AbstractType
'error_bubbling' => true
])
->add('date', ChillDateType::class)
//TODO : adapt to using AccompanyingCourseDocument categories. Currently there are none...
->add('category', EntityType::class, array(
'placeholder' => 'Choose a document category',
'class' => 'ChillDocStoreBundle:DocumentCategory',

View File

@ -50,6 +50,9 @@ class MenuBuilder implements LocalMenuBuilderInterface
public function buildMenu($menuId, MenuItem $menu, array $parameters)
{
switch($menuId) {
case 'accompanyingCourse':
$this->buildMenuAccompanyingCourse($menu, $parameters);
break;
case 'person':
$this->buildMenuPerson($menu, $parameters);
break;
@ -80,8 +83,25 @@ class MenuBuilder implements LocalMenuBuilderInterface
}
protected function buildMenuAccompanyingCourse(MenuItem $menu, array $parameters){
$course = $parameters['accompanyingCourse'];
// $user = $this->tokenStorage->getToken()->getUser();
//TODO : add condition to check user rights?
$menu->addChild($this->translator->trans('Documents'), [
'route' => 'accompanying_course_document_index',
'routeParameters' => [
'course' => $course->getId()
]
])
->setExtras([
'order'=> 400
]);
}
public static function getMenuIds(): array
{
return [ 'person' ];
return [ 'person', 'accompanyingCourse' ];
}
}

View File

@ -5,7 +5,7 @@
{% block title %}
{# {{ 'Editing document for %name%'|trans({ '%name%': accompanyingCourse|chill_entity_render_string } ) }} #}
{% endblock %}
{% block accompanyingCoursecontent %}
{% block content %}
<h1>{{ 'Edit Document' | trans }}</h1>
@ -16,13 +16,12 @@
{{ form_row(form.title) }}
{{ form_row(form.date) }}
{{ form_row(form.category) }}
{{ form_row(form.scope) }}
{{ form_row(form.description) }}
{{ form_row(form.object, { 'label': 'Document', 'existing': document.object }) }}
<ul class="record_actions">
<li class="cancel">
<a href="{{ path('accompanying_course_document_index', {'course': course.id}) }}" class="btn btn-cancel">
<a href="{{ path('accompanying_course_document_index', {'course': accompanyingCourse.id}) }}" class="btn btn-cancel">
{{ 'Back to the list' | trans }}
</a>
</li>

View File

@ -20,7 +20,6 @@
<tr>
<th>{{ 'Title' | trans }}</th>
<th>{{ 'Category'|trans }}</th>
<th>{{ 'Circle' | trans }}</th>
<th>{{ 'Actions' | trans }}</th>
</tr>
</thead>
@ -32,19 +31,19 @@
{# <td>{{ document.scope.name|localize_translatable_string }}</td> #}
<td>
<ul class="record_actions">
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS', document) %}
{# if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS', document) #}
<li>
{{ m.download_button(document.object, document.title) }}
</li>
<li>
<a href="{{ path('accompanying_course_document_show', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-show"></a>
<a href="{{ chill_path_add_return_path('accompanying_course_document_show', {'course': accompanyingCourse.id, 'id': document.id}) }}" class="btn btn-show"></a>
</li>
{% endif %}
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
{# endif #}
{# if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) #}
<li>
<a href="{{ path('accompanying_course_document_edit', {'course': accompanyingCourse.id, 'id': document.id }) }}" class="btn btn-update"></a>
</li>
{% endif %}
{# endif #}
</ul>
</td>
</tr>

View File

@ -13,7 +13,7 @@
{{ encore_entry_script_tags('mod_async_upload') }}
{% endblock %}
{% block accompanyingCoursecontent %}
{% block content %}
<h1>{{ 'Document %title%' | trans({ '%title%': document.title }) }}</h1>
@ -21,9 +21,6 @@
<dt>{{ 'Title'|trans }}</dt>
<dd>{{ document.title }}</dd>
<dt>{{ 'Scope' | trans }}</dt>
<dd>{{ document.scope.name | localize_translatable_string }}</dd>
<dt>{{ 'Category'|trans }}</dt>
<dd>{{ document.category.name|localize_translatable_string }}</dd>
@ -42,7 +39,7 @@
<ul class="record_actions">
<li class="cancel">
<a href="{{ path('accompanying_course_document_index', {'course': course.id}) }}" class="btn btn-cancel">
<a href="{{ path('accompanying_course_document_index', {'course': accompanyingCourse.id}) }}" class="btn btn-cancel">
{{ 'Back to the list' | trans }}
</a>
</li>
@ -53,7 +50,7 @@
{% if is_granted('CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE', document) %}
<li>
<a href="{{ path('accompanying_course_document_edit', {'id': document.id, 'course': course.id}) }}" class="btn btn-edit">
<a href="{{ path('accompanying_course_document_edit', {'id': document.id, 'course': accompanyingCourse.id}) }}" class="btn btn-edit">
{{ 'Edit' | trans }}
</a>
</li>

View File

@ -0,0 +1,94 @@
<?php
namespace Chill\DocStoreBundle\Security\Authorization;
use Chill\DocStoreBundle\Entity\AccompanyingCourseDocument;
use Chill\MainBundle\Security\Authorization\AbstractChillVoter;
use Chill\MainBundle\Security\Authorization\AuthorizationHelper;
use Chill\MainBundle\Security\ProvideRoleHierarchyInterface;
use Chill\MainBundle\Entity\User;
use Symfony\Component\Security\Core\Authorization\AccessDecisionManagerInterface;
use Psr\Log\LoggerInterface;
/**
*
*/
class AccompanyingCourseDocumentVoter extends AbstractChillVoter implements ProvideRoleHierarchyInterface
{
const CREATE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_CREATE';
const SEE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE';
const SEE_DETAILS = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_SEE_DETAILS';
const UPDATE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_UPDATE';
const DELETE = 'CHILL_ACCOMPANYING_COURSE_DOCUMENT_DELETE';
/**
* @var AuthorizationHelper
*/
protected $authorizationHelper;
/**
* @var AccessDecisionManagerInterface
*/
protected $accessDecisionManager;
/**
* @var LoggerInterface
*/
protected $logger;
public function __construct(
AccessDecisionManagerInterface $accessDecisionManager,
AuthorizationHelper $authorizationHelper,
LoggerInterface $logger
)
{
$this->accessDecisionManager = $accessDecisionManager;
$this->authorizationHelper = $authorizationHelper;
$this->logger = $logger;
}
public function getRoles()
{
return [
self::CREATE,
self::SEE,
self::SEE_DETAILS,
self::UPDATE,
self::DELETE
];
}
protected function supports($attribute, $subject)
{
if (\in_array($attribute, $this->getRoles()) && $subject instanceof AccompanyingCourseDocument) {
return true;
}
//if ($subject instanceof AccompanyingPeriod && $attribute === self::CREATE) {
return true;
//}
return false;
}
protected function isGranted($attribute, $report, $user = null)
{
if (! $user instanceof User){
return false;
}
// TODO
// return $this->helper->userHasAccess($user, $report, $attribute);
return true;
}
public function getRolesWithoutScope()
{
return array();
}
public function getRolesWithHierarchy()
{
return ['accompanyingCourseDocument' => $this->getRoles() ];
}
}

View File

@ -21,12 +21,9 @@ services:
tags:
- { name: form.type, alias: chill_docstorebundle_form_document }
Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter:
class: Chill\DocStoreBundle\Security\Authorization\PersonDocumentVoter
arguments:
- "@security.access.decision_manager"
- "@chill.main.security.authorization.helper"
- "@logger"
Chill\DocStoreBundle\Security\Authorization\:
resource: "./../Security/Authorization"
autowire: true
autoconfigure: true
tags:
- { name: security.voter }
- { name: chill.role }

View File

@ -1,18 +1,8 @@
services:
_defaults:
autowire: true
autoconfigure: true
Chill\DocStoreBundle\Controller\:
resource: "../../Controller"
tags: ["controller.service_arguments"]
Chill\DocStoreBundle\Controller\DocumentPersonController:
arguments:
$translator: '@Symfony\Component\Translation\TranslatorInterface'
$eventDispatcher: '@Symfony\Component\EventDispatcher\EventDispatcherInterface'
$authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
tags: ["controller.service_arguments"]
Chill\DocStoreBundle\Controller\DocumentAccompanyingCourseController:
arguments:
$translator: '@Symfony\Component\Translation\TranslatorInterface'
$eventDispatcher: '@Symfony\Component\EventDispatcher\EventDispatcherInterface'
$authorizationHelper: '@Chill\MainBundle\Security\Authorization\AuthorizationHelper'
tags: ["controller.service_arguments"]

View File

@ -61,13 +61,6 @@ class AccompanyingCourseMenuBuilder implements LocalMenuBuilderInterface
]])
->setExtras(['order' => 30]);
$menu->addChild($this->translator->trans('Documents'), [
'route' => 'accompanying_course_document_index',
'routeParameters' => [
'course' => $period->getId()
]])
->setExtras(['order' => 40]);
$menu->addChild($this->translator->trans('Accompanying Course Action'), [
'route' => 'chill_person_accompanying_period_work_list',
'routeParameters' => [