. */ namespace App\Controller; use App\Entity\Parts\Part; use App\Form\AdminPages\ImportType; use App\Services\ImportExportSystem\EntityExporter; use App\Services\ImportExportSystem\EntityImporter; use App\Services\LogSystem\EventCommentHelper; use App\Services\Parts\PartsTableActionHandler; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 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\Serializer\Exception\NotNormalizableValueException; use UnexpectedValueException; class PartImportExportController extends AbstractController { public function __construct(private readonly PartsTableActionHandler $partsTableActionHandler, private readonly EntityImporter $entityImporter, private readonly EventCommentHelper $commentHelper) { } #[Route(path: '/parts/import', name: 'parts_import')] public function importParts(Request $request): Response { $this->denyAccessUnlessGranted('@parts.import'); $import_form = $this->createForm(ImportType::class, ['entity_class' => Part::class]); $import_form->handleRequest($request); if ($import_form->isSubmitted() && $import_form->isValid()) { /** @var UploadedFile $file */ $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 = [ 'create_unknown_datastructures' => $data['create_unknown_datastructures'], 'path_delimiter' => $data['path_delimiter'], 'format' => $format, 'part_category' => $data['part_category'], 'class' => Part::class, 'csv_delimiter' => $data['csv_delimiter'], 'part_needs_review' => $data['part_needs_review'], 'abort_on_validation_error' => $data['abort_on_validation_error'], ]; $this->commentHelper->setMessage('Import '.$file->getClientOriginalName()); $entities = []; try { $errors = $this->entityImporter->importFileAndPersistToDB($file, $options, $entities); } catch (UnexpectedValueException $e) { $this->addFlash('error', 'parts.import.flash.error.invalid_file'); if ($e instanceof NotNormalizableValueException) { $this->addFlash('error', $e->getMessage()); } goto ret; } if (!isset($errors) || $errors) { $this->addFlash('error', 'parts.import.flash.error'); } else { $this->addFlash('success', 'parts.import.flash.success'); } } ret: return $this->render('parts/import/parts_import.html.twig', [ 'import_form' => $import_form, 'imported_entities' => $entities ?? [], 'import_errors' => $errors ?? [], ]); } #[Route(path: '/parts/export', name: 'parts_export', methods: ['GET'])] public function exportParts(Request $request, EntityExporter $entityExporter): Response { $ids = $request->query->get('ids', ''); $parts = $this->partsTableActionHandler->idStringToArray($ids); if ($parts === []) { throw new \RuntimeException('No parts found!'); } //Ensure that we have access to the parts foreach ($parts as $part) { $this->denyAccessUnlessGranted('read', $part); } return $entityExporter->exportEntityFromRequest($parts, $request); } }