mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-23 02:09:03 +02:00
Added possibility to autoselect the import format
This commit is contained in:
parent
61e2dde400
commit
508641d1e8
6 changed files with 106 additions and 6 deletions
|
@ -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());
|
||||
|
||||
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,
|
||||
|
|
|
@ -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 = [];
|
||||
|
||||
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 ?? [],
|
||||
|
|
|
@ -57,6 +57,7 @@ class ImportType extends AbstractType
|
|||
|
||||
->add('format', ChoiceType::class, [
|
||||
'choices' => [
|
||||
'parts.import.format.auto' => 'auto',
|
||||
'JSON' => 'json',
|
||||
'XML' => 'xml',
|
||||
'CSV' => 'csv',
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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>
|
||||
</segment>
|
||||
</unit>
|
||||
|
||||
<unit id="nd207H6" name="validator.part_lot.location_full.no_increasment">
|
||||
<notes>
|
||||
<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>
|
||||
</segment>
|
||||
</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>
|
||||
</xliff>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue