Skip to content

Commit

Permalink
Use context prefix for json-ld schema (see #1457)
Browse files Browse the repository at this point in the history
Description
-----------

As discussed in #1236 (comment)

Commits
-------

fa39c59 Use context prefix for json-ld schema
a43de85 Remove contao:pageId
498fd07 Fix the merge conflict
46c8f34 Merge branch '4.9' into fix/google-schema-validation
  • Loading branch information
ausi committed Mar 2, 2020
1 parent 0059dd4 commit 19ff24f
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 16 deletions.
12 changes: 6 additions & 6 deletions core-bundle/src/Resources/contao/pages/PageRegular.php
Original file line number Diff line number Diff line change
Expand Up @@ -825,12 +825,12 @@ protected function createFooterScripts($objLayout, $objPage = null)

$meta = array
(
'@context' => 'https://schema.contao.org/',
'@type' => 'RegularPage',
'noSearch' => $noSearch,
'protected' => (bool) $objPage->protected,
'groups' => array_map('intval', array_filter((array) $objPage->groups)),
'fePreview' => System::getContainer()->get('contao.security.token_checker')->isPreviewMode()
'@context' => array('contao' => 'https://schema.contao.org/'),
'@type' => 'contao:RegularPage',
'contao:noSearch' => $noSearch,
'contao:protected' => (bool) $objPage->protected,
'contao:groups' => array_map('intval', array_filter((array) $objPage->groups)),
'contao:fePreview' => System::getContainer()->get('contao.security.token_checker')->isPreviewMode()
);

$strScripts .= '<script type="application/ld+json">' . json_encode($meta) . '</script>';
Expand Down
80 changes: 75 additions & 5 deletions core-bundle/src/Search/Document.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,17 +142,87 @@ private function filterJsonLd(array $jsonLds, string $context = '', string $type
$matching = [];

foreach ($jsonLds as $data) {
if ('' !== $context && (!isset($data['@context']) || $data['@context'] !== $context)) {
continue;
}
$data = $this->expandJsonLdContexts($data);

if ('' !== $type && (!isset($data['@type']) || $data['@type'] !== $type)) {
if ('' !== $type && (!isset($data['@type']) || $data['@type'] !== $context.$type)) {
continue;
}

$matching[] = $data;
if (\count($filtered = $this->filterJsonLdContexts($data, [$context]))) {
$matching[] = $filtered;
}
}

return $matching;
}

private function expandJsonLdContexts(array $data): array
{
if (empty($data['@context'])) {
return $data;
}

if (\is_string($data['@context'])) {
foreach ($data as $key => $value) {
if ('@type' === $key) {
$data[$key] = $data['@context'].$value;
continue;
}

if ('@' !== $key[0]) {
unset($data[$key]);
$data[$data['@context'].$key] = $value;
}
}

return $data;
}

if (\is_array($data['@context'])) {
foreach ($data['@context'] as $prefix => $context) {
if (isset($data['@type']) && 0 === strncmp($data['@type'], $prefix.':', \strlen($prefix) + 1)) {
$data['@type'] = substr($data['@type'], \strlen($prefix) + 1);
}

foreach ($data as $key => $value) {
if (0 === strncmp($prefix.':', $key, \strlen($prefix) + 1)) {
unset($data[$key]);
$data[$context.substr($key, \strlen($prefix) + 1)] = $value;
}
}
}

return $data;
}

throw new \RuntimeException('Unable to expand JSON-LD data');
}

private function filterJsonLdContexts(array $data, array $contexts): array
{
$newData = [];
$found = false;

foreach ($data as $key => $value) {
foreach ($contexts as $context) {
if ('@type' === $key) {
$newData[$key] = $value;

if (0 === strncmp($value, $context, \strlen($context))) {
$newData[$key] = substr($value, \strlen($context));
$found = true;
break;
}
}

if (0 === strncmp($context, $key, \strlen($context))) {
$newData[substr($key, \strlen($context))] = $value;
$found = true;
break;
}
}
}

return $found ? $newData : [];
}
}
26 changes: 21 additions & 5 deletions core-bundle/tests/Search/DocumentTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function testExtractsTheJsdonLdScript(string $body, array $expectedJsonLd
$this->assertSame('https://example.com', (string) $document->getUri());
$this->assertSame(200, $document->getStatusCode());
$this->assertSame(['content-type' => ['text/html']], $document->getHeaders());
$this->assertSame($expectedJsonLds, $document->extractJsonLdScripts());
$this->assertSame($expectedJsonLds, $document->extractJsonLdScripts('https://contao.org/'));
}

public function documentProvider(): \Generator
Expand All @@ -64,7 +64,26 @@ public function documentProvider(): \Generator
'<html><body><script type="application/ld+json">{"@context":"https:\/\/contao.org\/","@type":"PageMetaData","foobar":true}</script></body></html>',
[
[
'@context' => 'https://contao.org/',
'@type' => 'PageMetaData',
'foobar' => true,
],
],
];

yield 'Test with one valid json ld element without context' => [
'<html><body><script type="application/ld+json">{"@type":"https:\/\/contao.org\/PageMetaData","https:\/\/contao.org\/foobar":true}</script></body></html>',
[
[
'@type' => 'PageMetaData',
'foobar' => true,
],
],
];

yield 'Test with one valid json ld element with context prefix' => [
'<html><body><script type="application/ld+json">{"@context":{"contao":"https:\/\/contao.org\/"},"@type":"contao:PageMetaData","contao:foobar":true}</script></body></html>',
[
[
'@type' => 'PageMetaData',
'foobar' => true,
],
Expand All @@ -75,12 +94,10 @@ public function documentProvider(): \Generator
'<html><body><script type="application/ld+json">{"@context":"https:\/\/contao.org\/","@type":"PageMetaData","foobar":true}</script><script type="application/ld+json">{"@context":"https:\/\/contao.org\/","@type":"PageMetaData","foobar":false}</script></body></html>',
[
[
'@context' => 'https://contao.org/',
'@type' => 'PageMetaData',
'foobar' => true,
],
[
'@context' => 'https://contao.org/',
'@type' => 'PageMetaData',
'foobar' => false,
],
Expand All @@ -91,7 +108,6 @@ public function documentProvider(): \Generator
'<html><body><script type="application/ld+json">{"@context":"https:\/\/contao.org\/","@type":"PageMetaData","foobar":true}</script><script type="application/ld+json">{"@context":"https:\/\/contao.org\/", ...</script></body></html>',
[
[
'@context' => 'https://contao.org/',
'@type' => 'PageMetaData',
'foobar' => true,
],
Expand Down

0 comments on commit 19ff24f

Please sign in to comment.