Skip to content

Commit

Permalink
feat(admin/submission): add export command filter by expression (#1085)
Browse files Browse the repository at this point in the history
Co-authored-by: David mattei <[email protected]>
  • Loading branch information
theus77 and Davidmattei authored Dec 2, 2024
1 parent f18a109 commit 52ba9b3
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ interface SpreadsheetGeneratorServiceInterface
public const WRITER = 'writer';
public const XLSX_WRITER = 'xlsx';
public const CSV_WRITER = 'csv';
public const FORMAT_WRITERS = [self::CSV_WRITER, self::XLSX_WRITER];
public const CSV_SEPARATOR = 'csv_separator';
public const SHEETS = 'sheets';
public const CONTENT_FILENAME = 'filename';
Expand Down
117 changes: 117 additions & 0 deletions EMS/core-bundle/src/Command/Submission/ExportCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

declare(strict_types=1);

namespace EMS\CoreBundle\Command\Submission;

use EMS\CommonBundle\Common\Command\AbstractCommand;
use EMS\CommonBundle\Contracts\SpreadsheetGeneratorServiceInterface;
use EMS\CommonBundle\Service\ExpressionService;
use EMS\CoreBundle\Commands;
use EMS\CoreBundle\Service\Form\Submission\FormSubmissionService;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class ExportCommand extends AbstractCommand
{
protected static $defaultName = Commands::SUBMISSION_EXPORT;
public const ARG_FIELDS = 'fields';
public const OPTION_FILTER = 'filter';
public const OPTION_FILENAME = 'filename';

/** @var string[] */
private array $fields;
private ?string $filter;
private ?string $filename;

public function __construct(
private readonly FormSubmissionService $formSubmissionService,
private readonly ExpressionService $expressionService,
private readonly SpreadsheetGeneratorServiceInterface $spreadsheetGeneratorService,
) {
parent::__construct();
}

protected function configure(): void
{
$this
->setDescription('Extract form submissions')
->addArgument(
self::ARG_FIELDS,
InputArgument::IS_ARRAY,
'Fields to export'
)->addOption(
self::OPTION_FILTER,
null,
InputOption::VALUE_OPTIONAL,
'Expression to filter submissions, e.g. "\'true\' == (data[\'recontact-optin\'] ?? \'false\')". The following variables are available: data (array), instance (string), name (string), locale (string), submission_date (date in the ISO 8601 format)'
)->addOption(
self::OPTION_FILENAME,
null,
InputOption::VALUE_OPTIONAL,
'Export filename, xlsx or csv formats are supported',
);
}

protected function initialize(InputInterface $input, OutputInterface $output): void
{
parent::initialize($input, $output);
$this->fields = $this->getArgumentStringArray(self::ARG_FIELDS);
$this->filter = $this->getOptionStringNull(self::OPTION_FILTER);
$this->filename = $this->getOptionStringNull(self::OPTION_FILENAME);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->io->section('Export the form submissions');
$sheet = [];

$this->io->progressStart($this->formSubmissionService->count());
foreach ($this->formSubmissionService->getUnprocessed() as $submission) {
$data = [
'instance' => $submission->getInstance(),
'name' => $submission->getName(),
'locale' => $submission->getLocale(),
'submission_date' => $submission->getCreated()->format('c'),
'data' => $submission->getData() ?? [],
];
if (null !== $this->filter && !$this->expressionService->evaluateToBool($this->filter, $data)) {
$this->io->progressAdvance();
continue;
}
$line = [];
foreach ($this->fields as $field) {
$line[] = $data['data'][$field] ?? $data[$field] ?? '';
}
$sheet[] = $line;
$this->io->progressAdvance();
}
$this->io->progressFinish();

if (null === $this->filename) {
$this->io->table([...$this->fields], $sheet);

return self::EXECUTE_SUCCESS;
}

$extension = \pathinfo($this->filename)['extension'] ?? '';
if (!\in_array($extension, SpreadsheetGeneratorServiceInterface::FORMAT_WRITERS)) {
$this->io->error(\sprintf('File format %s is not supported', $extension));
}

$config = [
SpreadsheetGeneratorServiceInterface::SHEETS => [[
'rows' => [[...$this->fields], ...$sheet],
'name' => 'submissions',
]],
SpreadsheetGeneratorServiceInterface::CONTENT_FILENAME => 'submissions',
SpreadsheetGeneratorServiceInterface::WRITER => $extension,
];
$this->spreadsheetGeneratorService->generateSpreadsheetFile($config, $this->filename);
$this->io->success(\sprintf('The file %s has been successfully generated', $this->filename));

return self::EXECUTE_SUCCESS;
}
}
1 change: 1 addition & 0 deletions EMS/core-bundle/src/Commands.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,5 @@ final class Commands
public const MANAGED_ALIAS_ADD_ENVIRONMENT = 'emsco:managed-alias:add-environment';
public const ASSET_REFRESH_FILE_FIELD = 'emsco:asset:refresh-file-fields';
final public const SUBMISSION_FORWARD = 'emsco:submissions:forward';
final public const SUBMISSION_EXPORT = 'emsco:submissions:export';
}
4 changes: 2 additions & 2 deletions EMS/core-bundle/src/Repository/FormSubmissionRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public function findAllUnprocessed(): array
->andWhere($qb->expr()->isNotNull('fs.data'))
->orderBy('fs.created', 'desc');

return $qb->getQuery()->getArrayResult();
return $qb->getQuery()->execute();
}

public function countAllUnprocessed(string $searchValue): int
Expand Down Expand Up @@ -105,7 +105,7 @@ public function findFormSubmissions(?string $formInstance = null): array
->andWhere($qb->expr()->isNotNull('fs.data'))
->orderBy('fs.created', 'desc');

return $qb->getQuery()->getArrayResult();
return $qb->getQuery()->execute();
}

public function persist(FormSubmission $formSubmission): void
Expand Down
6 changes: 6 additions & 0 deletions EMS/core-bundle/src/Resources/config/command.xml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,12 @@
<argument type="service" id="ems.form_submission"/>
<tag name="console.command"/>
</service>
<service id="ems.submission.export" class="EMS\CoreBundle\Command\Submission\ExportCommand">
<argument type="service" id="ems.form_submission"/>
<argument type="service" id="ems_common.service.expression_service"/>
<argument type="service" id="EMS\CommonBundle\Contracts\SpreadsheetGeneratorServiceInterface"/>
<tag name="console.command"/>
</service>
<service id="ems.environment.updatemetafield" class="EMS\CoreBundle\Command\UpdateMetaFieldCommand">
<argument type="service" id="doctrine"/>
<argument type="service" id="logger"/>
Expand Down

0 comments on commit 52ba9b3

Please sign in to comment.