Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,10 @@ private function getClassSchemaDefinition(?string $className, ?bool $readableLin
return ['type' => 'string', 'format' => 'binary'];
}

if (is_a($className, \BcMath\Number::class, true)) {
return ['type' => 'string', 'format' => 'string'];
}

$isResourceClass = $this->isResourceClass($className);
if (!$isResourceClass && is_a($className, \BackedEnum::class, true)) {
$enumCases = array_map(static fn (\BackedEnum $enum): string|int => $enum->value, $className::cases());
Expand Down Expand Up @@ -509,6 +513,13 @@ private function getLegacyClassType(?string $className, bool $nullable, ?bool $r
];
}

if (is_a($className, \BcMath\Number::class, true)) {
return [
'type' => 'string',
'format' => 'string',
];
}

$isResourceClass = $this->isResourceClass($className);
if (!$isResourceClass && is_a($className, \BackedEnum::class, true)) {
$enumCases = array_map(static fn (\BackedEnum $enum): string|int => $enum->value, $className::cases());
Expand Down
10 changes: 10 additions & 0 deletions src/Symfony/Bundle/DependencyInjection/ApiPlatformExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
use Symfony\Component\JsonStreamer\JsonStreamWriter;
use Symfony\Component\ObjectMapper\ObjectMapper;
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
use Symfony\Component\Serializer\Normalizer\NumberNormalizer;
use Symfony\Component\Uid\AbstractUid;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Symfony\Component\Yaml\Yaml;
Expand Down Expand Up @@ -267,6 +268,15 @@ private function registerCommonConfiguration(ContainerBuilder $container, array
$loader->load('symfony/uid.php');
}

// symfony/serializer:7.3 added the NumberNormalizer
// symfony/framework-bundle:7.3 added the serializer.normalizer.number` service
// if symfony/serializer >= 7.3 and symfony/framework-bundle < 7.3, the service is registred
if (class_exists(NumberNormalizer::class) && !$container->has('serializer.normalizer.number')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to just bump the minimum required versions to avoid supporting this edge case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we just bumped everything to 7.4 if I'm not mistaken

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mhh we did not but indeed we should bump this to 7.4

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don’t see the bump to 7.4 on the branch 4.2, I was wondering which components should I bump ?

https://github.com/api-platform/core/blob/4.2/src/JsonSchema/composer.json#L31
https://github.com/api-platform/core/blob/4.2/src/Serializer/composer.json#L30
https://github.com/api-platform/core/blob/4.2/src/Symfony/composer.json#L46

And there’s currently no dependency on symfony/framework-bundle for the api-platform/symfony, should I add it ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

anyways we still support 6.4 so this is valid I think I'll merge like this and come back to it if needed later

$numberNormalizerDefinition = new Definition(NumberNormalizer::class);
$numberNormalizerDefinition->addTag('serializer.normalizer', ['built_in' => true, 'priority' => -915]);
$container->setDefinition('serializer.normalizer.number', $numberNormalizerDefinition);
}

$defaultContext = ['hydra_prefix' => $config['serializer']['hydra_prefix']] + ($container->hasParameter('serializer.default_context') ? $container->getParameter('serializer.default_context') : []);

$container->setParameter('api_platform.serializer.default_context', $defaultContext);
Expand Down
43 changes: 43 additions & 0 deletions tests/Fixtures/TestBundle/ApiResource/MathNumber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Tests\Fixtures\TestBundle\ApiResource;

use ApiPlatform\Metadata\ApiProperty;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\Operation;
use ApiPlatform\Metadata\Post;

if (class_exists(\BcMath\Number::class)) {
#[Get(
provider: [self::class, 'provide'],
)]
#[Post]
class MathNumber
{
#[ApiProperty(identifier: true)]
public int $id;

#[ApiProperty(property: 'value')]
public ?\BcMath\Number $value;

public static function provide(Operation $operation, array $uriVariables = [], array $context = []): self
{
$mathNumber = new self();
$mathNumber->id = $uriVariables['id'];
$mathNumber->value = new \BcMath\Number('300.55');

return $mathNumber;
}
}
}
81 changes: 81 additions & 0 deletions tests/Functional/MathNumberTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

declare(strict_types=1);

namespace ApiPlatform\Tests\Functional;

use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\MathNumber;
use ApiPlatform\Tests\SetupClassResourcesTrait;
use PHPUnit\Framework\Attributes\RequiresPhp;
use PHPUnit\Framework\Attributes\RequiresPhpExtension;
use Symfony\Component\Serializer\Normalizer\NumberNormalizer;

#[RequiresPhp('^8.4')]
#[RequiresPhpExtension('bcmath')]
final class MathNumberTest extends ApiTestCase
{
use SetupClassResourcesTrait;

protected static ?bool $alwaysBootKernel = false;

/**
* @return class-string[]
*/
public static function getResources(): array
{
return [MathNumber::class];
}

protected function setUp(): void
{
if (!class_exists(NumberNormalizer::class)) {
$this->markTestSkipped('Requires BcMath/Number and symfony/serialiser >=7.3');
}

parent::setUp();
}

public function testGetMathNumber(): void
{
self::createClient()->request('GET', '/math_numbers/1', ['headers' => ['Accept' => 'application/ld+json']]);

$this->assertResponseIsSuccessful();
$this->assertJsonEquals([
'@context' => '/contexts/MathNumber',
'@id' => '/math_numbers/1',
'@type' => 'MathNumber',
'id' => 1,
'value' => '300.55',
]);
}

public function testPostMathNumber(): void
{
self::createClient()->request('POST', '/math_numbers', [
'headers' => ['Content-Type' => 'application/ld+json'],
'json' => [
'id' => 2,
'value' => '120.23',
],
]);

$this->assertResponseIsSuccessful();
$this->assertJsonEquals([
'@context' => '/contexts/MathNumber',
'@id' => '/math_numbers/2',
'@type' => 'MathNumber',
'id' => 2,
'value' => '120.23',
]);
}
}
Loading