Skip to content

Commit

Permalink
fix(jsonld): anonymous context hydra_prefix value
Browse files Browse the repository at this point in the history
  • Loading branch information
soyuka committed Dec 16, 2024
1 parent f15a338 commit d4d0d6b
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 19 deletions.
18 changes: 12 additions & 6 deletions src/JsonLd/ContextBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,14 +115,24 @@ public function getResourceContextUri(string $resourceClass, ?int $referenceType
public function getAnonymousResourceContext(object $object, array $context = [], int $referenceType = UrlGeneratorInterface::ABS_PATH): array
{
$outputClass = $this->getObjectClass($object);
$operation = $context['operation'] ?? new Get(shortName: (new \ReflectionClass($outputClass))->getShortName());
$operation = $context['operation'] ?? new Get(
shortName: (new \ReflectionClass($outputClass))->getShortName(),
normalizationContext: [
self::HYDRA_CONTEXT_HAS_PREFIX => $context[self::HYDRA_CONTEXT_HAS_PREFIX] ?? $this->defaultContext[self::HYDRA_CONTEXT_HAS_PREFIX] ?? true,
'groups' => [],
],
denormalizationContext: [
'groups' => [],
]
);
$shortName = $operation->getShortName();

$jsonLdContext = [
'@context' => $this->getResourceContextWithShortname(
$outputClass,
$referenceType,
$shortName
$shortName,
$operation
),
'@type' => $shortName,
];
Expand Down Expand Up @@ -184,10 +194,6 @@ private function getResourceContextWithShortname(string $resourceClass, int $ref
}
}

if (false === ($this->defaultContext[self::HYDRA_CONTEXT_HAS_PREFIX] ?? true)) {
return [HYDRA_CONTEXT, $context];
}

return $context;
}
}
11 changes: 9 additions & 2 deletions src/JsonLd/Serializer/JsonLdContextTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace ApiPlatform\JsonLd\Serializer;

use ApiPlatform\JsonLd\AnonymousContextBuilderInterface;
use ApiPlatform\JsonLd\ContextBuilder;
use ApiPlatform\JsonLd\ContextBuilderInterface;

/**
Expand Down Expand Up @@ -49,13 +50,19 @@ private function addJsonLdContext(ContextBuilderInterface $contextBuilder, strin

private function createJsonLdContext(AnonymousContextBuilderInterface $contextBuilder, $object, array &$context): array
{
$anonymousContext = ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null];

if (isset($context[ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX])) {
$anonymousContext[ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX] = $context[ContextBuilder::HYDRA_CONTEXT_HAS_PREFIX];
}

// 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, ['has_context' => true] + $anonymousContext);
}

$context['jsonld_has_context'] = true;

return $contextBuilder->getAnonymousResourceContext($object, ($context['output'] ?? []) + ['api_resource' => $context['api_resource'] ?? null]);
return $contextBuilder->getAnonymousResourceContext($object, $anonymousContext);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?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\Issue6810;

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

#[Get('/json_ld_context_output', provider: [self::class, 'getData'], output: Output::class, normalizationContext: ['hydra_prefix' => false])]
class JsonLdContextOutput
{
public function __construct(public string $id)
{
}

public static function getData(Operation $operation, array $uriVariables = [], array $context = []): Output
{
return new Output();
}
}
19 changes: 19 additions & 0 deletions tests/Fixtures/TestBundle/ApiResource/Issue6810/Output.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?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\Issue6810;

class Output
{
public string $foo = 'bar';
}
25 changes: 22 additions & 3 deletions tests/Functional/JsonLdTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
namespace ApiPlatform\Tests\Functional;

use ApiPlatform\Symfony\Bundle\Test\ApiTestCase;
use ApiPlatform\Tests\Fixtures\TestBundle\ApiResource\Issue6810\JsonLdContextOutput;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue6465\Bar;
use ApiPlatform\Tests\Fixtures\TestBundle\Entity\Issue6465\Foo;
use ApiPlatform\Tests\SetupClassResourcesTrait;
Expand All @@ -29,7 +30,7 @@ class JsonLdTest extends ApiTestCase
*/
public static function getResources(): array
{
return [Foo::class, Bar::class];
return [Foo::class, Bar::class, JsonLdContextOutput::class];
}

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

public function testContextWithOutput(): void
{
$response = self::createClient()->request(
'GET',
'/json_ld_context_output',
);
$res = $response->toArray();
$this->assertEquals($res['@context'], [
'@vocab' => 'http://localhost/docs.jsonld#',
'hydra' => 'http://www.w3.org/ns/hydra/core#',
'foo' => 'Output/foo',
]);
}

protected function setUp(): void
{
self::bootKernel();
Expand All @@ -66,8 +81,12 @@ protected function setUp(): void
$classes[] = $manager->getClassMetadata($entityClass);
}

$schemaTool = new SchemaTool($manager);
@$schemaTool->createSchema($classes);
try {
$schemaTool = new SchemaTool($manager);
@$schemaTool->createSchema($classes);
} catch (\Exception $e) {
return;
}

$foo = new Foo();
$foo->title = 'Foo';
Expand Down
11 changes: 3 additions & 8 deletions tests/JsonLd/ContextBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
use Prophecy\Prophecy\ObjectProphecy;
use Symfony\Component\PropertyInfo\Type;

use const ApiPlatform\JsonLd\HYDRA_CONTEXT;

/**
* @author Markus Mächler <[email protected]>
*/
Expand Down Expand Up @@ -293,12 +291,9 @@ public function testResourceContextWithoutHydraPrefix(): void
$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]);

$expected = [
HYDRA_CONTEXT,
[
'@vocab' => '#',
'hydra' => 'http://www.w3.org/ns/hydra/core#',
'dummyPropertyA' => 'DummyEntity/dummyPropertyA',
],
'@vocab' => '#',
'hydra' => 'http://www.w3.org/ns/hydra/core#',
'dummyPropertyA' => 'DummyEntity/dummyPropertyA',
];

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

0 comments on commit d4d0d6b

Please sign in to comment.