entityWorkflowManager = $entityWorkflowManager; $this->entityWorkflowRepository = $entityWorkflowRepository; $this->validator = $validator; $this->paginatorFactory = $paginatorFactory; $this->registry = $registry; $this->entityManager = $entityManager; $this->translator = $translator; } /** * @Route("/{_locale}/main/workflow/create", name="chill_main_workflow_create") */ public function create(Request $request): Response { if (!$request->query->has('entityClass')) { throw new BadRequestHttpException('Missing entityClass parameter'); } if (!$request->query->has('entityId')) { throw new BadRequestHttpException('missing entityId parameter'); } if (!$request->query->has('workflow')) { throw new BadRequestHttpException('missing workflow parameter'); } $entityWorkflow = new EntityWorkflow(); $entityWorkflow ->setRelatedEntityClass($request->query->get('entityClass')) ->setRelatedEntityId($request->query->getInt('entityId')) ->setWorkflowName($request->query->get('workflow')) ->addSubscriberToStep($this->getUser()) ->addSubscriberToFinal($this->getUser()); $errors = $this->validator->validate($entityWorkflow, null, ['creation']); if (count($errors) > 0) { $msg = []; foreach ($errors as $error) { /** @var \Symfony\Component\Validator\ConstraintViolationInterface $error */ $msg[] = $error->getMessage(); } return new Response(implode("\n", $msg), Response::HTTP_UNPROCESSABLE_ENTITY); } $this->denyAccessUnlessGranted(EntityWorkflowVoter::CREATE, $entityWorkflow); $em = $this->getDoctrine()->getManager(); $em->persist($entityWorkflow); $em->flush(); return $this->redirectToRoute('chill_main_workflow_show', ['id' => $entityWorkflow->getId()]); } /** * @Route("/{_locale}/main/workflow/{id}/delete", name="chill_main_workflow_delete") */ public function delete(EntityWorkflow $entityWorkflow, Request $request): Response { $this->denyAccessUnlessGranted(EntityWorkflowVoter::DELETE, $entityWorkflow); $form = $this->createForm(FormType::class); $form->add('submit', SubmitType::class, ['label' => 'workflow.Delete workflow']); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { $this->entityManager->remove($entityWorkflow); $this->entityManager->flush(); $this->addFlash('success', $this->translator->trans('workflow.Workflow deleted with success')); return $this->redirectToRoute('chill_main_homepage'); } return $this->render('@ChillMain/Workflow/delete.html.twig', [ 'entityWorkflow' => $entityWorkflow, 'delete_form' => $form->createView(), 'handler' => $this->entityWorkflowManager->getHandler($entityWorkflow), ]); } /** * @Route("/{_locale}/main/workflow-step/{id}/access_key", name="chill_main_workflow_grant_access_by_key") */ public function getAccessByAccessKey(EntityWorkflowStep $entityWorkflowStep, Request $request): Response { if (null === $accessKey = $request->query->get('accessKey', null)) { throw new BadRequestException('accessKey is missing'); } if (!$this->getUser() instanceof User) { throw new AccessDeniedException('Not a valid user'); } if ($entityWorkflowStep->getAccessKey() !== $accessKey) { throw new AccessDeniedException('Access key is invalid'); } if (!$entityWorkflowStep->isWaitingForTransition()) { $this->addFlash('error', $this->translator->trans('workflow.Steps is not waiting for transition. Maybe someone apply the transition before you ?')); } else { $entityWorkflowStep->addDestUserByAccessKey($this->getUser()); $this->entityManager->flush(); $this->addFlash('success', $this->translator->trans('workflow.You get access to this step')); } return $this->redirectToRoute('chill_main_workflow_show', ['id' => $entityWorkflowStep->getEntityWorkflow()->getId()]); } /** * Previous workflows where the user has applyed a transition. * * @Route("/{_locale}/main/workflow/list/previous_transitionned", name="chill_main_workflow_list_previous_transitionned") */ public function myPreviousWorkflowsTransitionned(Request $request): Response { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $total = $this->entityWorkflowRepository->countByPreviousTransitionned($this->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findByPreviousTransitionned( $this->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() ); return $this->render( '@ChillMain/Workflow/list.html.twig', [ 'help' => 'workflow.Previous workflow transitionned help', 'workflows' => $this->buildHandler($workflows), 'paginator' => $paginator, 'step' => 'previous_transitionned', ] ); } /** * Previous workflows where the user was mentioned, but did not give any reaction. * * @Route("/{_locale}/main/workflow/list/previous_without_reaction", name="chill_main_workflow_list_previous_without_reaction") */ public function myPreviousWorkflowsWithoutReaction(Request $request): Response { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $total = $this->entityWorkflowRepository->countByPreviousDestWithoutReaction($this->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findByPreviousDestWithoutReaction( $this->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() ); return $this->render( '@ChillMain/Workflow/list.html.twig', [ 'help' => 'workflow.Previous workflow without reaction help', 'workflows' => $this->buildHandler($workflows), 'paginator' => $paginator, 'step' => 'previous_without_reaction', ] ); } /** * @Route("/{_locale}/main/workflow/list/dest", name="chill_main_workflow_list_dest") */ public function myWorkflowsDest(Request $request): Response { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $total = $this->entityWorkflowRepository->countByDest($this->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findByDest( $this->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() ); return $this->render( '@ChillMain/Workflow/list.html.twig', [ 'workflows' => $this->buildHandler($workflows), 'paginator' => $paginator, 'step' => 'dest', ] ); } /** * @Route("/{_locale}/main/workflow/list/subscribed", name="chill_main_workflow_list_subscribed") */ public function myWorkflowsSubscribed(Request $request): Response { $this->denyAccessUnlessGranted('IS_AUTHENTICATED_REMEMBERED'); $total = $this->entityWorkflowRepository->countBySubscriber($this->getUser()); $paginator = $this->paginatorFactory->create($total); $workflows = $this->entityWorkflowRepository->findBySubscriber( $this->getUser(), ['createdAt' => 'DESC'], $paginator->getItemsPerPage(), $paginator->getCurrentPageFirstItemNumber() ); return $this->render( '@ChillMain/Workflow/list.html.twig', [ 'workflows' => $this->buildHandler($workflows), 'paginator' => $paginator, 'step' => 'subscribed', ] ); } /** * @Route("/{_locale}/main/workflow/{id}/show", name="chill_main_workflow_show") */ public function show(EntityWorkflow $entityWorkflow, Request $request): Response { $this->denyAccessUnlessGranted(EntityWorkflowVoter::SEE, $entityWorkflow); $handler = $this->entityWorkflowManager->getHandler($entityWorkflow); $workflow = $this->registry->get($entityWorkflow, $entityWorkflow->getWorkflowName()); $errors = []; if (count($workflow->getEnabledTransitions($entityWorkflow)) > 0) { // possible transition $transitionForm = $this->createForm( WorkflowStepType::class, $entityWorkflow->getCurrentStep(), ['transition' => true, 'entity_workflow' => $entityWorkflow] ); $transitionForm->handleRequest($request); if ($transitionForm->isSubmitted() && $transitionForm->isValid()) { if (!$workflow->can($entityWorkflow, $transition = $transitionForm['transition']->getData()->getName())) { $blockers = $workflow->buildTransitionBlockerList($entityWorkflow, $transition); $msgs = array_map(function (TransitionBlocker $tb) { return $this->translator->trans( $tb->getMessage(), $tb->getParameters() ); }, iterator_to_array($blockers)); throw $this->createAccessDeniedException( sprintf( "not allowed to apply transition {$transition}: %s", implode(', ', $msgs) ) ); } $entityWorkflow->futureDestUsers = $transitionForm['future_dest_users']->getData(); $entityWorkflow->futureDestEmails = $transitionForm['future_dest_emails']->getData(); $workflow->apply($entityWorkflow, $transition); foreach ($transitionForm['future_dest_users']->getData() as $user) { $entityWorkflow->getCurrentStep()->addDestUser($user); } foreach ($transitionForm['future_dest_emails']->getData() as $email) { $entityWorkflow->getCurrentStep()->addDestEmail($email); } $this->entityManager->flush(); return $this->redirectToRoute('chill_main_workflow_show', ['id' => $entityWorkflow->getId()]); } if ($transitionForm->isSubmitted() && !$transitionForm->isValid()) { $this->addFlash('error', $this->translator->trans('This form contains errors')); } } /* $commentForm = $this->createForm(EntityWorkflowCommentType::class, $newComment = new EntityWorkflowComment()); $commentForm->handleRequest($request); if ($commentForm->isSubmitted() && $commentForm->isValid()) { $this->entityManager->persist($newComment); $this->entityManager->flush(); $this->addFlash('success', $this->translator->trans('workflow.Comment added')); return $this->redirectToRoute('chill_main_workflow_show', ['id' => $entityWorkflow->getId()]); } elseif ($commentForm->isSubmitted() && !$commentForm->isValid()) { $this->addFlash('error', $this->translator->trans('This form contains errors')); } */ return $this->render( '@ChillMain/Workflow/index.html.twig', [ 'handler' => $handler, 'handler_template' => $handler->getTemplate($entityWorkflow), 'handler_template_data' => $handler->getTemplateData($entityWorkflow), 'transition_form' => isset($transitionForm) ? $transitionForm->createView() : null, 'entity_workflow' => $entityWorkflow, 'transition_form_errors' => $errors, //'comment_form' => $commentForm->createView(), ] ); } private function buildHandler(array $workflows): array { $lines = []; foreach ($workflows as $workflow) { $handler = $this->entityWorkflowManager->getHandler($workflow); $lines[] = [ 'handler' => $handler, 'entity_workflow' => $workflow, ]; } return $lines; } }