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
9 changes: 9 additions & 0 deletions features/jsonld/non_resource.feature
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ Feature: JSON-LD non-resource handling
}
}
"""
And the JSON node "notAResource.@id" should not exist

Scenario: Get a resource containing a raw object with selected properties
Given there are 1 dummy objects with relatedDummy and its thirdLevel
Expand Down Expand Up @@ -123,3 +124,11 @@ Feature: JSON-LD non-resource handling
"id": 1
}
"""

@php8
Scenario: Get a generated id
When I send a "GET" request to "/genids/1"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
And the JSON node "totalPrice.@id" should exist
1 change: 1 addition & 0 deletions src/Hydra/Serializer/CollectionNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ public function normalize($object, $format = null, array $context = []): array

$resourceClass = $this->resourceClassResolver->getResourceClass($object, $context['resource_class']);
$context = $this->initContext($resourceClass, $context);
$context['api_collection_sub_level'] = true;
$data = $this->addJsonLdContext($this->contextBuilder, $resourceClass, $context);

if ($this->iriConverter instanceof LegacyIriConverterInterface) {
Expand Down
8 changes: 8 additions & 0 deletions src/JsonLd/ContextBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,14 @@ public function getAnonymousResourceContext($object, array $context = [], int $r
}
}

if ($this->iriConverter && isset($context['gen_id']) && true === $context['gen_id']) {
$jsonLdContext['@id'] = $this->iriConverter->getIriFromResource($object);
}

if (false === ($context['iri'] ?? null)) {
trigger_deprecation('api-platform/core', '2.7', 'An anonymous resource will use a Skolem IRI in API Platform 3.0. Use #[ApiProperty(genId: false)] to keep this behavior in 3.0.');
}

if ($context['has_context'] ?? false) {
unset($jsonLdContext['@context']);
}
Expand Down
6 changes: 6 additions & 0 deletions src/JsonLd/Serializer/ItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ public function normalize($object, $format = null, array $context = [])
$context = $this->initContext($resourceClass, $context);
$metadata = $this->addJsonLdContext($this->contextBuilder, $resourceClass, $context);
} elseif ($this->contextBuilder instanceof AnonymousContextBuilderInterface) {
if ($context['api_collection_sub_level'] ?? false) {
unset($context['api_collection_sub_level']);
$context['output']['genid'] = true;
$context['output']['iri'] = null;
}

// We should improve what's behind the context creation, its probably more complicated then it should
$metadata = $this->createJsonLdContext($this->contextBuilder, $object, $context);
}
Expand Down
2 changes: 1 addition & 1 deletion src/JsonLd/Serializer/JsonLdContextTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private function createJsonLdContext(AnonymousContextBuilderInterface $contextBu
{
// We're in a collection, don't add the @context part
if (isset($context['jsonld_has_context'])) {
return $contextBuilder->getAnonymousResourceContext($object, ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null, 'has_context' => true]);
return $contextBuilder->getAnonymousResourceContext($object, ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null, 'has_context' => true, 'iri' => false]);
}

$context['jsonld_has_context'] = true;
Expand Down
19 changes: 19 additions & 0 deletions src/Metadata/ApiProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ final class ApiProperty

private $schema;
private $initializable;
private $genId;

/**
* @var string[]
Expand Down Expand Up @@ -146,6 +147,7 @@ public function __construct(
?array $builtinTypes = null,
?array $schema = null,
?bool $initializable = null,
?bool $genId = null,

$iris = null,

Expand Down Expand Up @@ -175,6 +177,7 @@ public function __construct(
$this->builtinTypes = $builtinTypes;
$this->schema = $schema;
$this->initializable = $initializable;
$this->genId = $genId;
$this->iris = $iris;
$this->extraProperties = $extraProperties;
}
Expand Down Expand Up @@ -507,4 +510,20 @@ public function withIris($iris): self

return $metadata;
}

/**
* Whether to generate a skolem iri on anonymous resources.
*/
public function getGenId()
{
return $this->genId;
}

public function withGenId(bool $genId): self
{
$metadata = clone $this;
$metadata->genId = $genId;

return $metadata;
}
}
1 change: 1 addition & 0 deletions src/Metadata/Extractor/XmlPropertyExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ protected function extractPath(string $path)
'initializable' => $this->phpize($property, 'initializable', 'bool'),
'extraProperties' => $this->buildExtraProperties($property, 'extraProperties'),
'iris' => $this->buildArrayValue($property, 'iri'),
'genId' => $this->phpize($property, 'genId', 'bool'),
];
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Metadata/Extractor/YamlPropertyExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ private function buildProperties(array $resourcesYaml): void
'example' => $propertyValues['example'] ?? null,
'builtinTypes' => $this->buildAttribute($propertyValues, 'builtinTypes'),
'schema' => $this->buildAttribute($propertyValues, 'schema'),
'genId' => $this->phpize($propertyValues, 'genId', 'bool'),
];
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Metadata/Extractor/schema/properties.xsd
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
<xsd:attribute name="security" type="xsd:string"/>
<xsd:attribute name="securityPostDenormalize" type="xsd:string"/>
<xsd:attribute name="initializable" type="xsd:boolean"/>
<xsd:attribute name="genId" type="xsd:boolean"/>
</xsd:complexType>

<xsd:complexType name="types">
Expand Down
6 changes: 2 additions & 4 deletions src/Serializer/AbstractItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -831,11 +831,9 @@ protected function getAttributeValue($object, $attribute, $format = null, array
unset($childContext['iri'], $childContext['uri_variables']);

if ($propertyMetadata instanceof PropertyMetadata) {
$childContext['output']['iri'] = $propertyMetadata->getIri();
$childContext['output']['iri'] = $propertyMetadata->getIri() ?? false;
} else {
if (null !== ($propertyIris = $propertyMetadata->getIris())) {
$childContext['output']['iri'] = 1 === \count($propertyIris) ? $propertyIris[0] : $propertyIris;
}
$childContext['output']['gen_id'] = $propertyMetadata->getGenId() ?? false;
}

return $this->serializer->normalize($attributeValue, $format, $childContext);
Expand Down
35 changes: 35 additions & 0 deletions tests/Fixtures/TestBundle/Model/GenId.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* 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\Model;

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

#[Get('/genids/{id}', provider: [GenId::class, 'getData'])]
class GenId
{
#[ApiProperty(genId: true)]
public MonetaryAmount $totalPrice;

public function __construct(public int $id)
{
$this->totalPrice = new MonetaryAmount(1000.01);
}

public static function getData(Operation $operation, array $uriVariables = [], array $context = []): self
{
return new self($uriVariables['id']);
}
}
21 changes: 21 additions & 0 deletions tests/Fixtures/TestBundle/Model/MonetaryAmount.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

/*
* This file is part of the API Platform project.
*
* (c) Kévin Dunglas <dunglas@gmail.com>
*
* 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\Model;

class MonetaryAmount
{
public function __construct(public float $value = 0.0, public string $currency = 'EUR', public float $minValue = 0.0)
{
}
}
1 change: 1 addition & 0 deletions tests/Hydra/Serializer/CollectionNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ private function normalizePaginator($partial = false)
'jsonld_has_context' => true,
'api_sub_level' => true,
'resource_class' => 'Foo',
'api_collection_sub_level' => true,
])->willReturn(['name' => 'Kévin', 'friend' => 'Smail']);

$normalizer = new CollectionNormalizer($contextBuilder->reveal(), $resourceClassResolverProphecy->reveal(), $iriConvert->reveal());
Expand Down
1 change: 1 addition & 0 deletions tests/Metadata/Extractor/Adapter/XmlPropertyAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ final class XmlPropertyAdapter implements PropertyAdapterInterface
'securityPostDenormalize',
'initializable',
'iris',
'genId',
];

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ final class PropertyMetadataCompatibilityTest extends TestCase
'custom_property' => 'Lorem ipsum dolor sit amet',
],
'iris' => ['https://schema.org/totalPrice'],
'genId' => true,
];

/**
Expand Down