diff --git a/src/Controller/AdminPages/BaseAdminController.php b/src/Controller/AdminPages/BaseAdminController.php
index 92d5dd5d..2619f9f5 100644
--- a/src/Controller/AdminPages/BaseAdminController.php
+++ b/src/Controller/AdminPages/BaseAdminController.php
@@ -58,6 +58,7 @@ use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
+use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Validator\ConstraintViolationList;
use Symfony\Contracts\Translation\TranslatorInterface;
@@ -338,17 +339,33 @@ abstract class BaseAdminController extends AbstractController
$file = $import_form['file']->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 = [
'parent' => $data['parent'],
'preserve_children' => $data['preserve_children'],
- 'format' => $data['format'],
+ 'format' => $format,
'class' => $this->entity_class,
'csv_delimiter' => $data['csv_delimiter'],
];
$this->commentHelper->setMessage('Import '.$file->getClientOriginalName());
- $errors = $importer->importFileAndPersistToDB($file, $options);
+ try {
+ $errors = $importer->importFileAndPersistToDB($file, $options);
+ }
+ catch (UnexpectedValueException $e) {
+ $this->addFlash('error', 'parts.import.flash.error.invalid_file');
+ goto ret;
+ }
foreach ($errors as $name => $error) {
/** @var ConstraintViolationList $error */
@@ -383,6 +400,7 @@ abstract class BaseAdminController extends AbstractController
$em->flush();
}
+ ret:
return $this->renderForm($this->twig_template, [
'entity' => $new_entity,
'form' => $form,
diff --git a/src/Controller/PartImportExportController.php b/src/Controller/PartImportExportController.php
index 9abf88d2..4d4aa54c 100644
--- a/src/Controller/PartImportExportController.php
+++ b/src/Controller/PartImportExportController.php
@@ -33,7 +33,7 @@ use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
-use Symfony\Component\Validator\ConstraintViolationList;
+use UnexpectedValueException;
class PartImportExportController extends AbstractController
{
@@ -64,9 +64,19 @@ class PartImportExportController extends AbstractController
$file = $import_form['file']->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 = [
'preserve_children' => $data['preserve_children'],
- 'format' => $data['format'],
+ 'format' => $format,
'part_category' => $data['part_category'],
'class' => Part::class,
'csv_delimiter' => $data['csv_delimiter'],
@@ -76,7 +86,12 @@ class PartImportExportController extends AbstractController
$entities = [];
- $errors = $this->entityImporter->importFileAndPersistToDB($file, $options, $entities);
+ try {
+ $errors = $this->entityImporter->importFileAndPersistToDB($file, $options, $entities);
+ } catch (UnexpectedValueException $e) {
+ $this->addFlash('error', 'parts.import.flash.error.invalid_file');
+ goto ret;
+ }
if ($errors) {
$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', [
'import_form' => $import_form,
'imported_entities' => $entities ?? [],
diff --git a/src/Form/AdminPages/ImportType.php b/src/Form/AdminPages/ImportType.php
index 71e088a3..ba0c7db7 100644
--- a/src/Form/AdminPages/ImportType.php
+++ b/src/Form/AdminPages/ImportType.php
@@ -57,6 +57,7 @@ class ImportType extends AbstractType
->add('format', ChoiceType::class, [
'choices' => [
+ 'parts.import.format.auto' => 'auto',
'JSON' => 'json',
'XML' => 'xml',
'CSV' => 'csv',
diff --git a/src/Services/ImportExportSystem/EntityImporter.php b/src/Services/ImportExportSystem/EntityImporter.php
index a6d82daa..25e4338b 100644
--- a/src/Services/ImportExportSystem/EntityImporter.php
+++ b/src/Services/ImportExportSystem/EntityImporter.php
@@ -279,6 +279,33 @@ class EntityImporter
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.
*
diff --git a/tests/Services/ImportExportSystem/EntityImporterTest.php b/tests/Services/ImportExportSystem/EntityImporterTest.php
index 79599c8e..57f8784e 100644
--- a/tests/Services/ImportExportSystem/EntityImporterTest.php
+++ b/tests/Services/ImportExportSystem/EntityImporterTest.php
@@ -151,4 +151,24 @@ EOT;
$this->assertCount(2, $errors);
$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));
+ }
}
diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf
index 1f81354d..a7f4bf2d 100644
--- a/translations/messages.en.xlf
+++ b/translations/messages.en.xlf
@@ -6674,7 +6674,6 @@ If you have done this incorrectly or if a computer is no longer trusted, you can
The parent can not be one of the children of itself.
-
obsolete
@@ -11038,5 +11037,23 @@ Element 3
Errors during import. This is most likely caused by some invalid data.
+
+
+ parts.import.format.auto
+ Automatic (based on file extension)
+
+
+
+
+ parts.import.flash.error.unknown_format
+ Could not determine the format from the given file!
+
+
+
+
+ parts.import.flash.error.invalid_file
+ File invalid / malformatted. Please check that you have selected the right format!
+
+