Files
vision/src/Controller/DocumentController.php
2022-04-26 19:17:57 +00:00

361 lines
14 KiB
PHP

<?php
namespace App\Controller;
use App\Entity\User;
use App\Entity\Comment;
use App\Entity\Document;
use App\Entity\Directory;
use App\Form\CommentType;
use App\Form\SearchBarType;
use App\Repository\DocumentRepository;
use Doctrine\ORM\EntityManagerInterface;
use Knp\Component\Pager\PaginatorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Gedmo\Loggable\Entity\Repository\LogEntryRepository;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
#[Route('/document', name: 'document_')]
class DocumentController extends AbstractController
{
private TokenStorageInterface $TokenStorage;
public function __construct(TokenStorageInterface $TokenStorage)
{
$this->TokenStorage = $TokenStorage;
}
#[Route('/archive/{id}', name: 'archive')]
#[IsGranted('archive', subject: 'Document', message: 'granted_not_allowed_archiving_document')]
public function archive(Document $Document, Request $Request): Response
{
$entityManager = $this->getDoctrine()->getManager();
$Document->setArchive(($Document->getArchive()) ? false : true);
$entityManager->persist($Document);
try {
$entityManager->flush();
} catch (\Throwable $th) {
if ($_ENV['APP_ENV'] === 'dev') {
throw $th; //DEBUG
}
$this->addFlash(
'warning',
'alert_error_' . (($Document->getArchive()) ? 'archiving' : 'unarchiving') . '_document'
);
if (null != $Request->headers->get('referer')) {
return $this->redirect($Request->headers->get('referer'));
}
return $this->redirectToRoute('document_view', ['id' => $Document->getId()]);
}
$this->addFlash(
'success',
'alert_success_' . (($Document->getArchive()) ? 'archiving' : 'unarchiving') . '_document'
);
if (null != $Request->headers->get('referer')) {
return $this->redirect($Request->headers->get('referer'));
}
return $this->redirectToRoute('document_view', ['id' => $Document->getId()]);
}
#[Route('/view/{id}', name: 'view')]
#[IsGranted('view', subject: 'Document', message: 'granted_not_allowed_viewing_document')]
public function view(Document $Document, EntityManagerInterface $em): Response
{
$formComment = $this->createForm(
CommentType::class,
new Comment(),
[ 'action' => $this->generateUrl('comment_create', ['Document' => $Document->getId()])]
);
/**
* @var LogEntryRepository $logEntryRepository
*/
$logEntryRepository = $em->getRepository('Gedmo\Loggable\Entity\LogEntry');
$documentHistory = $logEntryRepository->getLogEntries($Document);
return $this->render('document/view.html.twig', [
'controller_name' => 'DocumentController',
'document' => $Document,
'history' => $documentHistory,
'formComment' => $formComment->createView()
]);
}
#[Route('/history/{id}', name: 'history')]
#[IsGranted('view', subject: 'Document', message: 'granted_not_allowed_viewing_document')]
public function history(Document $Document, EntityManagerInterface $em): Response
{
/**
* @var LogEntryRepository $logEntryRepository
*/
$logEntryRepository = $em->getRepository('Gedmo\Loggable\Entity\LogEntry');
$documentHistory = $logEntryRepository->getLogEntries($Document);
return $this->render('document/history.html.twig', [
'controller_name' => 'DocumentController',
'document' => $Document,
'history' => $documentHistory,
]);
}
#[Route('/create/{type}', name: 'create')]
#[Route('/create/{type}/directory/{directory?}', name: 'create_directory')]
#[Route('/create/{type}/user/{user?}', name: 'create_user')]
public function create(string $type, Request $request, Directory $directory = null, User $user = null): Response
{
$Document = $this->getDocumentByTypename($type);
if (!$this->IsGranted('create', $Document)) {
throw new AccessDeniedHttpException('granted_not_allowed_creating_document');
}
if (method_exists($Document, 'setDirectory')) {
if (is_null($directory)) {
throw new \Exception('exception_document_need_directory');
}
$Document->setDirectory($directory);
}
if (method_exists($Document, 'setUser')) {
if (is_null($user)) {
throw new \Exception('exception_document_need_user');
}
$Document->setUser($user);
}
$form = $this->getFormByDocumentType($Document);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/**
* @var User $loggedUser
*/
$loggedUser = $this->getUser();
//check subGroups
//check for subGroups addition and user not in thoses subgroups
foreach ($Document->getAllowedSubGroups() as $key => $subGroup) {
if (
!$loggedUser->getSubGroups()->contains($subGroup)
&& !$loggedUser->hasPermission('group_ignore_subgroups')
) {
$this->addFlash('danger', 'alert_danger_adding_subgroup_document');
$Document->removeAllowedSubGroup($subGroup);
}
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($Document);
try {
$entityManager->flush();
} catch (\Throwable $th) {
if ($_ENV['APP_ENV'] === 'dev') {
throw $th; //DEBUG
}
$this->addFlash('danger', 'alert_error_creating_document');
return $this->redirectToRoute($request->getRequestUri());
}
$this->addFlash('success', 'alert_success_creating_document');
return $this->redirectToRoute('document_view', ['id' => $Document->getId()]);
}
return $this->render('document/create.html.twig', [
'controller_name' => 'DocumentController',
'document' => $Document,
'directory' => $directory,
'form' => $form->createView(),
'type' => $type,
]);
}
#[Route('/edit/{id}', name: 'edit')]
#[IsGranted('edit', subject: 'Document', message: 'granted_not_allowed_editing_document')]
public function edit(Request $request, Document $Document): Response
{
$CurrentSubGroupsAlloweds = $Document->getAllowedSubGroups()->toArray();
$form = $this->getFormByDocumentType($Document);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/**
* @var User $User
*/
$User = $this->getUser();
//check subGroups
//check for missing subGroups
foreach ($CurrentSubGroupsAlloweds as $key => $subGroup) {
if (
!in_array($subGroup, $Document->getAllowedSubGroups()->toArray())
&& !$User->getSubGroups()->contains($subGroup)
&& !$User->hasPermission('group_ignore_subgroups')
) {
$this->addFlash('danger', 'alert_danger_removing_subgroup_document');
$Document->addAllowedSubGroup($subGroup);
}
}
//check for subGroups addition and user not in thoses subgroups
foreach ($Document->getAllowedSubGroups() as $key => $subGroup) {
if (
!in_array($subGroup, $CurrentSubGroupsAlloweds)
&& !$User->getSubGroups()->contains($subGroup)
&& !$User->hasPermission('group_ignore_subgroups')
) {
$this->addFlash('danger', 'alert_danger_adding_subgroup_document');
$Document->removeAllowedSubGroup($subGroup);
}
}
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($Document);
try {
$entityManager->flush();
} catch (\Throwable $th) {
if ($_ENV['APP_ENV'] === 'dev') {
throw $th; //DEBUG
}
$this->addFlash('danger', 'alert_error_editing_document');
return $this->redirectToRoute($request->getRequestUri());
}
$this->addFlash('success', 'alert_success_editing_document');
return $this->redirectToRoute('document_view', ['id' => $Document->getId()]);
}
return $this->render('document/edit.html.twig', [
'controller_name' => 'DocumentController',
'document' => $Document,
'form' => $form->createView()
]);
}
#[Route('/delete/{id}', name: 'delete')]
#[IsGranted('delete', subject: 'Document', message: 'granted_not_allowed_deleting_document')]
public function delete(Document $Document, Request $Request): Response
{
$entityManager = $this->getDoctrine()->getManager();
$entityManager->remove($Document);
try {
$entityManager->flush();
} catch (\Throwable $th) {
if ($_ENV['APP_ENV'] === 'dev') {
throw $th; //DEBUG
}
$this->addFlash('warning', 'alert_error_deleting_document');
if (null != $Request->headers->get('referer')) {
return $this->redirect($Request->headers->get('referer'));
}
return $this->redirectToRoute('document_view', ['id' => $Document->getId()]);
}
$this->addFlash('success', 'alert_success_deleting_document');
/*if (null != $Request->headers->get('referer')) {
return $this->redirect($Request->headers->get('referer'));
}*/ //TODO: fix refere document when deleted (if path return view, send to list)
return $this->redirectToRoute('document_list', ['type' => $Document->getClassShort()]);
}
#[Route('/archives/{type}/{directory?}', name: 'list_archives')]
#[Route('/{type}/{directory?}', name: 'list')]
public function list(
PaginatorInterface $paginator,
Request $request,
DocumentRepository $DocumentRepository,
EntityManagerInterface $EntityManagerInterface,
Directory $directory = null,
string $type
): Response {
$searchForm = $this->createForm(SearchBarType::class);
$searchForm->handleRequest($request);
$documentTypeEntity = $this->getDocumentByTypename($type);
/**
* @var DocumentRepository $DocumentRepository
*/
$DocumentRepository = $EntityManagerInterface->getRepository(get_class($documentTypeEntity));
$archive = ($request->attributes->get('_route') == 'document_list_archives');
$pagination = $paginator->paginate(
$DocumentRepository ->listForUser($this->getUser(), $documentTypeEntity->getIsPublic())
->search((
$searchForm->isSubmitted()
&& $searchForm->isValid()
&& $searchForm->getData()['subject'] !== null
) ? $searchForm->getData()['subject'] : null)
->limitType($type)
->archive($archive)
->order(['createdAt' => 'DESC'])
->limitDirectory($directory)
->getResult(),
$request->query->getInt('page', 1)
);
return $this->render('document/list.html.twig', [
'controller_name' => 'DocumentController',
'pagination' => $pagination,
'count' => $pagination->getTotalItemCount(),
'searchForm' => $searchForm->createView(),
'documentTypeEntity' => $documentTypeEntity,
'type' => $documentTypeEntity->getClassShort(),
'archive' => $archive,
'directory' => $directory
]);
}
private function getFormByDocumentType(Document $Document)
{
if (!is_subclass_of($Document, 'App\Entity\Document')) {
throw new \Exception('exception_invalid_document_type');
}
$type = 'App\Form\\' . ucfirst(strtolower($Document->getClassShort())) . 'Type';
if (!class_exists($type)) {
throw new \Exception('exception_invalid_document_type');
return null;
}
$formtype = new $type($this->TokenStorage);
return $this->createForm(get_class($formtype), $Document);
}
private function getDocumentByTypename(string $type)
{
$type = 'App\Entity\\' . ucfirst(strtolower($type));
if (!class_exists($type)) {
throw new \Exception('exception_invalid_document_type');
return null;
}
$Document = new $type($this->getUser());
if (!is_subclass_of($Document, 'App\Entity\Document')) {
throw new \Exception('exception_invalid_document_type');
}
return $Document ;
}
}