Skip to content

Commit

Permalink
Merge pull request #56 from Sarke/jsonld-recursion
Browse files Browse the repository at this point in the history
  • Loading branch information
rvanlaak committed May 26, 2020
2 parents ef0089c + d4c8692 commit bbe4562
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 4 deletions.
26 changes: 22 additions & 4 deletions src/Micrometa/Infrastructure/Parser/JsonLD.php
Expand Up @@ -83,6 +83,12 @@ class JsonLD extends AbstractParser
* @var CachingContextLoader
*/
protected $contextLoader;
/**
* Array for keeping track of the hierarchy of objects, to prevent recursion
*
* @var NodeInterface[]
*/
protected $chain = [];

/**
* JSON-LD parser constructor
Expand Down Expand Up @@ -183,14 +189,26 @@ protected function parseRootNode($jsonLDRoot)
*
* @param NodeInterface $node Node
*
* @return \stdClass Item
* @return \stdClass|string Item or string ID
*/
protected function parseNode(NodeInterface $node)
{
$nodeId = $node->getId() ?: null;

// if ID is in the current chain, just return the ID reference
if (in_array($node, $this->chain, true)) {
return $nodeId;
}

// add node to chain, parse node tree, remove node from chain
$this->chain[] = $node;
$properties = $this->parseNodeProperties($node);
array_pop($this->chain);

return (object)[
'type' => $this->parseNodeType($node),
'id' => $node->getId() ?: null,
'properties' => $this->parseNodeProperties($node),
'id' => $nodeId,
'properties' => $properties,
];
}

Expand All @@ -206,7 +224,7 @@ protected function parseNodeType(NodeInterface $node): array
if ($node->isBlankNode()) {
return [];
}

/** @var NodeInterface|NodeInterface[] $itemTypes */
$itemTypes = $node->getType();
$itemTypes = is_array($itemTypes) ? $itemTypes : [$itemTypes];
Expand Down
18 changes: 18 additions & 0 deletions src/Micrometa/Tests/Fixture/json-ld/jsonld-recursion.html
@@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="UTF-8">
<title>JSON-LD test document</title>
<script type="application/ld+json">
{
"@context": "http://schema.org/",
"@type": "Website",
"@id": "https://www.example.com/",
"url": "https://www.example.com/"
};
</script>
</head>
<body>
<h1>JSON-LD test document</h1>
</body>
</html>
16 changes: 16 additions & 0 deletions src/Micrometa/Tests/Infrastructure/ParserTest.php
Expand Up @@ -204,4 +204,20 @@ public function testLinkTypeParser()
$this->assertEquals(LinkType::FORMAT, $items[0]->getFormat());
$this->assertEquals([new Iri(LinkType::HTML_PROFILE_URI, 'icon')], $items[0]->getType());
}

/**
* Test the JSON-LD parser with a valid recursion
*/
public function testRecursionInJsonLDParser()
{
$items = $this->parseItems('json-ld/jsonld-recursion.html', JsonLD::class);
$this->assertTrue(is_array($items));
$this->assertInstanceOf(Item::class, $items[0]);

$url = $items[0]->getProperty('url');
$this->assertTrue(is_array($url));
$this->assertEquals(1, count($url));
$this->assertInstanceOf(StringValue::class, $url[0]);
$this->assertEquals('https://www.example.com/', strval($url[0]));
}
}

0 comments on commit bbe4562

Please sign in to comment.