First step to async generation [WIP]

This commit is contained in:
2025-02-20 14:33:50 +01:00
parent 732b7dc8f7
commit 057c34610d
20 changed files with 489 additions and 41 deletions

View File

@@ -165,25 +165,31 @@ class ExportManager
$this->formatters[$alias] = $formatter;
}
/**
* Generate a response which contains the requested data.
*/
public function generate(string $exportAlias, array $pickedCentersData, array $data, array $formatterData): Response
public function generateExport(string $exportAlias, array $pickedCentersData, array $data, array $formatterData, User $byUser): FormattedExportGeneration
{
$export = $this->getExport($exportAlias);
$centers = $this->getPickedCenters($pickedCentersData);
$context = new ExportGenerationContext($byUser);
if ($export instanceof DirectExportInterface) {
return $export->generate(
$generatedExport = $export->generate(
$this->buildCenterReachableScopes($centers, $export),
$data[ExportType::EXPORT_KEY]
$data[ExportType::EXPORT_KEY],
);
if ($generatedExport instanceof Response) {
trigger_deprecation('chill-project/chill-bundles', '3.10', 'DirectExportInterface should not return a %s instance, but a %s instance', Response::class, FormattedExportGeneration::class);
return new FormattedExportGeneration($generatedExport->getContent(), $generatedExport->headers->get('Content-Type'));
}
return $generatedExport;
}
$query = $export->initiateQuery(
$this->retrieveUsedModifiers($data),
$this->buildCenterReachableScopes($centers, $export),
$data[ExportType::EXPORT_KEY]
$export->denormalizeFormData($data[ExportType::EXPORT_KEY], $context),
);
if ($query instanceof \Doctrine\ORM\NativeQuery) {
@@ -194,10 +200,10 @@ class ExportManager
}
} elseif ($query instanceof QueryBuilder) {
// handle filters
$this->handleFilters($export, $query, $data[ExportType::FILTER_KEY], $centers);
$this->handleFilters($export, $query, $data[ExportType::FILTER_KEY], $centers, $context);
// handle aggregators
$this->handleAggregators($export, $query, $data[ExportType::AGGREGATOR_KEY], $centers);
$this->handleAggregators($export, $query, $data[ExportType::AGGREGATOR_KEY], $centers, $context);
$this->logger->notice('[export] will execute this qb in export', [
'dql' => $query->getDQL(),
@@ -206,7 +212,7 @@ class ExportManager
throw new \UnexpectedValueException('The method `intiateQuery` should return a `\Doctrine\ORM\NativeQuery` or a `Doctrine\ORM\QueryBuilder` object.');
}
$result = $export->getResult($query, $data[ExportType::EXPORT_KEY]);
$result = $export->getResult($query, $export->denormalizeFormData($data[ExportType::EXPORT_KEY], $context));
if (!is_iterable($result)) {
throw new \UnexpectedValueException(sprintf('The result of the export should be an iterable, %s given', \gettype($result)));
@@ -231,14 +237,44 @@ class ExportManager
$filtersData[$alias] = $data[ExportType::FILTER_KEY][$alias]['form'];
}
return $formatter->getResponse(
if (method_exists($formatter, 'generate')) {
return $formatter->generate(
$result,
$formatterData,
$exportAlias,
$data[ExportType::EXPORT_KEY],
$filtersData,
$aggregatorsData,
);
}
trigger_deprecation('chill-project/chill-bundles', '3.10', '%s should implements the "generate" method', FormatterInterface::class);
$generatedExport = $formatter->getResponse(
$result,
$formatterData,
$exportAlias,
$data[ExportType::EXPORT_KEY],
$filtersData,
$aggregatorsData
$aggregatorsData,
);
return new FormattedExportGeneration($generatedExport->getContent(), $generatedExport->headers->get('content-type'));
}
/**
* Generate a response which contains the requested data.
*/
public function generate(string $exportAlias, array $pickedCentersData, array $data, array $formatterData): Response
{
$generated = $this->generateExport(
$exportAlias,
$pickedCentersData,
$data,
$formatterData,
);
return new Response($generated->content, headers: ['Content-Type' => $generated->contentType]);
}
/**
@@ -453,6 +489,7 @@ class ExportManager
DirectExportInterface|ExportInterface|null $export = null,
?array $centers = null,
): bool {
dump(__METHOD__, $this->tokenStorage->getToken()->getUser());
if ($element instanceof ExportInterface || $element instanceof DirectExportInterface) {
$role = $element->requiredRole();
} else {
@@ -473,7 +510,7 @@ class ExportManager
$role
);
}
dump($centers);
foreach ($centers as $center) {
if (false === $this->authorizationChecker->isGranted($role, $center)) {
// debugging
@@ -534,16 +571,13 @@ class ExportManager
QueryBuilder $qb,
array $data,
array $center,
ExportGenerationContext $context,
) {
$aggregators = $this->retrieveUsedAggregators($data);
foreach ($aggregators as $alias => $aggregator) {
if (false === $this->isGrantedForElement($aggregator, $export, $center)) {
throw new UnauthorizedHttpException('You are not authorized to use the aggregator'.$aggregator->getTitle());
}
$formData = $data[$alias];
$aggregator->alterQuery($qb, $formData['form']);
$aggregator->alterQuery($qb, $aggregator->denormalizeFormData($formData['form'], $context));
}
}
@@ -561,20 +595,17 @@ class ExportManager
QueryBuilder $qb,
mixed $data,
array $centers,
ExportGenerationContext $context,
) {
$filters = $this->retrieveUsedFilters($data);
foreach ($filters as $alias => $filter) {
if (false === $this->isGrantedForElement($filter, $export, $centers)) {
throw new UnauthorizedHttpException('You are not authorized to use the filter '.$filter->getTitle());
}
$formData = $data[$alias];
$this->logger->debug('alter query by filter '.$alias, [
'class' => self::class, 'function' => __FUNCTION__,
]);
$filter->alterQuery($qb, $formData['form']);
$filter->alterQuery($qb, $filter->denormalizeFormData($formData['form'], $context));
}
}