Skip to content
Merged

3.0 #5057

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
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ jobs:
- name: Run commitlint
run: |
commit=$(gh api \
-H "Accept: application/vnd.github+json" \
/repos/${{ github.repository }}/pulls/${{github.event.number}}/commits \
| jq -r '.[0].commit.message')
| jq -r '.[0].commit.message' \
| head -n 1)
# we can't use npx see https://github.com/conventional-changelog/commitlint/issues/613
echo '{}' > package.json
npm install --no-fund --no-audit @commitlint/config-conventional @commitlint/cli
Expand Down
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 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 not exist
2 changes: 2 additions & 0 deletions src/GraphQl/Serializer/ItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ public function supportsNormalization(mixed $data, string $format = null, array
/**
* {@inheritdoc}
*
* @param array<string, mixed> $context
*
* @throws UnexpectedValueException
*/
public function normalize(mixed $object, string $format = null, array $context = []): array|string|int|float|bool|\ArrayObject|null
Expand Down
1 change: 1 addition & 0 deletions src/Hydra/Serializer/CollectionNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public function normalize(mixed $object, string $format = null, array $context =
{
$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);
$data['@id'] = $this->iriConverter->getIriFromResource($resourceClass, UrlGeneratorInterface::ABS_PATH, $context['operation'] ?? null, $context);
$data['@type'] = 'hydra:Collection';
Expand Down
11 changes: 4 additions & 7 deletions src/JsonLd/ContextBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

use ApiPlatform\Api\IriConverterInterface;
use ApiPlatform\Api\UrlGeneratorInterface;
use ApiPlatform\Exception\RuntimeException;
use ApiPlatform\Metadata\Get;
use ApiPlatform\Metadata\HttpOperation;
use ApiPlatform\Metadata\Property\Factory\PropertyMetadataFactoryInterface;
Expand Down Expand Up @@ -123,12 +122,10 @@ public function getAnonymousResourceContext(object $object, array $context = [],
'@type' => $shortName,
];

if (!isset($context['iri']) || false !== $context['iri']) {
if (!isset($context['iri']) && !$this->iriConverter) {
throw new RuntimeException('Can not guess an anonymous resource IRI without IRI Converter.');
}

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

if ($context['has_context'] ?? false) {
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 @@ -79,6 +79,12 @@ public function normalize(mixed $object, string $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
4 changes: 2 additions & 2 deletions src/JsonLd/Serializer/JsonLdContextTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ 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, ['api_resource' => $context['api_resource'] ?? null, 'has_context' => true]);
return $contextBuilder->getAnonymousResourceContext($object, ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null, 'has_context' => true]);
}

$context['jsonld_has_context'] = true;

return $contextBuilder->getAnonymousResourceContext($object, ['api_resource' => $context['api_resource'] ?? null]);
return $contextBuilder->getAnonymousResourceContext($object, ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null]);
}
}
17 changes: 17 additions & 0 deletions src/Metadata/ApiProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ public function __construct(
private ?array $schema = null,
private ?bool $initializable = null,
private $iris = null,
private ?bool $genId = null,
private array $extraProperties = []
) {
if (\is_string($types)) {
Expand Down Expand Up @@ -403,4 +404,20 @@ public function withIris(string|array $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): void
'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
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?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\Metadata\Resource\Factory;

use ApiPlatform\Metadata\Resource\ResourceMetadataCollection;

/**
* @author Antoine Bluchet <soyuka@gmail.com>
*/
final class AlternateUriResourceMetadataCollectionFactory implements ResourceMetadataCollectionFactoryInterface
{
public function __construct(private readonly ?ResourceMetadataCollectionFactoryInterface $decorated = null)
{
}

/**
* {@inheritdoc}
*/
public function create(string $resourceClass): ResourceMetadataCollection
{
$resourceMetadataCollection = new ResourceMetadataCollection($resourceClass);
if ($this->decorated) {
$resourceMetadataCollection = $this->decorated->create($resourceClass);
}

foreach ($resourceMetadataCollection as $i => $resource) {
if (0 === $i) {
continue;
}

$resource = $resource->withExtraProperties($resource->getExtraProperties() + ['is_alternate_resource_metadata' => true]);
$operations = $resource->getOperations();
foreach ($operations as $key => $operation) {
$operations->add($key, $operation->withExtraProperties($operation->getExtraProperties() + ['is_alternate_resource_metadata' => true]));
}

$resourceMetadataCollection[$i] = $resource->withOperations($operations);
}

return $resourceMetadataCollection;
}
}
5 changes: 1 addition & 4 deletions src/Serializer/AbstractItemNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -592,10 +592,7 @@ protected function getAttributeValue(object $object, string $attribute, string $
if ($type && $type->getClassName()) {
$childContext = $this->createChildContext($context, $attribute, $format);
unset($childContext['iri'], $childContext['uri_variables']);

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

return $this->serializer->normalize($attributeValue, $format, $childContext);
}
Expand Down
6 changes: 3 additions & 3 deletions src/Symfony/Bundle/Command/DebugResourceCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if (0 === \count($resourceCollection)) {
$output->writeln(sprintf('<error>No resources found for class %s</error>', $resourceClass));

return Command::INVALID;
return \defined(Command::class.'::INVALID') ? Command::INVALID : 2;
}

$shortName = (false !== $pos = strrpos($resourceClass, '\\')) ? substr($resourceClass, $pos + 1) : $resourceClass;
Expand Down Expand Up @@ -103,13 +103,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$this->dumper->dump($this->cloner->cloneVar($selectedResource));
$output->writeln('Successfully dumped the selected resource');

return Command::SUCCESS;
return \defined(Command::class.'::SUCCESS') ? Command::SUCCESS : 0;
}

$this->dumper->dump($this->cloner->cloneVar($resourceCollection->getOperation($answerOperation)));
$output->writeln('Successfully dumped the selected operation');

return Command::SUCCESS;
return \defined(Command::class.'::SUCCESS') ? Command::SUCCESS : 0;
}

public static function getDefaultName(): string
Expand Down
2 changes: 1 addition & 1 deletion src/Symfony/Bundle/Command/GraphQlExportCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$output->writeln($schemaExport);
}

return 0;
return \defined(Command::class.'::SUCCESS') ? Command::SUCCESS : 0;
}

public static function getDefaultName(): string
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/Command/OpenApiCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int
$filesystem->dumpFile($filename, $content);
$io->success(sprintf('Data written to %s.', $filename));

return 0;
return \defined(Command::class.'::SUCCESS') ? Command::SUCCESS : 0;
}

$output->writeln($content);

return 0;
return \defined(Command::class.'::SUCCESS') ? Command::SUCCESS : 0;
}

public static function getDefaultName(): string
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/Resources/config/doctrine_mongodb_odm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@
<service id="api_platform.doctrine_mongodb.odm.state.remove_processor" class="ApiPlatform\Doctrine\Common\State\RemoveProcessor">
<argument type="service" id="doctrine_mongodb" />

<tag name="api_platform.state_processor" priority="-100" key="ApiPlatform\Doctrine\Common\State\RemoveProcessor" />
<tag name="api_platform.state_processor" priority="-100" key="api_platform.doctrine_mongodb.odm.state.remove_processor" />
<tag name="api_platform.state_processor" priority="-100" key="ApiPlatform\Doctrine\Common\State\RemoveProcessor" />
</service>
<service id="ApiPlatform\Doctrine\Common\State\RemoveProcessor" alias="api_platform.doctrine_mongodb.odm.state.remove_processor" />

<service id="api_platform.doctrine_mongodb.odm.state.persist_processor" class="ApiPlatform\Doctrine\Common\State\PersistProcessor">
<argument type="service" id="doctrine_mongodb" />

<tag name="api_platform.state_processor" priority="-100" key="ApiPlatform\Doctrine\Common\State\PersistProcessor" />
<tag name="api_platform.state_processor" priority="-100" key="api_platform.doctrine_mongodb.odm.state.persist_processor" />
<tag name="api_platform.state_processor" priority="-100" key="ApiPlatform\Doctrine\Common\State\PersistProcessor" />
</service>
<service id="ApiPlatform\Doctrine\Common\State\PersistProcessor" alias="api_platform.doctrine_mongodb.odm.state.persist_processor" />

Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Bundle/Resources/config/doctrine_orm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@
<service id="api_platform.doctrine.orm.state.remove_processor" class="ApiPlatform\Doctrine\Common\State\RemoveProcessor">
<argument type="service" id="doctrine" />

<tag name="api_platform.state_processor" priority="-100" key="ApiPlatform\Doctrine\Common\State\RemoveProcessor" />
<tag name="api_platform.state_processor" priority="-100" key="api_platform.doctrine.orm.state.remove_processor" />
<tag name="api_platform.state_processor" priority="-100" key="ApiPlatform\Doctrine\Common\State\RemoveProcessor" />
</service>
<service id="ApiPlatform\Doctrine\Common\State\RemoveProcessor" alias="api_platform.doctrine.orm.state.remove_processor" />

<service id="api_platform.doctrine.orm.state.persist_processor" class="ApiPlatform\Doctrine\Common\State\PersistProcessor">
<argument type="service" id="doctrine" />

<tag name="api_platform.state_processor" priority="-100" key="ApiPlatform\Doctrine\Common\State\PersistProcessor" />
<tag name="api_platform.state_processor" priority="-100" key="api_platform.doctrine.orm.state.persist_processor" />
<tag name="api_platform.state_processor" priority="-100" key="ApiPlatform\Doctrine\Common\State\PersistProcessor" />
</service>
<service id="ApiPlatform\Doctrine\Common\State\PersistProcessor" alias="api_platform.doctrine.orm.state.persist_processor" />

Expand Down
4 changes: 4 additions & 0 deletions src/Symfony/Bundle/Resources/config/metadata/resource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@
<argument type="service" id="api_platform.metadata.resource.metadata_collection_factory.filters.inner" />
</service>

<service id="api_platform.metadata.resource.metadata_collection_factory.alternate_uri" class="ApiPlatform\Metadata\Resource\Factory\AlternateUriResourceMetadataCollectionFactory" decorates="api_platform.metadata.resource.metadata_collection_factory" decoration-priority="200" public="false">
<argument type="service" id="api_platform.metadata.resource.metadata_collection_factory.alternate_uri.inner" />
</service>

<service id="api_platform.metadata.resource.metadata_collection_factory.cached" class="ApiPlatform\Metadata\Resource\Factory\CachedResourceMetadataCollectionFactory" decorates="api_platform.metadata.resource.metadata_collection_factory" decoration-priority="-10" public="false">
<argument type="service" id="api_platform.cache.metadata.resource_collection" />
<argument type="service" id="api_platform.metadata.resource.metadata_collection_factory.cached.inner" />
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
var isValid, qp, arr;

if (/code|token|error/.test(window.location.hash)) {
qp = window.location.hash.substring(1);
qp = window.location.hash.substring(1).replace('?', '&');
} else {
qp = location.search.substring(1);
}
Expand All @@ -38,7 +38,7 @@
authId: oauth2.auth.name,
source: "auth",
level: "warning",
message: "Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"
message: "Authorization may be unsafe, passed state was changed in server. The passed state wasn't returned from auth server."
});
}

Expand All @@ -58,7 +58,7 @@
authId: oauth2.auth.name,
source: "auth",
level: "error",
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server"
message: oauthErrorMsg || "[Authorization failed]: no accessCode received from the server."
});
}
} else {
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Loading