Improved EntityExporter to handle recursive exports

This commit is contained in:
Jan Böhmer 2024-06-23 00:11:38 +02:00
parent f6e955b487
commit bbf7222a6a
2 changed files with 26 additions and 1 deletions

View file

@ -51,7 +51,7 @@ class StructuralElementNormalizer implements NormalizerInterface
/** /**
* @return array<string, mixed> * @return array<string, mixed>
*/ */
public function normalize($object, string $format = null, array $context = []): array public function normalize($object, string $format = null, array $context = []): mixed
{ {
if (!$object instanceof AbstractStructuralDBElement) { if (!$object instanceof AbstractStructuralDBElement) {
throw new \InvalidArgumentException('This normalizer only supports AbstractStructural objects!'); throw new \InvalidArgumentException('This normalizer only supports AbstractStructural objects!');
@ -59,6 +59,10 @@ class StructuralElementNormalizer implements NormalizerInterface
$data = $this->normalizer->normalize($object, $format, $context); $data = $this->normalizer->normalize($object, $format, $context);
if (!is_array($data)) {
return $data;
}
//Remove type field for CSV export //Remove type field for CSV export
if ($format === 'csv') { if ($format === 'csv') {
unset($data['type']); unset($data['type']);

View file

@ -23,9 +23,13 @@ declare(strict_types=1);
namespace App\Services\ImportExportSystem; namespace App\Services\ImportExportSystem;
use App\Entity\Base\AbstractNamedDBElement; use App\Entity\Base\AbstractNamedDBElement;
use App\Entity\Base\AbstractStructuralDBElement;
use App\Helpers\FilenameSanatizer; use App\Helpers\FilenameSanatizer;
use App\Serializer\APIPlatform\SkippableItemNormalizer;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
use InvalidArgumentException; use InvalidArgumentException;
use Symfony\Component\Serializer\Exception\CircularReferenceException;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use function is_array; use function is_array;
use ReflectionClass; use ReflectionClass;
use ReflectionException; use ReflectionException;
@ -97,10 +101,27 @@ class EntityExporter
'csv_delimiter' => $options['csv_delimiter'], 'csv_delimiter' => $options['csv_delimiter'],
'xml_root_node_name' => 'PartDBExport', 'xml_root_node_name' => 'PartDBExport',
'partdb_export' => true, 'partdb_export' => true,
//Skip the item normalizer, so that we dont get IRIs in the output
SkippableItemNormalizer::DISABLE_ITEM_NORMALIZER => true,
//Handle circular references
AbstractNormalizer::CIRCULAR_REFERENCE_HANDLER => $this->handleCircularReference(...),
] ]
); );
} }
private function handleCircularReference(object $object, string $format, array $context): string
{
if ($object instanceof AbstractStructuralDBElement) {
return $object->getFullPath("->");
} elseif ($object instanceof AbstractNamedDBElement) {
return $object->getName();
} elseif ($object instanceof \Stringable) {
return $object->__toString();
}
throw new CircularReferenceException('Circular reference detected for object of type '.get_class($object));
}
/** /**
* Exports an Entity or an array of entities to multiple file formats. * Exports an Entity or an array of entities to multiple file formats.
* *