Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
21 changes: 10 additions & 11 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ name: Continuous integration

on:
push:
branches: [ master ]
branches:
- "**"
pull_request:
branches: [ master ]
branches:
- master
- php8

jobs:
ci:
Expand All @@ -16,15 +19,11 @@ jobs:
strategy:
matrix:
php-version:
- "5.3"
- "5.4"
- "5.5"
- "5.6"
- "7.0"
- "7.1"
- "7.2"
- "7.3"
- "7.4"
- "8.1"
- "8.2"
- "8.3"
- "8.4"
- "8.5"

steps:
- name: "Install PHP"
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/vendor
/composer.lock
/.phpunit.result.cache
/phpunit.xml
/earl-report.jsonld
35 changes: 27 additions & 8 deletions FileGetContentsLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,36 @@ public function loadDocument($url)

$httpHeadersOffset = 0;

/*
* TODO: remove this if-clause when dropping 8.4.x support
* As of PHP 8.4.0 using $http_response_header is deprecated, related deprecation message:
*
* The predefined locally scoped $http_response_header variable is deprecated,
* call http_get_last_response_headers() instead.
*
* See: https://www.php.net/manual/de/function.http-get-last-response-headers
*
* On PHP 8.5 the deprecation persists even though the following code should avoid it.
*/
if (function_exists('http_get_last_response_headers')) {
$httpResponseHeader = http_get_last_response_headers();
} elseif (isset($http_response_header)) {
$httpResponseHeader = $http_response_header;
} else {
$httpResponseHeader = null;
}

stream_context_set_params($context, array('notification' =>
function ($code, $severity, $msg, $msgCode, $bytesTx, $bytesMax) use (
&$remoteDocument, &$http_response_header, &$httpHeadersOffset
&$remoteDocument, &$httpResponseHeader, &$httpHeadersOffset
) {
if ($code === STREAM_NOTIFY_MIME_TYPE_IS) {
$remoteDocument->mediaType = $msg;
} elseif ($code === STREAM_NOTIFY_REDIRECTED) {
$remoteDocument->documentUrl = $msg;
$remoteDocument->mediaType = null;

$httpHeadersOffset = isset($http_response_header) ? count($http_response_header) : 0;
$httpHeadersOffset = is_array($httpResponseHeader) ? count($httpResponseHeader) : 0;
}
}
));
Expand All @@ -62,16 +81,16 @@ function ($code, $severity, $msg, $msgCode, $bytesTx, $bytesMax) use (
throw new JsonLdException(
JsonLdException::LOADING_DOCUMENT_FAILED,
sprintf('Unable to load the remote document "%s".', $url),
$http_response_header
$httpResponseHeader
);
}

// Extract HTTP Link headers
$linkHeaderValues = array();
if (is_array($http_response_header)) {
for ($i = count($http_response_header) - 1; $i > $httpHeadersOffset; $i--) {
if (0 === substr_compare($http_response_header[$i], 'Link:', 0, 5, true)) {
$value = substr($http_response_header[$i], 5);
if (is_array($httpResponseHeader)) {
for ($i = count($httpResponseHeader) - 1; $i > $httpHeadersOffset; $i--) {
if (0 === substr_compare($httpResponseHeader[$i], 'Link:', 0, 5, true)) {
$value = substr($httpResponseHeader[$i], 5);
$linkHeaderValues[] = $value;
}
}
Expand All @@ -90,7 +109,7 @@ function ($code, $severity, $msg, $msgCode, $bytesTx, $bytesMax) use (
throw new JsonLdException(
JsonLdException::MULTIPLE_CONTEXT_LINK_HEADERS,
'Found multiple contexts in HTTP Link headers',
$http_response_header
$httpResponseHeader
);
}

Expand Down
12 changes: 12 additions & 0 deletions Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -1482,6 +1482,12 @@ private function getPropertyDefinition($activectx, $property, $only = null)
$result['isKeyword'] = true;
$result['compactArrays'] = (bool) (('@list' !== $property) && ('@graph' !== $property));
} else {
// Adaptions to avoid the following deprecation later on:
// Using null as an array offset is deprecated, use an empty string instead
if (null === $property) {
$property = '';
}

$def = (isset($activectx[$property])) ? $activectx[$property] : null;

if (null !== $def) {
Expand Down Expand Up @@ -2072,6 +2078,12 @@ private function getBlankNodeId($id = null)
return $this->blankNodeMap[$id];
}

// Adaption to avoid the following deprecation later on:
// Using null as an array offset is deprecated, use an empty string instead
if (null === $id) {
$id = '';
}

$bnode = '_:b' . $this->blankNodeCounter++;
$this->blankNodeMap[$id] = $bnode;

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ require('vendor/autoload.php');
Of course, you can also download JsonLD as
[ZIP archive](https://github.com/lanthaler/JsonLD/releases) from Github.

JsonLD requires PHP 5.3 or later.
JsonLD requires **PHP 8.1** or later.


Usage
Expand Down
17 changes: 9 additions & 8 deletions Test/GraphTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace ML\JsonLD\Test;

use InvalidArgumentException;
use ML\JsonLD\Document;
use ML\JsonLD\FileGetContentsLoader;
use ML\JsonLD\Graph;
Expand Down Expand Up @@ -564,11 +565,11 @@ public function testNodePropertyUniqueness()

/**
* Tests whether it is possible to add invalid values
*
* @expectedException InvalidArgumentException
*/
public function testAddInvalidPropertyValue()
{
$this->expectException(InvalidArgumentException::class);

$graph = new Graph();
$newNode = $graph->createNode();

Expand All @@ -579,23 +580,23 @@ public function testAddInvalidPropertyValue()
/**
* Tests whether it is possible to set the node's type to an invalid
* value
*
* @expectedException InvalidArgumentException
*/
public function testSetInvalidTypeValue()
{
$this->expectException(InvalidArgumentException::class);

$node1 = $this->graph->getNode('http://example.com/node/1');
$node1->setType('http://vocab.com/type/aTypeAsString');
}

/**
* Tests whether it is possible to set the node's type to an invalid
* value when an array is used.
*
* @expectedException InvalidArgumentException
*/
public function testSetInvalidTypeArray()
{
$this->expectException(InvalidArgumentException::class);

$types = array(
$this->graph->getNode('http://vocab.com/type/nodeWithAliases'),
'http://vocab.com/type/aTypeAsString'
Expand All @@ -609,11 +610,11 @@ public function testSetInvalidTypeArray()
/**
* Tests whether it is possible to add an type which is not part of the
* graph
*
* @expectedException InvalidArgumentException
*/
public function testAddTypeNotInGraph()
{
$this->expectException(InvalidArgumentException::class);

$graph = new Graph();
$newType = $graph->createNode();

Expand Down
13 changes: 5 additions & 8 deletions Test/JsonLDApiTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace ML\JsonLD\Test;

use ML\JsonLD\JsonLD;
use PHPUnit\Framework\Attributes\Group;

/**
* Tests JsonLD's API
Expand All @@ -20,9 +21,8 @@ class JsonLDApiTest extends JsonTestCase
{
/**
* Tests the expansion API
*
* @group expansion
*/
#[Group('expansion')]
public function testExpansion()
{
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR;
Expand All @@ -40,9 +40,8 @@ public function testExpansion()

/**
* Tests the compaction API
*
* @group compaction
*/
#[Group('compaction')]
public function testCompaction()
{
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR;
Expand All @@ -63,9 +62,8 @@ public function testCompaction()

/**
* Tests the flattening API
*
* @group flattening
*/
#[Group('flattening')]
public function testFlatten()
{
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR;
Expand All @@ -88,9 +86,8 @@ public function testFlatten()
* Tests the framing API
*
* This test intentionally uses the same fixtures as the flattening tests.
*
* @group framing
*/
#[Group('framing')]
public function testFrame()
{
$path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Fixtures' . DIRECTORY_SEPARATOR;
Expand Down
19 changes: 10 additions & 9 deletions Test/NQuadsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

namespace ML\JsonLD\Test;

use ML\JsonLD\Exception\InvalidQuadException;
use ML\JsonLD\JsonLD;
use ML\JsonLD\NQuads;
use PHPUnit\Framework\TestCase;
Expand All @@ -22,11 +23,11 @@ class NQuadsTest extends TestCase
{
/**
* Tests that parsing an invalid NQuad file fails
*
* @expectedException \ML\JsonLD\Exception\InvalidQuadException
*/
public function testInvalidParse()
{
$this->expectException(InvalidQuadException::class);

$nquads = new NQuads();
$nquads->parse('Invalid NQuads file');
}
Expand Down Expand Up @@ -74,34 +75,34 @@ public function testParseBlankNodes()

/**
* Tests that parsing fails for blank node labels beginning with "-"
*
* @expectedException \ML\JsonLD\Exception\InvalidQuadException
*/
public function testParseBlankNodeDashAtTheBeginning()
{
$this->expectException(InvalidQuadException::class);

$nquads = new NQuads();
$nquads->parse('_:-b1 <http://ex/1> "Test" .');
}

/**
* Tests that parsing fails for blank node labels beginning with "."
*
* @expectedException \ML\JsonLD\Exception\InvalidQuadException
*/
public function testParseBlankNodePeriodAtTheBeginning()
{
$this->expectException(InvalidQuadException::class);

$nquads = new NQuads();
$nquads->parse('_:.b1 <http://ex/1> "Test" .');
}

/**
* Tests that parsing fails for blank node labels ending with "."
*
* @expectedException \ML\JsonLD\Exception\InvalidQuadException
*/
public function testParseBlankNodePeriodAtTheEnd()
{
$this->expectException(InvalidQuadException::class);

$nquads = new NQuads();
$nquads->parse('_:b1. <http://ex/1> "Test" .');
}
}
}
37 changes: 34 additions & 3 deletions Test/TestManifestIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

namespace ML\JsonLD\Test;

use Exception;

/**
* TestManifestIterator reads a test manifest and returns the contained test
* definitions.
Expand Down Expand Up @@ -71,7 +73,7 @@ public function valid(): bool
*
* @return string The key of the current element
*/
public function key()
public function key(): mixed
{
return $this->url . $this->manifest->{'sequence'}[$this->key]->{'@id'};
}
Expand All @@ -80,9 +82,11 @@ public function key()
* Returns the current element.
*
* @return array Returns an array containing the name of the test and the
* test definition object.
* test definition object.
*
* @throws Exception
*/
public function current()
public function current(): mixed
{
$test = $this->manifest->{'sequence'}[$this->key];
$options = isset($test->{'option'})
Expand All @@ -101,6 +105,33 @@ public function current()
$options->{'expandContext'} = $this->directory . $options->{'expandContext'};
}

/*
* This code in the if-clause fixes at least the following tests of the W3C test suite:
*
* - remote-doc-manifest.jsonld#t0011
*
* Tests failed because context was not provided properly. The following code extracts
* the context file and loads it into the options object. Later on the value of
* expandContext is being merged into the active context.
*
* For further information: https://github.com/lanthaler/JsonLD/pull/113#issuecomment-3426479583
*/
if (
isset($options->httpLink)
&& is_string($options->httpLink)
&& 1 === preg_match('/<(.*?)>/', $options->httpLink, $match)
&& isset($match[1])
) {
// TODO use a local file path
$linkToContextFile = 'http://localhost:8080/Test/json-ld-test-suite/'.$match[1];
$content = file_get_contents($linkToContextFile);
if (false === $content) {
throw new Exception('Could not context from URL: '. $linkToContextFile);
}

$options->expandContext = json_decode($content, false);
}

$test = array(
'name' => $test->{'name'},
'test' => $test,
Expand Down
Loading
Loading