Added possibility to autoselect the import format

This commit is contained in:
Jan Böhmer 2023-03-12 21:43:40 +01:00
parent 61e2dde400
commit 508641d1e8
6 changed files with 106 additions and 6 deletions

View file

@ -58,6 +58,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface; use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Validator\ConstraintViolationList; use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Contracts\Translation\TranslatorInterface; use Symfony\Contracts\Translation\TranslatorInterface;
@ -338,17 +339,33 @@ abstract class BaseAdminController extends AbstractController
$file = $import_form['file']->getData(); $file = $import_form['file']->getData();
$data = $import_form->getData(); $data = $import_form->getData();
if ($data['format'] === 'auto') {
$format = $importer->determineFormat($file->getClientOriginalExtension());
if (null === $format) {
$this->addFlash('error', 'parts.import.flash.error.unknown_format');
goto ret;
}
} else {
$format = $data['format'];
}
$options = [ $options = [
'parent' => $data['parent'], 'parent' => $data['parent'],
'preserve_children' => $data['preserve_children'], 'preserve_children' => $data['preserve_children'],
'format' => $data['format'], 'format' => $format,
'class' => $this->entity_class, 'class' => $this->entity_class,
'csv_delimiter' => $data['csv_delimiter'], 'csv_delimiter' => $data['csv_delimiter'],
]; ];
$this->commentHelper->setMessage('Import '.$file->getClientOriginalName()); $this->commentHelper->setMessage('Import '.$file->getClientOriginalName());
try {
$errors = $importer->importFileAndPersistToDB($file, $options); $errors = $importer->importFileAndPersistToDB($file, $options);
}
catch (UnexpectedValueException $e) {
$this->addFlash('error', 'parts.import.flash.error.invalid_file');
goto ret;
}
foreach ($errors as $name => $error) { foreach ($errors as $name => $error) {
/** @var ConstraintViolationList $error */ /** @var ConstraintViolationList $error */
@ -383,6 +400,7 @@ abstract class BaseAdminController extends AbstractController
$em->flush(); $em->flush();
} }
ret:
return $this->renderForm($this->twig_template, [ return $this->renderForm($this->twig_template, [
'entity' => $new_entity, 'entity' => $new_entity,
'form' => $form, 'form' => $form,

View file

@ -33,7 +33,7 @@ use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Validator\ConstraintViolationList; use UnexpectedValueException;
class PartImportExportController extends AbstractController class PartImportExportController extends AbstractController
{ {
@ -64,9 +64,19 @@ class PartImportExportController extends AbstractController
$file = $import_form['file']->getData(); $file = $import_form['file']->getData();
$data = $import_form->getData(); $data = $import_form->getData();
if ($data['format'] === 'auto') {
$format = $this->entityImporter->determineFormat($file->getClientOriginalExtension());
if (null === $format) {
$this->addFlash('error', 'parts.import.flash.error.unknown_format');
goto ret;
}
} else {
$format = $data['format'];
}
$options = [ $options = [
'preserve_children' => $data['preserve_children'], 'preserve_children' => $data['preserve_children'],
'format' => $data['format'], 'format' => $format,
'part_category' => $data['part_category'], 'part_category' => $data['part_category'],
'class' => Part::class, 'class' => Part::class,
'csv_delimiter' => $data['csv_delimiter'], 'csv_delimiter' => $data['csv_delimiter'],
@ -76,7 +86,12 @@ class PartImportExportController extends AbstractController
$entities = []; $entities = [];
try {
$errors = $this->entityImporter->importFileAndPersistToDB($file, $options, $entities); $errors = $this->entityImporter->importFileAndPersistToDB($file, $options, $entities);
} catch (UnexpectedValueException $e) {
$this->addFlash('error', 'parts.import.flash.error.invalid_file');
goto ret;
}
if ($errors) { if ($errors) {
$this->addFlash('error', 'parts.import.flash.error'); $this->addFlash('error', 'parts.import.flash.error');
@ -85,6 +100,8 @@ class PartImportExportController extends AbstractController
} }
} }
ret:
return $this->renderForm('parts/import/parts_import.html.twig', [ return $this->renderForm('parts/import/parts_import.html.twig', [
'import_form' => $import_form, 'import_form' => $import_form,
'imported_entities' => $entities ?? [], 'imported_entities' => $entities ?? [],

View file

@ -57,6 +57,7 @@ class ImportType extends AbstractType
->add('format', ChoiceType::class, [ ->add('format', ChoiceType::class, [
'choices' => [ 'choices' => [
'parts.import.format.auto' => 'auto',
'JSON' => 'json', 'JSON' => 'json',
'XML' => 'xml', 'XML' => 'xml',
'CSV' => 'csv', 'CSV' => 'csv',

View file

@ -279,6 +279,33 @@ class EntityImporter
return $this->importString($file->getContent(), $options, $errors); return $this->importString($file->getContent(), $options, $errors);
} }
/**
* Determines the format to import based on the file extension.
* @param string $extension The file extension to use
* @return string The format to use (json, xml, csv, yaml), or null if the extension is unknown
*/
public function determineFormat(string $extension): ?string
{
//Convert the extension to lower case
$extension = strtolower($extension);
switch ($extension) {
case 'json':
return 'json';
case 'xml':
return 'xml';
case 'csv':
case 'tsv':
return 'csv';
case 'yaml':
case 'yml':
return 'yaml';
default:
return null;
}
}
/** /**
* This functions corrects the parent setting based on the children value of the parent. * This functions corrects the parent setting based on the children value of the parent.
* *

View file

@ -151,4 +151,24 @@ EOT;
$this->assertCount(2, $errors); $this->assertCount(2, $errors);
$this->assertSame('Node 1', $errors[0]['entity']->getName()); $this->assertSame('Node 1', $errors[0]['entity']->getName());
} }
public function formatDataProvider(): array
{
return [
['csv', 'csv'],
['csv', 'CSV'],
['xml', 'Xml'],
['json', 'json'],
['yaml', 'yml'],
['yaml', 'YAML'],
];
}
/**
* @dataProvider formatDataProvider
*/
public function testDetermineFormat(string $expected, string $extension): void
{
$this->assertSame($expected, $this->service->determineFormat($extension));
}
} }

View file

@ -6674,7 +6674,6 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
<target>The parent can not be one of the children of itself.</target> <target>The parent can not be one of the children of itself.</target>
</segment> </segment>
</unit> </unit>
<unit id="nd207H6" name="validator.part_lot.location_full.no_increasment"> <unit id="nd207H6" name="validator.part_lot.location_full.no_increasment">
<notes> <notes>
<note priority="1">obsolete</note> <note priority="1">obsolete</note>
@ -11038,5 +11037,23 @@ Element 3</target>
<target>Errors during import. This is most likely caused by some invalid data.</target> <target>Errors during import. This is most likely caused by some invalid data.</target>
</segment> </segment>
</unit> </unit>
<unit id="hJHxH3J" name="parts.import.format.auto">
<segment>
<source>parts.import.format.auto</source>
<target>Automatic (based on file extension)</target>
</segment>
</unit>
<unit id="E1zm0rb" name="parts.import.flash.error.unknown_format">
<segment>
<source>parts.import.flash.error.unknown_format</source>
<target>Could not determine the format from the given file!</target>
</segment>
</unit>
<unit id="y2UaCL7" name="parts.import.flash.error.invalid_file">
<segment>
<source>parts.import.flash.error.invalid_file</source>
<target>File invalid / malformatted. Please check that you have selected the right format!</target>
</segment>
</unit>
</file> </file>
</xliff> </xliff>