src/Controller/Core/TaxonomyController.php line 430

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Core;
  3. use App\Entity\Term\Actiontype;
  4. use App\Entity\Term\Emailtemplate;
  5. use App\Entity\Term\Evaluationcriterion;
  6. use App\Entity\Term\Inscriptionstatus;
  7. use App\Entity\Term\MenuItem;
  8. use App\Entity\Term\Presencestatus;
  9. use App\Entity\Term\Publictype;
  10. use App\Entity\Term\Sessiontype;
  11. use App\Entity\Term\Supervisor;
  12. use App\Entity\Term\Tag;
  13. use App\Entity\Term\Theme;
  14. use App\Entity\Term\Title;
  15. use App\Entity\Term\Trainertype;
  16. use App\Entity\Term\Trainingcategory;
  17. use App\Entity\Back\Organization;
  18. use App\Vocabulary\VocabularyRegistry;
  19. use Doctrine\ORM\EntityNotFoundException;
  20. use Doctrine\Persistence\ManagerRegistry;
  21. use FOS\RestBundle\Controller\Annotations as Rest;
  22. use Gedmo\Tree\Entity\Repository\NestedTreeRepository;
  23. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
  24. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  25. use Symfony\Component\Routing\Annotation\Route;
  26. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Security;
  27. use App\Entity\Core\AbstractOrganization;
  28. use App\Entity\Term\AbstractTerm;
  29. use App\Entity\Term\Publiposttemplate;
  30. use App\Entity\Term\TreeTrait;
  31. use App\Form\Type\VocabularyType;
  32. use App\Vocabulary\VocabularyInterface;
  33. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  34. use Symfony\Component\HttpFoundation\BinaryFileResponse;
  35. use Symfony\Component\HttpFoundation\Request;
  36. use Symfony\Component\HttpFoundation\ResponseHeaderBag;
  37. use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
  38. use Symfony\Component\Security\Core\Exception\AccessDeniedException;
  39. use Symfony\Component\Validator\Constraints\NotBlank;
  40. /**
  41.  * Class TaxonomyController.
  42.  *
  43.  * @Route("/admin/taxonomy")
  44.  */
  45. class TaxonomyController extends AbstractController
  46. {
  47.     /**
  48.      * @Route("/", name="taxonomy.index")
  49.      */
  50.     public function indexAction(ManagerRegistry $doctrineVocabularyRegistry $vocRegistry)
  51.     {
  52.         if (!$this->isGranted('VIEW'VocabularyInterface::class)) {
  53.             throw new AccessDeniedException();
  54.         }
  55.         return $this->render('Core/views/Taxonomy/index.html.twig', array(
  56.             'vocabularies' => $this->getVocabulariesList($doctrine,  $vocRegistry),
  57.             'organization' => $this->getUser()->getOrganization()
  58.         ));
  59.     }
  60.     /**
  61.      * @param AbstractTerm         $term
  62.      * @param AbstractOrganization $organization
  63.      *
  64.      * @Route("/{vocabularyId}/view/{organizationId}", name="taxonomy.view", defaults={"organizationId" = null})
  65.      * @ParamConverter("organization", class="App\Entity\Core\AbstractOrganization", options={"id" = "organizationId"}, isOptional="true")
  66.      * @Security("is_granted('VIEW', 'App\\Vocabulary\\VocabularyInterface')")
  67.      * @throws EntityNotFoundException
  68.      *
  69.      * @return array|\Symfony\Component\HttpFoundation\RedirectResponse
  70.      */
  71.     public function viewVocabularyAction(ManagerRegistry $doctrineVocabularyRegistry $vocRegistry$vocabularyId$organization null)
  72.     {
  73.         /** @var AbstractTerm $abstractVocabulary */
  74.         $abstractVocabulary $vocRegistry->getVocabularyById($vocabularyId);
  75.         $abstractVocabulary->setVocabularyId($vocabularyId);
  76.         // for mixed vocabularies
  77.         $canEditNationalTerms $this->isGranted('VIEW'$abstractVocabulary);
  78.         if ($abstractVocabulary->getVocabularyStatus() === VocabularyInterface::VOCABULARY_LOCAL && !$organization) {
  79.             return $this->redirect($this->generateUrl('taxonomy.view', array('vocabularyId' => $vocabularyId'organizationId' => $this->getUser()->getOrganization()->getId())));
  80.         }
  81.         // set organization to abstract vocabulary to check access rights
  82.         $abstractVocabulary->setOrganization($organization);
  83.         if (!$this->isGranted('VIEW'$abstractVocabulary) && !$canEditNationalTerms) {
  84.             // organization required for local vocabularies
  85.             throw new AccessDeniedException('');
  86.         }
  87.         // needed for template organization tabs
  88.         $organizations = array();
  89.         if ($abstractVocabulary->getVocabularyStatus() !== VocabularyInterface::VOCABULARY_NATIONAL) {
  90.             $alterOrganizations $doctrine->getManager()->getRepository(AbstractOrganization::class)->findAll();
  91.             $alterAbstractVocabulary $vocRegistry->getVocabularyById($vocabularyId);
  92.             foreach ($alterOrganizations as $alterOrganization) {
  93.                 $alterAbstractVocabulary->setOrganization($alterOrganization);
  94.                 if ($this->isGranted('VIEW'$alterAbstractVocabulary)) {
  95.                     $organizations[$alterOrganization->getId()] = $alterOrganization;
  96.                 }
  97.             }
  98.         }
  99.         $terms $this->getRootTerms($doctrine$abstractVocabulary$organization);
  100.         if ($organization) {
  101.             foreach ($terms as $key => $term) {
  102.                 if (!$term->getOrganization()) {
  103.                     unset($terms[$key]);
  104.                 }
  105.             }
  106.         }
  107.         return $this->render('Core/views/Taxonomy/view.html.twig', array(
  108.             'organization' => $organization,
  109.             'organizations' => $organizations,
  110.             'canEditNationalTerms' => $canEditNationalTerms,
  111.             'terms' => $terms,
  112.             'vocabulary' => $abstractVocabulary,
  113.             'vocabularies' => $this->getVocabulariesList($doctrine,  $vocRegistry),
  114.             'sortable' => $abstractVocabulary::orderBy() === 'position',
  115.             'depth' => method_exists($abstractVocabulary'getChildren') ? 1,
  116.         ));
  117.     }
  118.     /**
  119.      * @Route("/{vocabularyId}/edit/{id}/{organizationId}", name="taxonomy.edit", defaults={"id" = null, "organizationId" = null})
  120.      * @Security("is_granted('EDIT', 'App\\Vocabulary\\VocabularyInterface')")
  121.      */
  122.     public function editVocabularyTermAction(Request $requestManagerRegistry $doctrineVocabularyRegistry $vocRegistry$vocabularyId$organizationId$id null)
  123.     {
  124.         $organization null;
  125.         if ($organizationId) {
  126.             $organization $doctrine->getManager()->getRepository(AbstractOrganization::class)->find($organizationId);
  127.         }
  128.         $term null;
  129.         $abstractVocabulary $vocRegistry->getVocabularyById($vocabularyId);
  130.         $abstractVocabulary->setVocabularyId($vocabularyId);
  131.         $termClass get_class($abstractVocabulary);
  132.         $em $doctrine->getManager();
  133.         // find term
  134.         if ($id) {
  135.             $term $em->find($termClass$id);
  136.         }
  137.         // create term if not found
  138.         if (!$term) {
  139.             $term = new $termClass();
  140.             $term->setOrganization($organization);
  141.         }
  142.         if (!$this->isGranted('EDIT'$term)) {
  143.             throw new AccessDeniedException();
  144.         }
  145.         // get term from
  146.         $formType VocabularyType::class;
  147.         if (method_exists($abstractVocabulary'getFormType')) {
  148.             $formType $abstractVocabulary::getFormType();
  149.         }
  150.         $form $this->createForm($formType$term);
  151.         if ($request->getMethod() === 'POST') {
  152.             $form->handleRequest($request);
  153.             if (($form->isSubmitted()) && ($form->isValid())) {
  154.                 $term->setOrganization($organization);
  155.                 $em->persist($term);
  156.                 $em->flush();
  157.                 $this->get('session')->getFlashBag()->add('success''Le terme a bien été enregistré.');
  158.                 $organization_id null;
  159.                 if ($organization) {
  160.                     $organization_id $organization->getId();
  161.                 }
  162.                 return $this->redirect($this->generateUrl('taxonomy.view', array('vocabularyId' => $vocabularyId'organizationId' => $organization_id)));
  163.             }
  164.         }
  165.         return $this->render('Core/views/Taxonomy/edit.html.twig', array(
  166.             'vocabulary' => $abstractVocabulary,
  167.             'organization' => $organization,
  168.             'term' => $term,
  169.             'id' => $id,
  170.             'form' => $form->createView(),
  171.             'vocabularies' => $this->getVocabulariesList($doctrine,  $vocRegistry),
  172.         ));
  173.     }
  174.     /**
  175.      * @Route("/{vocabularyId}/remove/{id}", name="taxonomy.remove")
  176.      * @Security("is_granted('REMOVE', 'App\\Vocabulary\\VocabularyInterface')")
  177.      */
  178.     public function removeAction(Request $requestManagerRegistry $doctrineVocabularyRegistry $vocRegistry$vocabularyId$id)
  179.     {
  180.         $abstractVocabulary $vocRegistry->getVocabularyById($vocabularyId);
  181.         $abstractVocabulary->setVocabularyId($vocabularyId);
  182.         $termClass get_class($abstractVocabulary);
  183.         $em $doctrine->getManager();
  184.         // find term
  185.         $term $em->find($termClass$id);
  186.         if (!$term) {
  187.             throw new NotFoundHttpException();
  188.         }
  189.         // protected term because needed for special system operations
  190.         if ($term->isLocked()) {
  191.             throw new AccessDeniedException("This term can't be removed");
  192.         }
  193.         if (!$this->isGranted('REMOVE'$term)) {
  194.             throw new AccessDeniedException();
  195.         }
  196.         // get term usage
  197.         $count $vocRegistry->getTermUsages($em$term);
  198.         $formB $this->createFormBuilder(null, array('validation_groups' => array('taxonomy_term_remove')));
  199.         $constraint = new NotBlank(array('message' => 'Vous devez sélectionner un terme de substitution'));
  200.         $constraint->addImplicitGroupName('taxonomy_term_remove');
  201.         // build query
  202.         $queryBuilder $em->createQueryBuilder('s')
  203.             ->select('t')
  204.             ->from($termClass't')
  205.             ->where('t.id != :id')->setParameter('id'$id)
  206.             ->orderBy('t.'.$abstractVocabulary::orderBy());
  207.         if ($term->getOrganization()) {
  208.             $queryBuilder
  209.                 ->andWhere('t.organization = :organization')
  210.                 ->setParameter('organization'$term->getOrganization());
  211.         }
  212.         $queryBuilder->orWhere('t.organization is null');
  213.         //if entities are linked to current
  214.         if ($count 0) {
  215.             $required = !empty($abstractVocabulary::$replacementRequired);
  216.             $formB
  217.                 ->add('term''entity',
  218.                     array(
  219.                         'class' => $termClass,
  220.                         'expanded' => true,
  221.                         'label' => 'Terme de substitution',
  222.                         'required' => $required,
  223.                         'constraints' => $required $constraint null,
  224.                         'query_builder' => $queryBuilder,
  225.                         'empty_value' => $required null '- Aucun -',
  226.                     )
  227.                 );
  228.         }
  229.         $organization_id null;
  230.         if ($term->getOrganization()) {
  231.             $organization_id $term->getOrganization()->getId();
  232.         }
  233.         $form $formB->getForm();
  234.         if ($request->getMethod() === 'POST') {
  235.             $form->handleRequest($request);
  236.             if ($form->isValid()) {
  237.                 if ($form->has('term')) {
  238.                     $newTerm $form->get('term')->getData();
  239.                     if ($newTerm) {
  240.                         $vocRegistry->replaceTermInUsages(
  241.                             $em,
  242.                             $term,
  243.                             $newTerm);
  244.                     }
  245.                 }
  246.                 $em->remove($term);
  247.                 $em->flush();
  248.                 $this->get('session')->getFlashBag()->add('success''Le terme a bien été supprimé.');
  249.                 return $this->redirect($this->generateUrl('taxonomy.view', array('vocabularyId' => $vocabularyId'organizationId' => $organization_id)));
  250.             }
  251.         }
  252.         return $this->render('Core/views/Taxonomy/remove.html.twig', array(
  253.             'vocabulary' => $abstractVocabulary,
  254.             'organization' => $term->getOrganization(),
  255.             'organization_id' => $organization_id,
  256.             'term' => $term,
  257.             'vocabularies' => $this->getVocabulariesList($doctrine$vocRegistry),
  258.             'count' => $count,
  259.             'form' => $form->createView(),
  260.         ));
  261.     }
  262.     /**
  263.      * @Route("/{vocabulary}/terms/order", name="taxonomy.terms_order", options={"expose"=true}, defaults={"_format" = "json"})
  264.      * @Method({"POST"})
  265.      * @Rest\View
  266.      */
  267.     public function termsOrderAction(ManagerRegistry $doctrineVocabularyRegistry $vocRegistry$vocabularyRequest $request)
  268.     {
  269.         $abstractVocabulary = $$vocRegistry->getVocabularyById($vocabulary);
  270.         $abstractVocabulary->setVocabularyId($vocabulary);
  271.         $termClass get_class($abstractVocabulary);
  272.         $em $doctrine->getManager();
  273.         $repository $em->getRepository($termClass);
  274.         $serialized $request->get('serialized');
  275.         $process = function ($objects$parent null) use ($em$repository, &$process) {
  276.             $pos 0;
  277.             foreach ($objects as $object) {
  278.                 /** @var TreeTrait $entity */
  279.                 $entity $repository->find($object['id']);
  280.                 if (method_exists($entity'setParent')) {
  281.                     $entity->setParent($parent);
  282.                 }
  283.                 if (method_exists($entity'setPosition')) {
  284.                     $entity->setPosition($pos++);
  285.                 }
  286.                 //$entity->setParent($parent);
  287.                 $em->persist($entity);
  288.                 if (isset($object['children'])) {
  289.                     $process($object['children'], $entity);
  290.                 }
  291.             }
  292.         };
  293.         $process($serialized);
  294.         $em->flush();
  295.     }
  296.     /**
  297.      * Return the terms for a specified vocabulary, filter by an organization
  298.      * For tree vocabulary, only root ones.
  299.      *
  300.      * @param $vocabulary
  301.      * @param null $organization
  302.      * @param null $isAdmin
  303.      *
  304.      * @return mixed
  305.      */
  306.     private function getRootTerms(ManagerRegistry $doctrine$vocabulary$organization$isAdmin=null)
  307.     {
  308.         $class get_class($vocabulary);
  309.         $repository $doctrine->getManager()->getRepository($class);
  310.         if ($repository instanceof NestedTreeRepository) {
  311.             $qb $repository->getRootNodesQueryBuilder('position');
  312.         } else {
  313.             $qb $repository->createQueryBuilder('node');
  314.             $qb->orderBy('node.'.$vocabulary::orderBy(), 'ASC');
  315.         }
  316.         if ($vocabulary->getVocabularyStatus() !== VocabularyInterface::VOCABULARY_NATIONAL) {
  317.             if (!$isAdmin) {
  318.                 if ($organization) {
  319.                     $qb->where('node.organization = :organization')
  320.                         ->setParameter('organization'$organization)
  321.                         ->orWhere('node.organization is null');
  322.                 } else {
  323.                     $qb->where('node.organization is null');
  324.                 }
  325.             }
  326.         }
  327.         return $qb->getQuery()->getResult();
  328.     }
  329.     /**
  330.      * @return array list of allowed vocabularies, grouped by existing groups
  331.      */
  332.     private function getVocabulariesList(ManagerRegistry $doctrineVocabularyRegistry $vocRegistry)
  333.     {
  334.         $vocsGroups $vocRegistry->getGroups();
  335.         $userOrg $this->getUser()->getOrganization();
  336.         //getting vocabularies list, grouped by vocabularies groups
  337.         $vocNames = array();
  338.         foreach ($vocsGroups as $group => $vocs) {
  339.             foreach ($vocs as $vid => $voc) {
  340.                 if ($voc->getVocabularyStatus() !== VocabularyInterface::VOCABULARY_NATIONAL && !empty($userOrg)) {
  341.                     $voc->setOrganization($userOrg);
  342.                 }
  343.                 if ($this->isGranted('VIEW'$voc)) {
  344.                     $label $vocRegistry->getVocabularyLabel($vid);
  345.                     $voc->setVocabularyLabel($label);
  346.                     $vocNames[] = array('id' => $vid'vocabulary' => $voc'name' => $voc->getVocabularyLabel(), 'scope' => $voc->getVocabularyStatus());
  347.                 }
  348.             }
  349.         }
  350.         //ordering list
  351.         usort($vocNames, function ($a$b) {
  352.             return $a['vocabulary']->getVocabularyLabel() > $b['vocabulary']->getVocabularyLabel();
  353.         });
  354.         return $vocNames;
  355.     }
  356.     /**
  357.      * @Route(
  358.      *     "/download/template/{id}",
  359.      *     name="taxonomy.download.template",
  360.      *     requirements={"id"="\d+"}
  361.      * )
  362.      * @Method("GET")
  363.      * @Security("is_granted('VIEW', 'Vocabulary\\VocabularyInterface')")
  364.      *
  365.      * @param Publiposttemplate $template
  366.      *
  367.      * @return BinaryFileResponse
  368.      */
  369.     public function downloadTemplateAction(Publiposttemplate $template)
  370.     {
  371.         $file $template->getFile();
  372.         if (!$file) {
  373.             throw $this->createNotFoundException("No file found for template \"{$template->getName()}\".");
  374.         }
  375.         $response = new BinaryFileResponse($file);
  376.         $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT$template->getFileName());
  377.         return $response;
  378.     }
  379.     /**
  380.      * @Route("/get_terms/{vocabularyId}", name="taxonomy.get", options={"expose"=true}, defaults={"_format" = "json"})
  381.      * @Rest\View
  382.      */
  383.     public function getTermsAction(ManagerRegistry $doctrineVocabularyRegistry $vocRegistry$vocabularyId)
  384.     {
  385.         /*
  386.          * @var AbstractTerm
  387.          */
  388.         $vocabulary $vocRegistry->getVocabularyById($vocabularyId);
  389.         if (!$vocabulary) {
  390.             throw new \InvalidArgumentException('This vocabulary does not exists.');
  391.         }
  392.         $userOrg $this->getUser()->getOrganization();
  393.         $isAdmin $this->getUser()->isAdmin();
  394.         $terms $this->getRootTerms($doctrine$vocabulary$userOrg$isAdmin);
  395.         return $terms;
  396.     }
  397. }