diff --git a/src/Bundle/ChillMainBundle/Controller/ExportController.php b/src/Bundle/ChillMainBundle/Controller/ExportController.php index 0b45d5a9a..42ac80de7 100644 --- a/src/Bundle/ChillMainBundle/Controller/ExportController.php +++ b/src/Bundle/ChillMainBundle/Controller/ExportController.php @@ -15,6 +15,7 @@ use Chill\MainBundle\Entity\ExportGeneration; use Chill\MainBundle\Entity\SavedExport; use Chill\MainBundle\Entity\User; use Chill\MainBundle\Export\DirectExportInterface; +use Chill\MainBundle\Export\ExportConfigNormalizer; use Chill\MainBundle\Export\ExportFormHelper; use Chill\MainBundle\Export\ExportInterface; use Chill\MainBundle\Export\ExportManager; @@ -36,11 +37,11 @@ use Symfony\Component\Form\Extension\Core\Type\FormType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\FormFactoryInterface; use Symfony\Component\Form\FormInterface; -use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException; use Symfony\Component\Messenger\Envelope; use Symfony\Component\Messenger\MessageBusInterface; use Symfony\Component\Routing\Annotation\Route; @@ -69,6 +70,7 @@ class ExportController extends AbstractController ParameterBagInterface $parameterBag, private readonly MessageBusInterface $messageBus, private readonly ClockInterface $clock, + private readonly ExportConfigNormalizer $exportConfigNormalizer, ) { $this->filterStatsByCenters = $parameterBag->get('chill_main')['acl']['filter_stats_by_center']; } @@ -76,6 +78,12 @@ class ExportController extends AbstractController #[Route(path: '/{_locale}/exports/download/{alias}', name: 'chill_main_export_download', methods: ['GET'])] public function downloadResultAction(Request $request, mixed $alias) { + $user = $this->security->getUser(); + + if (!$user instanceof User) { + throw new UnauthorizedHttpException('Only regular users can generate exports'); + } + /** @var ExportManager $exportManager */ $exportManager = $this->exportManager; $export = $exportManager->getExport($alias); @@ -84,6 +92,20 @@ class ExportController extends AbstractController [$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key, $savedExport); + $config = [ + 'centers' => $dataCenters, + 'export' => $dataExport['export']['export'] ?? [], + 'filters' => $dataExport['export']['filters'] ?? [], + 'aggregators' => $dataExport['export']['aggregators'] ?? [], + 'formatter' => $dataFormatter, + ]; + + $generation = new ExportGeneration('alias', $config, $this->clock->now()->add(new \DateInterval('P6M'))); + $this->entityManager->persist($generation); + $this->entityManager->flush(); + + $this->messageBus->dispatch(new ExportRequestGenerationMessage($generation, $user)); + $formatterAlias = $exportManager->getFormatterAlias($dataExport['export']); if (null !== $formatterAlias) { @@ -282,7 +304,7 @@ class ExportController extends AbstractController 'formatter', 'generate_formatter' => [ 'export_alias' => $alias, 'formatter_alias' => $exportManager->getFormatterAlias($data['export']), - 'aggregator_aliases' => $exportManager->getUsedAggregatorsAliases($data['export']), + 'aggregator_aliases' => $exportManager->getUsedAggregatorsAliases($data['export']['aggregators']), ], default => [ 'export_alias' => $alias, @@ -437,13 +459,14 @@ class ExportController extends AbstractController * and redirect to the `generate` action. * * The data from previous steps is removed from session. - * - * @param string $alias - * - * @return RedirectResponse */ - private function forwardToGenerate(Request $request, DirectExportInterface|ExportInterface $export, $alias, ?SavedExport $savedExport) + private function forwardToGenerate(Request $request, DirectExportInterface|ExportInterface $export, $alias, ?SavedExport $savedExport): Response { + $user = $this->getUser(); + + if (!$user instanceof User) { + throw new AccessDeniedHttpException('only regular users can generate export'); + } $dataCenters = $this->session->get('centers_step_raw', null); $dataFormatter = $this->session->get('formatter_step_raw', null); $dataExport = $this->session->get('export_step_raw', null); @@ -456,28 +479,75 @@ class ExportController extends AbstractController ]); } - $parameters = [ - 'formatter' => $dataFormatter ?? [], - 'export' => $dataExport ?? [], - 'centers' => $dataCenters ?? [], - 'alias' => $alias, - ]; - unset($parameters['_token']); - $key = md5(uniqid((string) random_int(0, mt_getrandmax()), false)); + $dataToNormalize = $this->buildExportDataForNormalization( + $alias, + $dataCenters, + $dataExport, + $dataFormatter, + ); - $this->redis->setEx($key, 3600, \serialize($parameters)); + $this->entityManager->persist( + $exportGeneration = new ExportGeneration( + $alias, + $this->exportConfigNormalizer->normalizeConfig($alias, $dataToNormalize), + $this->clock->now()->add(new \DateInterval('P6M')), + ) + ); + $this->entityManager->flush(); + $this->messageBus->dispatch(new ExportRequestGenerationMessage($exportGeneration, $user)); // remove data from session + $this->session->remove('centers_step_raw'); $this->session->remove('export_step_raw'); $this->session->remove('export_step'); $this->session->remove('formatter_step_raw'); $this->session->remove('formatter_step'); - return $this->redirectToRoute('chill_main_export_download', [ - 'key' => $key, - 'alias' => $alias, - 'from_saved' => $savedExport?->getId(), - ]); + return new Response('ok: '.$exportGeneration->getId()); + } + + /** + * Build the export form data into a way suitable for normalization. + * + * @param string $alias the export alias + * @param array $dataCenters Raw data from center step + * @param array $dataExport Raw data from export step + * @param array $dataFormatter Raw data from formatter step + */ + private function buildExportDataForNormalization(string $alias, array $dataCenters, array $dataExport, array $dataFormatter): array + { + if ($this->filterStatsByCenters) { + $formCenters = $this->createCreateFormExport($alias, 'generate_centers', [], null); + $formCenters->submit($dataCenters); + $dataCenters = $formCenters->getData(); + } else { + $dataCenters = ['centers' => []]; + } + + $formExport = $this->createCreateFormExport($alias, 'generate_export', $dataCenters, null); + $formExport->submit($dataExport); + $dataExport = $formExport->getData(); + + if (\count($dataFormatter) > 0) { + $formFormatter = $this->createCreateFormExport( + $alias, + 'generate_formatter', + $dataExport, + null, + ); + $formFormatter->submit($dataFormatter); + $dataFormatter = $formFormatter->getData(); + } + dump($dataExport); + + return [ + 'centers' => $dataCenters['centers'], + 'export' => $dataExport['export']['export'] ?? [], + 'filters' => $dataExport['export']['filters'] ?? [], + 'aggregators' => $dataExport['export']['aggregators'] ?? [], + 'pick_formatter' => $dataExport['export']['pick_formatter']['alias'], + 'formatter' => $dataFormatter['formatter'] ?? [], + ]; } private function rebuildData($key, ?SavedExport $savedExport)