mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-20 17:15:51 +02:00
Rewrote PartNormalizer so that it does not use ObjectNormalizer directly
This commit is contained in:
parent
e53da5ad06
commit
7a90d3f281
2 changed files with 28 additions and 18 deletions
|
@ -29,21 +29,24 @@ use App\Entity\Parts\Supplier;
|
||||||
use App\Entity\PriceInformations\Orderdetail;
|
use App\Entity\PriceInformations\Orderdetail;
|
||||||
use App\Entity\PriceInformations\Pricedetail;
|
use App\Entity\PriceInformations\Pricedetail;
|
||||||
use Brick\Math\BigDecimal;
|
use Brick\Math\BigDecimal;
|
||||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
|
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
|
||||||
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
|
||||||
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see \App\Tests\Serializer\PartNormalizerTest
|
* @see \App\Tests\Serializer\PartNormalizerTest
|
||||||
* TODO: Properly rewrite this class to use the SerializerAware interface and dont use the ObjectNormalizer directly
|
|
||||||
*/
|
*/
|
||||||
class PartNormalizer implements NormalizerInterface, DenormalizerInterface
|
class PartNormalizer implements NormalizerInterface, DenormalizerInterface, NormalizerAwareInterface, DenormalizerAwareInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
|
use NormalizerAwareTrait;
|
||||||
|
use DenormalizerAwareTrait;
|
||||||
|
|
||||||
|
private const ALREADY_CALLED = 'PART_NORMALIZER_ALREADY_CALLED';
|
||||||
|
|
||||||
private const DENORMALIZE_KEY_MAPPING = [
|
private const DENORMALIZE_KEY_MAPPING = [
|
||||||
'notes' => 'comment',
|
'notes' => 'comment',
|
||||||
'quantity' => 'instock',
|
'quantity' => 'instock',
|
||||||
|
@ -56,10 +59,6 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly StructuralElementFromNameDenormalizer $locationDenormalizer,
|
private readonly StructuralElementFromNameDenormalizer $locationDenormalizer,
|
||||||
#[Autowire(service: ObjectNormalizer::class)]
|
|
||||||
private readonly NormalizerInterface $normalizer,
|
|
||||||
#[Autowire(service: ObjectNormalizer::class)]
|
|
||||||
private readonly DenormalizerInterface $denormalizer,
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -67,20 +66,22 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||||
public function supportsNormalization($data, string $format = null, array $context = []): bool
|
public function supportsNormalization($data, string $format = null, array $context = []): bool
|
||||||
{
|
{
|
||||||
//We only remove the type field for CSV export
|
//We only remove the type field for CSV export
|
||||||
return $format === 'csv' && $data instanceof Part ;
|
return !isset($context[self::ALREADY_CALLED]) && $format === 'csv' && $data instanceof Part ;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public function normalize($object, string $format = null, array $context = []): array
|
||||||
* @return (float|mixed)[]|\ArrayObject|null|scalar
|
|
||||||
*
|
|
||||||
* @psalm-return \ArrayObject|array{total_instock: float|mixed,...}|null|scalar
|
|
||||||
*/
|
|
||||||
public function normalize($object, string $format = null, array $context = [])
|
|
||||||
{
|
{
|
||||||
if (!$object instanceof Part) {
|
if (!$object instanceof Part) {
|
||||||
throw new \InvalidArgumentException('This normalizer only supports Part objects!');
|
throw new \InvalidArgumentException('This normalizer only supports Part objects!');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$context[self::ALREADY_CALLED] = true;
|
||||||
|
|
||||||
|
//Prevent exception in API Platform
|
||||||
|
if ($object->getID() === null) {
|
||||||
|
$context['iri'] = 'not-persisted';
|
||||||
|
}
|
||||||
|
|
||||||
$data = $this->normalizer->normalize($object, $format, $context);
|
$data = $this->normalizer->normalize($object, $format, $context);
|
||||||
|
|
||||||
//Remove type field for CSV export
|
//Remove type field for CSV export
|
||||||
|
@ -93,7 +94,7 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||||
|
|
||||||
public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool
|
public function supportsDenormalization($data, string $type, string $format = null, array $context = []): bool
|
||||||
{
|
{
|
||||||
return is_array($data) && is_a($type, Part::class, true);
|
return !isset($context[self::ALREADY_CALLED]) && is_array($data) && is_a($type, Part::class, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function normalizeKeys(array &$data): array
|
private function normalizeKeys(array &$data): array
|
||||||
|
@ -129,6 +130,8 @@ class PartNormalizer implements NormalizerInterface, DenormalizerInterface
|
||||||
$data['minamount'] = 0.0;
|
$data['minamount'] = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$context[self::ALREADY_CALLED] = true;
|
||||||
|
|
||||||
$object = $this->denormalizer->denormalize($data, $type, $format, $context);
|
$object = $this->denormalizer->denormalize($data, $type, $format, $context);
|
||||||
|
|
||||||
if (!$object instanceof Part) {
|
if (!$object instanceof Part) {
|
||||||
|
|
|
@ -28,17 +28,24 @@ use App\Entity\PriceInformations\Orderdetail;
|
||||||
use App\Entity\PriceInformations\Pricedetail;
|
use App\Entity\PriceInformations\Pricedetail;
|
||||||
use App\Serializer\PartNormalizer;
|
use App\Serializer\PartNormalizer;
|
||||||
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
|
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
|
||||||
|
|
||||||
class PartNormalizerTest extends WebTestCase
|
class PartNormalizerTest extends WebTestCase
|
||||||
{
|
{
|
||||||
/** @var PartNormalizer */
|
/** @var PartNormalizer */
|
||||||
protected $service;
|
protected DenormalizerInterface&NormalizerInterface $service;
|
||||||
|
|
||||||
protected function setUp(): void
|
protected function setUp(): void
|
||||||
{
|
{
|
||||||
//Get a service instance.
|
//Get a service instance.
|
||||||
self::bootKernel();
|
self::bootKernel();
|
||||||
$this->service = self::getContainer()->get(PartNormalizer::class);
|
$this->service = self::getContainer()->get(PartNormalizer::class);
|
||||||
|
|
||||||
|
//We need to inject the serializer into the normalizer, as we use it directly
|
||||||
|
$serializer = self::getContainer()->get('serializer');
|
||||||
|
$this->service->setNormalizer($serializer);
|
||||||
|
$this->service->setDenormalizer($serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testSupportsNormalization(): void
|
public function testSupportsNormalization(): void
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue