[WIP] get default data from saved exports for center and export steps

This commit is contained in:
2023-06-02 15:32:38 +02:00
parent d1e1b1c4ce
commit fb0afc7e0a
9 changed files with 225 additions and 97 deletions

View File

@@ -13,13 +13,16 @@ namespace Chill\MainBundle\Controller;
use Chill\MainBundle\Entity\SavedExport;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Export\DirectExportInterface;
use Chill\MainBundle\Export\ExportFormHelper;
use Chill\MainBundle\Export\ExportInterface;
use Chill\MainBundle\Export\ExportManager;
use Chill\MainBundle\Form\SavedExportType;
use Chill\MainBundle\Form\Type\Export\ExportType;
use Chill\MainBundle\Form\Type\Export\FormatterType;
use Chill\MainBundle\Form\Type\Export\PickCenterType;
use Chill\MainBundle\Redis\ChillRedis;
use Chill\MainBundle\Repository\SavedExportRepositoryInterface;
use Chill\MainBundle\Security\Authorization\SavedExportVoter;
use Doctrine\ORM\EntityManagerInterface;
use LogicException;
@@ -37,6 +40,7 @@ use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Core\Security;
use Symfony\Contracts\Translation\TranslatorInterface;
use function count;
use function serialize;
@@ -89,6 +93,8 @@ class ExportController extends AbstractController
TranslatorInterface $translator,
EntityManagerInterface $entityManager,
private readonly ExportFormHelper $exportFormHelper,
private readonly SavedExportRepositoryInterface $savedExportRepository,
private readonly Security $security,
) {
$this->entityManager = $entityManager;
$this->redis = $chillRedis;
@@ -103,12 +109,11 @@ class ExportController extends AbstractController
{
/** @var \Chill\MainBundle\Export\ExportManager $exportManager */
$exportManager = $this->exportManager;
$export = $exportManager->getExport($alias);
$key = $request->query->get('key', null);
$savedExport = $this->getSavedExportFromRequest($request);
[$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key);
[$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key, $savedExport);
$formatterAlias = $exportManager->getFormatterAlias($dataExport['export']);
@@ -146,8 +151,9 @@ class ExportController extends AbstractController
/** @var \Chill\MainBundle\Export\ExportManager $exportManager */
$exportManager = $this->exportManager;
$key = $request->query->get('key', null);
$savedExport = $this->getSavedExportFromRequest($request);
[$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key);
[$dataCenters, $dataExport, $dataFormatter] = $this->rebuildData($key, $savedExport);
return $exportManager->generate(
$alias,
@@ -206,12 +212,8 @@ class ExportController extends AbstractController
* 3. 'generate': gather data from session from the previous steps, and
* make a redirection to the "generate" action with data in query (HTTP GET)
*
* @param string $request
* @param Request $alias
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function newAction(Request $request, $alias)
public function newAction(Request $request, string $alias): Response
{
// first check for ACL
$exportManager = $this->exportManager;
@@ -221,20 +223,22 @@ class ExportController extends AbstractController
throw $this->createAccessDeniedException('The user does not have access to this export');
}
$savedExport = $this->getSavedExportFromRequest($request);
$step = $request->query->getAlpha('step', 'centers');
switch ($step) {
case 'centers':
return $this->selectCentersStep($request, $export, $alias);
return $this->selectCentersStep($request, $export, $alias, $savedExport);
case 'export':
return $this->exportFormStep($request, $export, $alias);
return $this->exportFormStep($request, $export, $alias, $savedExport);
case 'formatter':
return $this->formatterFormStep($request, $export, $alias);
return $this->formatterFormStep($request, $export, $alias, $savedExport);
case 'generate':
return $this->forwardToGenerate($request, $export, $alias);
return $this->forwardToGenerate($request, $export, $alias, $savedExport);
default:
throw $this->createNotFoundException("The given step '{$step}' is invalid");
@@ -284,29 +288,35 @@ class ExportController extends AbstractController
/**
* create a form to show on different steps.
*
* @param string $alias
* @param array $data the data from previous step. Required for steps 'formatter' and 'generate_formatter'
* @param mixed $step
*/
protected function createCreateFormExport($alias, $step, $data = []): FormInterface
protected function createCreateFormExport(string $alias, string $step, array $data, ?SavedExport $savedExport): FormInterface
{
/** @var \Chill\MainBundle\Export\ExportManager $exportManager */
$exportManager = $this->exportManager;
$isGenerate = strpos($step, 'generate_') === 0;
$options = match ($step) {
'export', 'generate_export' => ['picked_centers' => $exportManager->getPickedCenters($data['centers'])],
default => [],
};
$defaultFormData = match ($savedExport) {
null => $this->exportFormHelper->getDefaultData($step, $exportManager->getExport($alias), $options),
default => $this->exportFormHelper->savedExportDataToFormData($savedExport, $step, $options),
};
$builder = $this->formFactory
->createNamedBuilder(
null,
FormType::class,
$this->exportFormHelper->getDefaultData($step, $exportManager->getExport($alias)),
$defaultFormData,
[
'method' => $isGenerate ? 'GET' : 'POST',
'csrf_protection' => $isGenerate ? false : true,
'csrf_protection' => !$isGenerate,
]
);
// TODO: add a condition to be able to select a regroupment of centers?
if ('centers' === $step || 'generate_centers' === $step) {
$builder->add('centers', PickCenterType::class, [
'export_alias' => $alias,
@@ -342,13 +352,8 @@ class ExportController extends AbstractController
*
* When the method is POST, the form is stored if valid, and a redirection
* is done to next step.
*
* @param string $alias
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
*
* @return \Symfony\Component\HttpFoundation\Response
*/
private function exportFormStep(Request $request, $export, $alias)
private function exportFormStep(Request $request, DirectExportInterface|ExportInterface $export, string $alias, ?SavedExport $savedExport = null): Response
{
$exportManager = $this->exportManager;
@@ -364,7 +369,7 @@ class ExportController extends AbstractController
$export = $exportManager->getExport($alias);
$form = $this->createCreateFormExport($alias, 'export', $data);
$form = $this->createCreateFormExport($alias, 'export', $data, $savedExport);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
@@ -386,6 +391,7 @@ class ExportController extends AbstractController
$this->generateUrl('chill_main_export_new', [
'step' => $this->getNextStep('export', $export),
'alias' => $alias,
'from_saved' => $request->get('from_saved', '')
])
);
}
@@ -406,13 +412,8 @@ class ExportController extends AbstractController
*
* If the form is posted and valid, store the data in session and
* redirect to the next step.
*
* @param \Chill\MainBundle\Export\DirectExportInterface|\Chill\MainBundle\Export\ExportInterface $export
* @param string $alias
*
* @return \Symfony\Component\HttpFoundation\Response
*/
private function formatterFormStep(Request $request, $export, $alias)
private function formatterFormStep(Request $request, DirectExportInterface|ExportInterface $export, string $alias, ?SavedExport $savedExport = null): Response
{
// check we have data from the previous step (export step)
$data = $this->session->get('export_step', null);
@@ -424,7 +425,7 @@ class ExportController extends AbstractController
]);
}
$form = $this->createCreateFormExport($alias, 'formatter', $data);
$form = $this->createCreateFormExport($alias, 'formatter', $data, $savedExport);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
@@ -443,6 +444,7 @@ class ExportController extends AbstractController
[
'alias' => $alias,
'step' => $this->getNextStep('formatter', $export),
'from_saved' => $request->get('from_saved', ''),
]
));
}
@@ -469,7 +471,7 @@ class ExportController extends AbstractController
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse
*/
private function forwardToGenerate(Request $request, $export, $alias)
private function forwardToGenerate(Request $request, $export, $alias, ?SavedExport $savedExport)
{
$dataCenters = $this->session->get('centers_step_raw', null);
$dataFormatter = $this->session->get('formatter_step_raw', null);
@@ -501,17 +503,17 @@ class ExportController extends AbstractController
return $this->redirectToRoute('chill_main_export_download', ['key' => $key, 'alias' => $alias]);
}
private function rebuildData($key)
private function rebuildData($key, ?SavedExport $savedExport)
{
$rawData = $this->rebuildRawData($key);
$alias = $rawData['alias'];
$formCenters = $this->createCreateFormExport($alias, 'generate_centers');
$formCenters = $this->createCreateFormExport($alias, 'generate_centers', [], $savedExport);
$formCenters->submit($rawData['centers']);
$dataCenters = $formCenters->getData();
$formExport = $this->createCreateFormExport($alias, 'generate_export', $dataCenters);
$formExport = $this->createCreateFormExport($alias, 'generate_export', $dataCenters, $savedExport);
$formExport->submit($rawData['export']);
$dataExport = $formExport->getData();
@@ -519,7 +521,8 @@ class ExportController extends AbstractController
$formFormatter = $this->createCreateFormExport(
$alias,
'generate_formatter',
$dataExport
$dataExport,
$savedExport
);
$formFormatter->submit($rawData['formatter']);
$dataFormatter = $formFormatter->getData();
@@ -534,12 +537,12 @@ class ExportController extends AbstractController
*
* @return Response
*/
private function selectCentersStep(Request $request, $export, $alias)
private function selectCentersStep(Request $request, $export, $alias, ?SavedExport $savedExport = null)
{
/** @var \Chill\MainBundle\Export\ExportManager $exportManager */
$exportManager = $this->exportManager;
$form = $this->createCreateFormExport($alias, 'centers');
$form = $this->createCreateFormExport($alias, 'centers', [], $savedExport);
if ($request->getMethod() === 'POST') {
$form->handleRequest($request);
@@ -571,6 +574,7 @@ class ExportController extends AbstractController
return $this->redirectToRoute('chill_main_export_new', [
'step' => $this->getNextStep('centers', $export),
'alias' => $alias,
'from_saved' => $request->get('from_saved', ''),
]);
}
}
@@ -677,4 +681,18 @@ class ExportController extends AbstractController
return $rawData;
}
private function getSavedExportFromRequest(Request $request): ?SavedExport
{
$savedExport = match ($savedExportId = $request->query->get('from_saved', '')) {
'' => null,
default => $this->savedExportRepository->find($savedExportId),
};
if (null !== $savedExport && !$this->security->isGranted(SavedExportVoter::EDIT, $savedExport)) {
throw new AccessDeniedHttpException("saved export edition not allowed");
}
return $savedExport;
}
}