mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-22 18:03:37 +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\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,
|
||||||
|
|
|
@ -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 ?? [],
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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.
|
||||||
*
|
*
|
||||||
|
|
|
@ -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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue