Skip to content

Commit 18018b0

Browse files
committed
fix(laravel): read property type before serialization
fixes #7316
1 parent d1abfc0 commit 18018b0

File tree

6 files changed

+161
-4
lines changed

6 files changed

+161
-4
lines changed

src/Laravel/ApiPlatformProvider.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,10 @@ public function register(): void
262262
return new CachePropertyMetadataFactory(
263263
new SchemaPropertyMetadataFactory(
264264
$app->make(ResourceClassResolverInterface::class),
265-
new PropertyInfoPropertyMetadataFactory(
266-
$app->make(PropertyInfoExtractorInterface::class),
267-
new SerializerPropertyMetadataFactory(
268-
$app->make(SerializerClassMetadataFactory::class),
265+
new SerializerPropertyMetadataFactory(
266+
$app->make(SerializerClassMetadataFactory::class),
267+
new PropertyInfoPropertyMetadataFactory(
268+
$app->make(PropertyInfoExtractorInterface::class),
269269
new AttributePropertyMetadataFactory(
270270
new EloquentAttributePropertyMetadataFactory(
271271
new EloquentPropertyMetadataFactory(

src/Laravel/Tests/JsonLdTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,4 +369,13 @@ public function testResourceWithOptionModel(): void
369369
'@type' => 'Collection',
370370
]);
371371
}
372+
373+
public function testCustomRelation(): void
374+
{
375+
$response = $this->get('/api/home', headers: ['accept' => ['application/ld+json']]);
376+
$home = $response->json();
377+
$this->assertArrayHasKey('order', $home);
378+
$this->assertArrayHasKey('id', $home['order']);
379+
$this->assertArrayHasKey('number', $home['order']);
380+
}
372381
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Workbench\App\ApiResource;
15+
16+
use ApiPlatform\Metadata\ApiProperty;
17+
use ApiPlatform\Metadata\ApiResource;
18+
use ApiPlatform\Metadata\Get;
19+
use ApiPlatform\Metadata\Operation;
20+
use Symfony\Component\Serializer\Annotation\Groups;
21+
use Workbench\App\Models\Order;
22+
use Workbench\Database\Factories\OrderFactory;
23+
24+
#[ApiResource(
25+
operations: [
26+
new Get(
27+
uriTemplate: '/home',
28+
normalizationContext: ['groups' => ['home:read']],
29+
provider: [self::class, 'provide'],
30+
),
31+
],
32+
)]
33+
class Home
34+
{
35+
#[ApiProperty(identifier: true)]
36+
public int $id = 1;
37+
38+
#[Groups(['home:read'])]
39+
public ?Order $order = null;
40+
41+
public static function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
42+
{
43+
$order = OrderFactory::new()->create();
44+
$home = new self();
45+
$home->order = $order;
46+
47+
return $home;
48+
}
49+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Workbench\App\Models;
15+
16+
use ApiPlatform\Metadata\ApiProperty;
17+
use ApiPlatform\Metadata\ApiResource;
18+
use Illuminate\Database\Eloquent\Factories\HasFactory;
19+
use Illuminate\Database\Eloquent\Model;
20+
use Symfony\Component\Serializer\Attribute\Groups;
21+
22+
#[ApiResource()]
23+
#[ApiProperty(property: 'id', serialize: [new Groups(['home:read'])])]
24+
#[ApiProperty(property: 'number', serialize: [new Groups(['home:read'])])]
25+
class Order extends Model
26+
{
27+
use HasFactory;
28+
29+
protected $fillable = [
30+
'number',
31+
];
32+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
namespace Workbench\Database\Factories;
15+
16+
use Illuminate\Database\Eloquent\Factories\Factory;
17+
use Workbench\App\Models\Order;
18+
19+
class OrderFactory extends Factory
20+
{
21+
protected $model = Order::class;
22+
23+
public function definition()
24+
{
25+
return [
26+
'number' => $this->faker->randomNumber(),
27+
];
28+
}
29+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the API Platform project.
5+
*
6+
* (c) Kévin Dunglas <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
declare(strict_types=1);
13+
14+
use Illuminate\Database\Migrations\Migration;
15+
use Illuminate\Database\Schema\Blueprint;
16+
use Illuminate\Support\Facades\Schema;
17+
18+
return new class extends Migration {
19+
/**
20+
* Run the migrations.
21+
*/
22+
public function up(): void
23+
{
24+
Schema::create('orders', function (Blueprint $table): void {
25+
$table->id();
26+
$table->integer('number');
27+
$table->timestamps();
28+
});
29+
}
30+
31+
/**
32+
* Reverse the migrations.
33+
*/
34+
public function down(): void
35+
{
36+
Schema::dropIfExists('orders');
37+
}
38+
};

0 commit comments

Comments
 (0)