accompanyingPeriodACLAwareRepository = $accompanyingPeriodACLAwareRepository; $this->eventDispatcher = $eventDispatcher; $this->validator = $validator; } /** * @throws \Exception */ public function closeAction(int $person_id, Request $request): Response { $person = $this->_getPerson($person_id); $this->denyAccessUnlessGranted(PersonVoter::UPDATE, $person, 'You are not allowed to update this person'); if ($person->isOpen() === false) { $this->get('session')->getFlashBag() ->add('error', $this->get('translator') ->trans( 'Beware period is closed', ['%name%' => $person->__toString()] )); return $this->redirect( $this->generateUrl('chill_person_accompanying_period_list', [ 'person_id' => $person->getId(), ]) ); } $current = $person->getCurrentAccompanyingPeriod(); $form = $this->createForm(AccompanyingPeriodType::class, $current, [ 'period_action' => 'close', 'center' => $person->getCenter(), ]); if ($request->getMethod() === 'POST') { $form->handleRequest($request); if ($form->isValid()) { $person->close($current); $errors = $this->_validatePerson($person); if (count($errors) === 0) { $this->get('session')->getFlashBag() ->add('success', $this->get('translator') ->trans('An accompanying period has been closed.', [ '%name%' => $person->__toString(), ])); $this->getDoctrine()->getManager()->flush(); return $this->redirect( $this->generateUrl('chill_person_accompanying_period_list', [ 'person_id' => $person->getId(), ]) ); } $this->get('session')->getFlashBag() ->add('error', $this->get('translator') ->trans('Error! Period not closed!')); foreach ($errors as $error) { $this->get('session')->getFlashBag() ->add('info', $error->getMessage()); } } else { //if form is not valid $this->get('session')->getFlashBag() ->add( 'error', $this->get('translator') ->trans('Pediod closing form is not valid') ); foreach ($form->getErrors() as $error) { $this->get('session')->getFlashBag() ->add('info', $error->getMessage()); } } } return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [ 'form' => $form->createView(), 'person' => $person, 'accompanying_period' => $current, ]); } public function createAction(int $person_id, Request $request): Response { $person = $this->_getPerson($person_id); $this->denyAccessUnlessGranted( PersonVoter::UPDATE, $person, 'You are not allowed to update this person' ); $accompanyingPeriod = new AccompanyingPeriod(new DateTime('now')); $accompanyingPeriod->setClosingDate(new DateTime('now')); $accompanyingPeriod->addPerson($person); //or $person->addAccompanyingPeriod($accompanyingPeriod); $form = $this->createForm( AccompanyingPeriodType::class, $accompanyingPeriod, [ 'period_action' => 'create', 'center' => $person->getCenter(), ] ); if ($request->getMethod() === 'POST') { $form->handleRequest($request); $errors = $this->_validatePerson($person); $flashBag = $this->get('session')->getFlashBag(); if ( $form->isValid(['Default', 'closed']) && count($errors) === 0 ) { $em = $this->getDoctrine()->getManager(); $em->persist($accompanyingPeriod); $em->flush(); $flashBag->add( 'success', $this->get('translator')->trans( 'A period has been created.' ) ); return $this->redirect( $this->generateUrl('chill_person_accompanying_period_list', [ 'person_id' => $person->getId(), ]) ); } $flashBag->add('error', $this->get('translator') ->trans('Error! Period not created!')); foreach ($errors as $error) { $flashBag->add('info', $error->getMessage()); } } return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [ 'form' => $form->createView(), 'person' => $person, 'accompanying_period' => $accompanyingPeriod, ]); } /** * @ParamConverter("person", options={"id": "person_id"}) */ public function listAction(Person $person): Response { $this->denyAccessUnlessGranted(AccompanyingPeriodVoter::SEE, $person); $event = new PrivacyEvent($person, [ 'element_class' => AccompanyingPeriod::class, 'action' => 'list', ]); $this->eventDispatcher->dispatch(PrivacyEvent::PERSON_PRIVACY_EVENT, $event); $accompanyingPeriodsRaw = $this->accompanyingPeriodACLAwareRepository ->findByPerson($person, AccompanyingPeriodVoter::SEE); usort($accompanyingPeriodsRaw, static function ($a, $b) { return $b->getOpeningDate() > $a->getOpeningDate(); }); // filter visible or not visible $accompanyingPeriods = array_filter($accompanyingPeriodsRaw, function (AccompanyingPeriod $ap) { return $this->isGranted(AccompanyingPeriodVoter::SEE, $ap); }); return $this->render('@ChillPerson/AccompanyingPeriod/list.html.twig', [ 'accompanying_periods' => $accompanyingPeriods, 'person' => $person, ]); } public function openAction(int $person_id, Request $request): Response { $person = $this->_getPerson($person_id); $this->denyAccessUnlessGranted( PersonVoter::UPDATE, $person, 'You are not allowed to update this person' ); //in case the person is already open if ($person->isOpen()) { $this->get('session')->getFlashBag() ->add('error', $this->get('translator') ->trans( 'Error! Period %name% is not closed ; it can be open', ['%name%' => $person->__toString()] )); return $this->redirect( $this->generateUrl('chill_person_accompanying_period_list', [ 'person_id' => $person->getId(), ]) ); } $accompanyingPeriod = new AccompanyingPeriod(new DateTime()); $form = $this->createForm( AccompanyingPeriodType::class, $accompanyingPeriod, [ 'period_action' => 'open', 'center' => $person->getCenter(), ] ); if ($request->getMethod() === 'POST') { $form->handleRequest($request); if ($form->isValid()) { $person->open($accompanyingPeriod); $errors = $this->_validatePerson($person); if (count($errors) <= 0) { $this->get('session')->getFlashBag() ->add('success', $this->get('translator') ->trans( 'An accompanying period has been opened.', ['%name%' => $person->__toString()] )); $this->getDoctrine()->getManager()->flush(); return $this->redirect( $this->generateUrl('chill_person_accompanying_period_list', [ 'person_id' => $person->getId(), ]) ); } $this->get('session')->getFlashBag() ->add('error', $this->get('translator') ->trans('Period not opened')); foreach ($errors as $error) { $this->get('session')->getFlashBag() ->add('info', $error->getMessage()); } } else { // if errors in forms $this->get('session')->getFlashBag() ->add( 'error', $this->get('translator') ->trans('Period not opened : form is invalid') ); } } return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [ 'form' => $form->createView(), 'person' => $person, 'accompanying_period' => $accompanyingPeriod, ]); } public function reOpenAction(int $person_id, int $period_id, Request $request): Response { /** @var Person $person */ $person = $this->_getPerson($person_id); /** @var AccompanyingPeriod $period */ $period = array_filter( $person->getAccompanyingPeriods(), static function (AccompanyingPeriod $p) use ($period_id) { return $p->getId() === ($period_id); } )[0] ?? null; if (null === $period) { throw $this->createNotFoundException('period not found'); } $confirm = $request->query->getBoolean('confirm', false); if (true === $confirm && $period->canBeReOpened($person)) { $period->reOpen(); $this->_validatePerson($person); $this->getDoctrine()->getManager()->flush(); $this->addFlash('success', $this->get('translator')->trans( 'The period has been re-opened' )); return $this->redirectToRoute('chill_person_accompanying_period_list', [ 'person_id' => $person->getId(), ]); } if (false === $confirm && $period->canBeReOpened($person)) { return $this->render('ChillPersonBundle:AccompanyingPeriod:re_open.html.twig', [ 'period' => $period, 'person' => $person, ]); } return (new Response()) ->setStatusCode(Response::HTTP_BAD_REQUEST) ->setContent('You cannot re-open this period'); } /** * @throws Exception */ public function updateAction(int $person_id, int $period_id, Request $request): Response { $em = $this->getDoctrine()->getManager(); /** @var AccompanyingPeriod $accompanyingPeriod */ $accompanyingPeriod = $em->getRepository(AccompanyingPeriod::class)->find($period_id); if (null === $accompanyingPeriod) { throw $this->createNotFoundException('Period with id ' . $period_id . ' is not found'); } /** @var Person $person */ $person = $this->_getPerson($person_id); // CHECK if (!$accompanyingPeriod->containsPerson($person)) { throw new Exception('Accompanying period ' . $period_id . ' does not contain person ' . $person_id); } $this->denyAccessUnlessGranted( PersonVoter::UPDATE, $person, 'You are not allowed to update this person' ); $form = $this->createForm( AccompanyingPeriodType::class, $accompanyingPeriod, [ 'period_action' => 'update', 'center' => $person->getCenter(), ] ); if ($request->getMethod() === 'POST') { $form->handleRequest($request); $errors = $this->_validatePerson($person); $flashBag = $this->get('session')->getFlashBag(); if ( $form->isValid(['Default', 'closed']) && count($errors) === 0 ) { $em->flush(); $flashBag->add( 'success', $this->get('translator')->trans('An accompanying period has been updated.') ); return $this->redirect( $this->generateUrl('chill_person_accompanying_period_list', [ 'person_id' => $person->getId(), ]) ); } $flashBag->add('error', $this->get('translator') ->trans('Error when updating the period')); foreach ($errors as $error) { $flashBag->add('info', $error->getMessage()); } } return $this->render('ChillPersonBundle:AccompanyingPeriod:form.html.twig', [ 'form' => $form->createView(), 'person' => $person, 'accompanying_period' => $accompanyingPeriod, ]); } /** * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException */ private function _getPerson(int $id): Person { $person = $this->getDoctrine()->getManager() ->getRepository(\Chill\PersonBundle\Entity\Person::class)->find($id); if (null === $person) { throw $this->createNotFoundException('Person not found'); } $this->denyAccessUnlessGranted( PersonVoter::SEE, $person, 'You are not allowed to see this person' ); return $person; } private function _validatePerson(Person $person): ConstraintViolationListInterface { $errors = $this->validator->validate( $person, null, ['Default'] ); // Can be disabled with config if (false === $this->container->getParameter('chill_person.allow_multiple_simultaneous_accompanying_periods')) { $errors_accompanying_period = $this->validator->validate( $person, null, ['accompanying_period_consistent'] ); foreach ($errors_accompanying_period as $error) { $errors->add($error); } } return $errors; } }