diff --git a/src/Serializer/StructuralElementNormalizer.php b/src/Serializer/StructuralElementNormalizer.php index 105aad76..3af8d293 100644 --- a/src/Serializer/StructuralElementNormalizer.php +++ b/src/Serializer/StructuralElementNormalizer.php @@ -51,7 +51,7 @@ class StructuralElementNormalizer implements NormalizerInterface /** * @return array */ - public function normalize($object, string $format = null, array $context = []): array + public function normalize($object, string $format = null, array $context = []): mixed { if (!$object instanceof AbstractStructuralDBElement) { throw new \InvalidArgumentException('This normalizer only supports AbstractStructural objects!'); @@ -59,6 +59,10 @@ class StructuralElementNormalizer implements NormalizerInterface $data = $this->normalizer->normalize($object, $format, $context); + if (!is_array($data)) { + return $data; + } + //Remove type field for CSV export if ($format === 'csv') { unset($data['type']); diff --git a/src/Services/ImportExportSystem/EntityExporter.php b/src/Services/ImportExportSystem/EntityExporter.php index 2619c975..c37db50c 100644 --- a/src/Services/ImportExportSystem/EntityExporter.php +++ b/src/Services/ImportExportSystem/EntityExporter.php @@ -23,9 +23,13 @@ declare(strict_types=1); namespace App\Services\ImportExportSystem; use App\Entity\Base\AbstractNamedDBElement; +use App\Entity\Base\AbstractStructuralDBElement; use App\Helpers\FilenameSanatizer; +use App\Serializer\APIPlatform\SkippableItemNormalizer; use Symfony\Component\OptionsResolver\OptionsResolver; use InvalidArgumentException; +use Symfony\Component\Serializer\Exception\CircularReferenceException; +use Symfony\Component\Serializer\Normalizer\AbstractNormalizer; use function is_array; use ReflectionClass; use ReflectionException; @@ -97,10 +101,27 @@ class EntityExporter 'csv_delimiter' => $options['csv_delimiter'], 'xml_root_node_name' => 'PartDBExport', '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. *