Skip to content

Commit f2c9981

Browse files
authored
fix(jsonld): anonymous context hydra_prefix value (#6873)
fixes #6810
1 parent 3a69462 commit f2c9981

File tree

6 files changed

+95
-19
lines changed

6 files changed

+95
-19
lines changed

src/JsonLd/ContextBuilder.php

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,24 @@ public function getResourceContextUri(string $resourceClass, ?int $referenceType
115115
public function getAnonymousResourceContext(object $object, array $context = [], int $referenceType = UrlGeneratorInterface::ABS_PATH): array
116116
{
117117
$outputClass = $this->getObjectClass($object);
118-
$operation = $context['operation'] ?? new Get(shortName: (new \ReflectionClass($outputClass))->getShortName());
118+
$operation = $context['operation'] ?? new Get(
119+
shortName: (new \ReflectionClass($outputClass))->getShortName(),
120+
normalizationContext: [
121+
self::HYDRA_CONTEXT_HAS_PREFIX => $context[self::HYDRA_CONTEXT_HAS_PREFIX] ?? $this->defaultContext[self::HYDRA_CONTEXT_HAS_PREFIX] ?? true,
122+
'groups' => [],
123+
],
124+
denormalizationContext: [
125+
'groups' => [],
126+
]
127+
);
119128
$shortName = $operation->getShortName();
120129

121130
$jsonLdContext = [
122131
'@context' => $this->getResourceContextWithShortname(
123132
$outputClass,
124133
$referenceType,
125-
$shortName
134+
$shortName,
135+
$operation
126136
),
127137
'@type' => $shortName,
128138
];
@@ -184,10 +194,6 @@ private function getResourceContextWithShortname(string $resourceClass, int $ref
184194
}
185195
}
186196

187-
if (false === ($this->defaultContext[self::HYDRA_CONTEXT_HAS_PREFIX] ?? true)) {
188-
return [HYDRA_CONTEXT, $context];
189-
}
190-
191197
return $context;
192198
}
193199
}

src/JsonLd/Serializer/JsonLdContextTrait.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\JsonLd\Serializer;
1515

1616
use ApiPlatform\JsonLd\AnonymousContextBuilderInterface;
17+
use ApiPlatform\JsonLd\ContextBuilder;
1718
use ApiPlatform\JsonLd\ContextBuilderInterface;
1819

1920
/**
@@ -49,13 +50,19 @@ private function addJsonLdContext(ContextBuilderInterface $contextBuilder, strin
4950

5051
private function createJsonLdContext(AnonymousContextBuilderInterface $contextBuilder, $object, array &$context): array
5152
{
53+
$anonymousContext = ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null];
54+
55+
if (isset($context[ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX])) {
56+
$anonymousContext[ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX] = $context[ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX];
57+
}
58+
5259
// We're in a collection, don't add the @context part
5360
if (isset($context['jsonld_has_context'])) {
54-
return $contextBuilder->getAnonymousResourceContext($object, ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null, 'has_context' => true]);
61+
return $contextBuilder->getAnonymousResourceContext($object, ['has_context' => true] + $anonymousContext);
5562
}
5663

5764
$context['jsonld_has_context'] = true;
5865

59-
return $contextBuilder->getAnonymousResourceContext($object, ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null]);
66+
return $contextBuilder->getAnonymousResourceContext($object, $anonymousContext);
6067
}
6168
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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 ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue6810;
15+
16+
use ApiPlatform\Metadata\Get;
17+
use ApiPlatform\Metadata\Operation;
18+
19+
#[Get('/json_ld_context_output', provider: [self::class, 'getData'], output: Output::class, normalizationContext: ['hydra_prefix' => false])]
20+
class JsonLdContextOutput
21+
{
22+
public function __construct(public string $id)
23+
{
24+
}
25+
26+
public static function getData(Operation $operation, array $uriVariables = [], array $context = []): Output
27+
{
28+
return new Output();
29+
}
30+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
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 ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue6810;
15+
16+
class Output
17+
{
18+
public string $foo = 'bar';
19+
}

tests/Functional/JsonLdTest.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
namespace ApiPlatform\Tests\Functional;
1515

1616
use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
17+
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue6810\JsonLdContextOutput;
1718
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue6465\Bar;
1819
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue6465\Foo;
1920
use ApiPlatform\Tests\SetupClassResourcesTrait;
@@ -29,7 +30,7 @@ class JsonLdTest extends ApiTestCase
2930
*/
3031
public static function getResources(): array
3132
{
32-
return [Foo::class, Bar::class];
33+
return [Foo::class, Bar::class, JsonLdContextOutput::class];
3334
}
3435

3536
/**
@@ -50,6 +51,20 @@ public function testIssue6465(): void
5051
$this->assertEquals('Bar two', $res['title']);
5152
}
5253

54+
public function testContextWithOutput(): void
55+
{
56+
$response = self::createClient()->request(
57+
'GET',
58+
'/json_ld_context_output',
59+
);
60+
$res = $response->toArray();
61+
$this->assertEquals($res['@context'], [
62+
'@vocab' => 'http://localhost/docs.jsonld#',
63+
'hydra' => 'http://www.w3.org/ns/hydra/core#',
64+
'foo' => 'Output/foo',
65+
]);
66+
}
67+
5368
protected function setUp(): void
5469
{
5570
self::bootKernel();
@@ -66,8 +81,12 @@ protected function setUp(): void
6681
$classes[] = $manager->getClassMetadata($entityClass);
6782
}
6883

69-
$schemaTool = new SchemaTool($manager);
70-
@$schemaTool->createSchema($classes);
84+
try {
85+
$schemaTool = new SchemaTool($manager);
86+
@$schemaTool->createSchema($classes);
87+
} catch (\Exception $e) {
88+
return;
89+
}
7190

7291
$foo = new Foo();
7392
$foo->title = 'Foo';

tests/JsonLd/ContextBuilderTest.php

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
use Prophecy\Prophecy\ObjectProphecy;
3636
use Symfony\Component\PropertyInfo\Type;
3737

38-
use const ApiPlatform\JsonLd\HYDRA_CONTEXT;
39-
4038
/**
4139
* @author Markus Mächler <[email protected]>
4240
*/
@@ -293,12 +291,9 @@ public function testResourceContextWithoutHydraPrefix(): void
293291
$contextBuilder = new ContextBuilder($this->resourceNameCollectionFactoryProphecy->reveal(), $this->resourceMetadataCollectionFactoryProphecy->reveal(), $this->propertyNameCollectionFactoryProphecy->reveal(), $this->propertyMetadataFactoryProphecy->reveal(), $this->urlGeneratorProphecy->reveal(), null, null, [ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX => false]);
294292

295293
$expected = [
296-
HYDRA_CONTEXT,
297-
[
298-
'@vocab' => '#',
299-
'hydra' => 'http://www.w3.org/ns/hydra/core#',
300-
'dummyPropertyA' => 'DummyEntity/dummyPropertyA',
301-
],
294+
'@vocab' => '#',
295+
'hydra' => 'http://www.w3.org/ns/hydra/core#',
296+
'dummyPropertyA' => 'DummyEntity/dummyPropertyA',
302297
];
303298

304299
$this->assertEquals($expected, $contextBuilder->getResourceContext($this->entityClass));

0 commit comments

Comments
 (0)