Update file formatting to PSR-2 (with tabs)

- Use short array syntax
- Bump required PHP version to PHP 5.4
- Update version to 1.0.0
This commit is contained in:
Hypolite Petovan 2018-09-27 19:59:13 -04:00
commit 23cd99e8fb
3 changed files with 6385 additions and 6301 deletions

View file

@ -24,7 +24,7 @@
} }
], ],
"require": { "require": {
"php": ">=5.3.0", "php": ">=5.4.0",
"ext-json": "*" "ext-json": "*"
}, },
"autoload": { "autoload": {

1198
jsonld.php
View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP implementation of the JSON-LD API. * PHP implementation of the JSON-LD API.
* Version: 0.4.8-dev * Version: 0.4.8-dev
@ -48,7 +49,8 @@
* *
* @return mixed the compacted JSON-LD output. * @return mixed the compacted JSON-LD output.
*/ */
function jsonld_compact($input, $ctx, $options=array()) { function jsonld_compact($input, $ctx, $options = [])
{
$p = new JsonLdProcessor(); $p = new JsonLdProcessor();
return $p->compact($input, $ctx, $options); return $p->compact($input, $ctx, $options);
} }
@ -63,7 +65,8 @@ function jsonld_compact($input, $ctx, $options=array()) {
* *
* @return array the expanded JSON-LD output. * @return array the expanded JSON-LD output.
*/ */
function jsonld_expand($input, $options=array()) { function jsonld_expand($input, $options = [])
{
$p = new JsonLdProcessor(); $p = new JsonLdProcessor();
return $p->expand($input, $options); return $p->expand($input, $options);
} }
@ -80,7 +83,8 @@ function jsonld_expand($input, $options=array()) {
* *
* @return mixed the flattened JSON-LD output. * @return mixed the flattened JSON-LD output.
*/ */
function jsonld_flatten($input, $ctx, $options=array()) { function jsonld_flatten($input, $ctx, $options = [])
{
$p = new JsonLdProcessor(); $p = new JsonLdProcessor();
return $p->flatten($input, $ctx, $options); return $p->flatten($input, $ctx, $options);
} }
@ -100,7 +104,8 @@ function jsonld_flatten($input, $ctx, $options=array()) {
* *
* @return stdClass the framed JSON-LD output. * @return stdClass the framed JSON-LD output.
*/ */
function jsonld_frame($input, $frame, $options=array()) { function jsonld_frame($input, $frame, $options = [])
{
$p = new JsonLdProcessor(); $p = new JsonLdProcessor();
return $p->frame($input, $frame, $options); return $p->frame($input, $frame, $options);
} }
@ -119,7 +124,8 @@ function jsonld_frame($input, $frame, $options=array()) {
* *
* @return the linked JSON-LD output. * @return the linked JSON-LD output.
*/ */
function jsonld_link($input, $ctx, $options) { function jsonld_link($input, $ctx, $options)
{
// API matches running frame with a wildcard frame and embed: '@link' // API matches running frame with a wildcard frame and embed: '@link'
// get arguments // get arguments
$frame = new stdClass(); $frame = new stdClass();
@ -128,7 +134,7 @@ function jsonld_link($input, $ctx, $options) {
} }
$frame->{'@embed'} = '@link'; $frame->{'@embed'} = '@link';
return jsonld_frame($input, $frame, $options); return jsonld_frame($input, $frame, $options);
}; }
/** /**
* Performs RDF dataset normalization on the given input. The input is * Performs RDF dataset normalization on the given input. The input is
@ -146,7 +152,8 @@ function jsonld_link($input, $ctx, $options) {
* *
* @return mixed the normalized output. * @return mixed the normalized output.
*/ */
function jsonld_normalize($input, $options=array()) { function jsonld_normalize($input, $options = [])
{
$p = new JsonLdProcessor(); $p = new JsonLdProcessor();
return $p->normalize($input, $options); return $p->normalize($input, $options);
} }
@ -166,7 +173,8 @@ function jsonld_normalize($input, $options=array()) {
* *
* @return array the JSON-LD output. * @return array the JSON-LD output.
*/ */
function jsonld_from_rdf($input, $options=array()) { function jsonld_from_rdf($input, $options = [])
{
$p = new JsonLdProcessor(); $p = new JsonLdProcessor();
return $p->fromRDF($input, $options); return $p->fromRDF($input, $options);
} }
@ -185,7 +193,8 @@ function jsonld_from_rdf($input, $options=array()) {
* *
* @return mixed the resulting RDF dataset (or a serialization of it). * @return mixed the resulting RDF dataset (or a serialization of it).
*/ */
function jsonld_to_rdf($input, $options=array()) { function jsonld_to_rdf($input, $options = [])
{
$p = new JsonLdProcessor(); $p = new JsonLdProcessor();
return $p->toRDF($input, $options); return $p->toRDF($input, $options);
} }
@ -201,7 +210,8 @@ function jsonld_to_rdf($input, $options=array()) {
* *
* @return the encoded JSON data. * @return the encoded JSON data.
*/ */
function jsonld_encode($input, $options=0, $depth=512) { function jsonld_encode($input, $options = 0, $depth = 512)
{
// newer PHP has a flag to avoid escaped '/' // newer PHP has a flag to avoid escaped '/'
if (defined('JSON_UNESCAPED_SLASHES')) { if (defined('JSON_UNESCAPED_SLASHES')) {
return json_encode($input, JSON_UNESCAPED_SLASHES | $options, $depth); return json_encode($input, JSON_UNESCAPED_SLASHES | $options, $depth);
@ -217,7 +227,8 @@ function jsonld_encode($input, $options=0, $depth=512) {
* *
* @return mixed the resolved JSON-LD object, null on error. * @return mixed the resolved JSON-LD object, null on error.
*/ */
function jsonld_decode($input) { function jsonld_decode($input)
{
return json_decode($input); return json_decode($input);
} }
@ -241,32 +252,34 @@ function jsonld_decode($input) {
* *
* @return assoc the parsed result. * @return assoc the parsed result.
*/ */
function jsonld_parse_link_header($header) { function jsonld_parse_link_header($header)
$rval = array(); {
$rval = [];
// split on unbracketed/unquoted commas // split on unbracketed/unquoted commas
if(!preg_match_all( if (!preg_match_all('/(?:<[^>]*?>|"[^"]*?"|[^,])+/', $header, $entries, PREG_SET_ORDER)) {
'/(?:<[^>]*?>|"[^"]*?"|[^,])+/', $header, $entries, PREG_SET_ORDER)) {
return $rval; return $rval;
} }
$r_link_header = '/\s*<([^>]*?)>\s*(?:;\s*(.*))?/'; $r_link_header = '/\s*<([^>]*?)>\s*(?:;\s*(.*))?/';
foreach ($entries as $entry) { foreach ($entries as $entry) {
if (!preg_match($r_link_header, $entry[0], $match)) { if (!preg_match($r_link_header, $entry[0], $match)) {
continue; continue;
} }
$result = (object)array('target' => $match[1]); $result = (object) ['target' => $match[1]];
$params = $match[2]; $params = $match[2];
$r_params = '/(.*?)=(?:(?:"([^"]*?)")|([^"]*?))\s*(?:(?:;\s*)|$)/'; $r_params = '/(.*?)=(?:(?:"([^"]*?)")|([^"]*?))\s*(?:(?:;\s*)|$)/';
preg_match_all($r_params, $params, $matches, PREG_SET_ORDER); preg_match_all($r_params, $params, $matches, PREG_SET_ORDER);
foreach ($matches as $match) { foreach ($matches as $match) {
$result->{$match[1]} = $match[2] ?: $match[3]; $result->{$match[1]} = $match[2] ?: $match[3];
} }
$rel = property_exists($result, 'rel') ? $result->rel : ''; $rel = property_exists($result, 'rel') ? $result->rel : '';
if (!isset($rval[$rel])) { if (!isset($rval[$rel])) {
$rval[$rel] = $result; $rval[$rel] = $result;
} else if (is_array($rval[$rel])) { } else if (is_array($rval[$rel])) {
$rval[$rel][] = $result; $rval[$rel][] = $result;
} else { } else {
$rval[$rel] = array($rval[$rel], $result); $rval[$rel] = [$rval[$rel], $result];
} }
} }
return $rval; return $rval;
@ -277,7 +290,8 @@ function jsonld_parse_link_header($header) {
* *
* @param mixed input the JSON-LD input. * @param mixed input the JSON-LD input.
*/ */
function jsonld_relabel_blank_nodes($input) { function jsonld_relabel_blank_nodes($input)
{
$p = new JsonLdProcessor(); $p = new JsonLdProcessor();
return $p->_labelBlankNodes(new UniqueNamer('_:b'), $input); return $p->_labelBlankNodes(new UniqueNamer('_:b'), $input);
} }
@ -298,7 +312,8 @@ $jsonld_default_load_document = 'jsonld_default_document_loader';
* *
* @param callable load_document(url) the document loader. * @param callable load_document(url) the document loader.
*/ */
function jsonld_set_document_loader($load_document) { function jsonld_set_document_loader($load_document)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
$jsonld_default_load_document = $load_document; $jsonld_default_load_document = $load_document;
} }
@ -310,7 +325,8 @@ function jsonld_set_document_loader($load_document) {
* *
* @return the JSON-LD. * @return the JSON-LD.
*/ */
function jsonld_get_url($url) { function jsonld_get_url($url)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
if ($jsonld_default_load_document !== null) { if ($jsonld_default_load_document !== null) {
$document_loader = $jsonld_default_load_document; $document_loader = $jsonld_default_load_document;
@ -322,6 +338,7 @@ function jsonld_get_url($url) {
if ($remote_doc) { if ($remote_doc) {
return $remote_doc->document; return $remote_doc->document;
} }
return null; return null;
} }
@ -332,25 +349,26 @@ function jsonld_get_url($url) {
* *
* @return stdClass the RemoteDocument object. * @return stdClass the RemoteDocument object.
*/ */
function jsonld_default_document_loader($url) { function jsonld_default_document_loader($url)
$doc = (object)array( {
'contextUrl' => null, 'document' => null, 'documentUrl' => $url); $doc = (object) [
$redirects = array(); 'contextUrl' => null, 'document' => null, 'documentUrl' => $url];
$redirects = [];
$opts = array( $opts = [
'http' => array( 'http' => [
'method' => 'GET', 'method' => 'GET',
'header' => 'header' =>
"Accept: application/ld+json\r\n"), "Accept: application/ld+json\r\n"],
/* Note: Use jsonld_default_secure_document_loader for security. */ /* Note: Use jsonld_default_secure_document_loader for security. */
'ssl' => array( 'ssl' => [
'verify_peer' => false, 'verify_peer' => false,
'allow_self_signed' => true) 'allow_self_signed' => true]
); ];
$context = stream_context_create($opts); $context = stream_context_create($opts);
$content_type = null; $content_type = null;
stream_context_set_params($context, array('notification' => stream_context_set_params($context, ['notification' =>
function($notification_code, $severity, $message) use ( function($notification_code, $severity, $message) use (
&$redirects, &$content_type) { &$redirects, &$content_type) {
switch ($notification_code) { switch ($notification_code) {
@ -361,14 +379,14 @@ function jsonld_default_document_loader($url) {
$content_type = $message; $content_type = $message;
break; break;
}; };
})); }]);
$result = @file_get_contents($url, false, $context); $result = @file_get_contents($url, false, $context);
if ($result === false) { if ($result === false) {
throw new JsonLdException( throw new JsonLdException(
'Could not retrieve a JSON-LD document from the URL: ' . $url, 'Could not retrieve a JSON-LD document from the URL: ' . $url, 'jsonld.LoadDocumentError', 'loading document failed');
'jsonld.LoadDocumentError', 'loading document failed');
} }
$link_header = array();
$link_header = [];
foreach ($http_response_header as $header) { foreach ($http_response_header as $header) {
if (strpos($header, 'link') === 0) { if (strpos($header, 'link') === 0) {
$value = explode(': ', $header); $value = explode(': ', $header);
@ -377,19 +395,20 @@ function jsonld_default_document_loader($url) {
} }
} }
} }
$link_header = jsonld_parse_link_header(join(',', $link_header)); $link_header = jsonld_parse_link_header(join(',', $link_header));
if (isset($link_header['http://www.w3.org/ns/json-ld#context'])) { if (isset($link_header['http://www.w3.org/ns/json-ld#context'])) {
$link_header = $link_header['http://www.w3.org/ns/json-ld#context']; $link_header = $link_header['http://www.w3.org/ns/json-ld#context'];
} else { } else {
$link_header = null; $link_header = null;
} }
if ($link_header && $content_type !== 'application/ld+json') { if ($link_header && $content_type !== 'application/ld+json') {
// only 1 related link header permitted // only 1 related link header permitted
if (is_array($link_header)) { if (is_array($link_header)) {
throw new JsonLdException( throw new JsonLdException(
'URL could not be dereferenced, it has more than one ' . 'URL could not be dereferenced, it has more than one ' .
'associated HTTP Link Header.', 'jsonld.LoadDocumentError', 'associated HTTP Link Header.', 'jsonld.LoadDocumentError', 'multiple context link headers', ['url' => $url]);
'multiple context link headers', array('url' => $url));
} }
$doc->{'contextUrl'} = $link_header->target; $doc->{'contextUrl'} = $link_header->target;
} }
@ -399,8 +418,10 @@ function jsonld_default_document_loader($url) {
if ($redirs > 0) { if ($redirs > 0) {
$url = $redirects[$redirs - 1]; $url = $redirects[$redirs - 1];
} }
$doc->document = $result; $doc->document = $result;
$doc->documentUrl = $url; $doc->documentUrl = $url;
return $doc; return $doc;
} }
@ -411,30 +432,33 @@ function jsonld_default_document_loader($url) {
* *
* @return stdClass the RemoteDocument object. * @return stdClass the RemoteDocument object.
*/ */
function jsonld_default_secure_document_loader($url) { function jsonld_default_secure_document_loader($url)
{
if (strpos($url, 'https') !== 0) { if (strpos($url, 'https') !== 0) {
throw new JsonLdException( throw new JsonLdException(
"Could not GET url: '$url'; 'https' is required.", "Could not GET url: '$url'; 'https' is required.",
'jsonld.LoadDocumentError', 'loading document failed'); 'jsonld.LoadDocumentError',
'loading document failed'
);
} }
$doc = (object)array( $doc = (object) [
'contextUrl' => null, 'document' => null, 'documentUrl' => $url); 'contextUrl' => null, 'document' => null, 'documentUrl' => $url];
$redirects = array(); $redirects = [];
// default JSON-LD https GET implementation // default JSON-LD https GET implementation
$opts = array( $opts = [
'http' => array( 'http' => [
'method' => 'GET', 'method' => 'GET',
'header' => 'header' =>
"Accept: application/ld+json\r\n"), "Accept: application/ld+json\r\n"],
'ssl' => array( 'ssl' => [
'verify_peer' => true, 'verify_peer' => true,
'allow_self_signed' => false, 'allow_self_signed' => false,
'cafile' => '/etc/ssl/certs/ca-certificates.crt')); 'cafile' => '/etc/ssl/certs/ca-certificates.crt']];
$context = stream_context_create($opts); $context = stream_context_create($opts);
$content_type = null; $content_type = null;
stream_context_set_params($context, array('notification' => stream_context_set_params($context, ['notification' =>
function($notification_code, $severity, $message) use ( function($notification_code, $severity, $message) use (
&$redirects, &$content_type) { &$redirects, &$content_type) {
switch ($notification_code) { switch ($notification_code) {
@ -445,14 +469,14 @@ function jsonld_default_secure_document_loader($url) {
$content_type = $message; $content_type = $message;
break; break;
}; };
})); }]);
$result = @file_get_contents($url, false, $context); $result = @file_get_contents($url, false, $context);
if ($result === false) { if ($result === false) {
throw new JsonLdException( throw new JsonLdException(
'Could not retrieve a JSON-LD document from the URL: ' + $url, 'Could not retrieve a JSON-LD document from the URL: ' + $url, 'jsonld.LoadDocumentError', 'loading document failed');
'jsonld.LoadDocumentError', 'loading document failed');
} }
$link_header = array();
$link_header = [];
foreach ($http_response_header as $header) { foreach ($http_response_header as $header) {
if (strpos($header, 'link') === 0) { if (strpos($header, 'link') === 0) {
$value = explode(': ', $header); $value = explode(': ', $header);
@ -461,19 +485,20 @@ function jsonld_default_secure_document_loader($url) {
} }
} }
} }
$link_header = jsonld_parse_link_header(join(',', $link_header)); $link_header = jsonld_parse_link_header(join(',', $link_header));
if (isset($link_header['http://www.w3.org/ns/json-ld#context'])) { if (isset($link_header['http://www.w3.org/ns/json-ld#context'])) {
$link_header = $link_header['http://www.w3.org/ns/json-ld#context']; $link_header = $link_header['http://www.w3.org/ns/json-ld#context'];
} else { } else {
$link_header = null; $link_header = null;
} }
if ($link_header && $content_type !== 'application/ld+json') { if ($link_header && $content_type !== 'application/ld+json') {
// only 1 related link header permitted // only 1 related link header permitted
if (is_array($link_header)) { if (is_array($link_header)) {
throw new JsonLdException( throw new JsonLdException(
'URL could not be dereferenced, it has more than one ' . 'URL could not be dereferenced, it has more than one ' .
'associated HTTP Link Header.', 'jsonld.LoadDocumentError', 'associated HTTP Link Header.', 'jsonld.LoadDocumentError', 'multiple context link headers', ['url' => $url]);
'multiple context link headers', array('url' => $url));
} }
$doc->{'contextUrl'} = $link_header->target; $doc->{'contextUrl'} = $link_header->target;
} }
@ -483,12 +508,15 @@ function jsonld_default_secure_document_loader($url) {
if (strpos($redirect, 'https') !== 0) { if (strpos($redirect, 'https') !== 0) {
throw new JsonLdException( throw new JsonLdException(
"Could not GET redirected url: '$redirect'; 'https' is required.", "Could not GET redirected url: '$redirect'; 'https' is required.",
'jsonld.LoadDocumentError', 'loading document failed'); 'jsonld.LoadDocumentError',
'loading document failed'
);
} }
$url = $redirect; $url = $redirect;
} }
$doc->document = $result; $doc->document = $result;
$doc->documentUrl = $url; $doc->documentUrl = $url;
return $doc; return $doc;
} }
@ -505,7 +533,8 @@ $jsonld_rdf_parsers = new stdClass();
* @param callable $parser(input) the parser function (takes a string as * @param callable $parser(input) the parser function (takes a string as
* a parameter and returns an RDF dataset). * a parameter and returns an RDF dataset).
*/ */
function jsonld_register_rdf_parser($content_type, $parser) { function jsonld_register_rdf_parser($content_type, $parser)
{
global $jsonld_rdf_parsers; global $jsonld_rdf_parsers;
$jsonld_rdf_parsers->{$content_type} = $parser; $jsonld_rdf_parsers->{$content_type} = $parser;
} }
@ -515,7 +544,8 @@ function jsonld_register_rdf_parser($content_type, $parser) {
* *
* @param string $content_type the content-type for the parser. * @param string $content_type the content-type for the parser.
*/ */
function jsonld_unregister_rdf_parser($content_type) { function jsonld_unregister_rdf_parser($content_type)
{
global $jsonld_rdf_parsers; global $jsonld_rdf_parsers;
if (property_exists($jsonld_rdf_parsers, $content_type)) { if (property_exists($jsonld_rdf_parsers, $content_type)) {
unset($jsonld_rdf_parsers->{$content_type}); unset($jsonld_rdf_parsers->{$content_type});
@ -529,20 +559,21 @@ function jsonld_unregister_rdf_parser($content_type) {
* *
* @return assoc the parsed URL. * @return assoc the parsed URL.
*/ */
function jsonld_parse_url($url) { function jsonld_parse_url($url)
{
if ($url === null) { if ($url === null) {
$url = ''; $url = '';
} }
$keys = array( $keys = [
'href', 'protocol', 'scheme', '?authority', 'authority', 'href', 'protocol', 'scheme', '?authority', 'authority',
'?auth', 'auth', 'user', 'pass', 'host', '?port', 'port', 'path', '?auth', 'auth', 'user', 'pass', 'host', '?port', 'port', 'path',
'?query', 'query', '?fragment', 'fragment'); '?query', 'query', '?fragment', 'fragment'];
$regex = "/^(([^:\/?#]+):)?(\/\/(((([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(:(\d*))?))?([^?#]*)(\?([^#]*))?(#(.*))?/"; $regex = "/^(([^:\/?#]+):)?(\/\/(((([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(:(\d*))?))?([^?#]*)(\?([^#]*))?(#(.*))?/";
preg_match($regex, $url, $match); preg_match($regex, $url, $match);
$rval = array(); $rval = [];
$flags = array(); $flags = [];
$len = count($keys); $len = count($keys);
for ($i = 0; $i < $len; ++$i) { for ($i = 0; $i < $len; ++$i) {
$key = $keys[$i]; $key = $keys[$i];
@ -583,7 +614,8 @@ function jsonld_parse_url($url) {
* @param string $path the path to remove dot segments from. * @param string $path the path to remove dot segments from.
* @param bool $has_authority true if the URL has an authority, false if not. * @param bool $has_authority true if the URL has an authority, false if not.
*/ */
function jsonld_remove_dot_segments($path, $has_authority) { function jsonld_remove_dot_segments($path, $has_authority)
{
$rval = ''; $rval = '';
if (strpos($path, '/') === 0) { if (strpos($path, '/') === 0) {
@ -592,7 +624,7 @@ function jsonld_remove_dot_segments($path, $has_authority) {
// RFC 3986 5.2.4 (reworked) // RFC 3986 5.2.4 (reworked)
$input = explode('/', $path); $input = explode('/', $path);
$output = array(); $output = [];
while (count($input) > 0) { while (count($input) > 0) {
if ($input[0] === '.' || ($input[0] === '' && count($input) > 1)) { if ($input[0] === '.' || ($input[0] === '' && count($input) > 1)) {
array_shift($input); array_shift($input);
@ -623,7 +655,8 @@ function jsonld_remove_dot_segments($path, $has_authority) {
* *
* @return string the absolute IRI. * @return string the absolute IRI.
*/ */
function jsonld_prepend_base($base, $iri) { function jsonld_prepend_base($base, $iri)
{
// skip IRI processing // skip IRI processing
if ($base === null) { if ($base === null) {
return $iri; return $iri;
@ -643,7 +676,7 @@ function jsonld_prepend_base($base, $iri) {
$rel = jsonld_parse_url($iri); $rel = jsonld_parse_url($iri);
// per RFC3986 5.2.2 // per RFC3986 5.2.2
$transform = array('protocol' => $base['protocol']); $transform = ['protocol' => $base['protocol']];
if ($rel['authority'] !== null) { if ($rel['authority'] !== null) {
$transform['authority'] = $rel['authority']; $transform['authority'] = $rel['authority'];
@ -718,7 +751,8 @@ function jsonld_prepend_base($base, $iri) {
* @return string the relative IRI if relative to base, otherwise the absolute * @return string the relative IRI if relative to base, otherwise the absolute
* IRI. * IRI.
*/ */
function jsonld_remove_base($base, $iri) { function jsonld_remove_base($base, $iri)
{
// skip IRI processing // skip IRI processing
if ($base === null) { if ($base === null) {
return $iri; return $iri;
@ -787,11 +821,12 @@ function jsonld_remove_base($base, $iri) {
return $rval; return $rval;
} }
/** /**
* A JSON-LD processor. * A JSON-LD processor.
*/ */
class JsonLdProcessor { class JsonLdProcessor
{
/** XSD constants */ /** XSD constants */
const XSD_BOOLEAN = 'http://www.w3.org/2001/XMLSchema#boolean'; const XSD_BOOLEAN = 'http://www.w3.org/2001/XMLSchema#boolean';
const XSD_DOUBLE = 'http://www.w3.org/2001/XMLSchema#double'; const XSD_DOUBLE = 'http://www.w3.org/2001/XMLSchema#double';
@ -804,8 +839,7 @@ class JsonLdProcessor {
const RDF_REST = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest'; const RDF_REST = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#rest';
const RDF_NIL = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'; const RDF_NIL = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#nil';
const RDF_TYPE = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type'; const RDF_TYPE = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type';
const RDF_LANGSTRING = const RDF_LANGSTRING = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString';
'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString';
/** Restraints */ /** Restraints */
const MAX_CONTEXT_URLS = 10; const MAX_CONTEXT_URLS = 10;
@ -816,7 +850,10 @@ class JsonLdProcessor {
/** /**
* Constructs a JSON-LD processor. * Constructs a JSON-LD processor.
*/ */
public function __construct() {} public function __construct()
{
}
/** /**
* Performs JSON-LD compaction. * Performs JSON-LD compaction.
@ -835,13 +872,13 @@ class JsonLdProcessor {
* *
* @return mixed the compacted JSON-LD output. * @return mixed the compacted JSON-LD output.
*/ */
public function compact($input, $ctx, $options) { public function compact($input, $ctx, $options)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
if ($ctx === null) { if ($ctx === null) {
throw new JsonLdException( throw new JsonLdException(
'The compaction context must not be null.', 'The compaction context must not be null.', 'jsonld.CompactError', 'invalid local context');
'jsonld.CompactError', 'invalid local context');
} }
// nothing to compact // nothing to compact
@ -849,14 +886,14 @@ class JsonLdProcessor {
return null; return null;
} }
self::setdefaults($options, array( self::setdefaults($options, [
'base' => is_string($input) ? $input : '', 'base' => is_string($input) ? $input : '',
'compactArrays' => true, 'compactArrays' => true,
'graph' => false, 'graph' => false,
'skipExpansion' => false, 'skipExpansion' => false,
'activeCtx' => false, 'activeCtx' => false,
'documentLoader' => $jsonld_default_load_document, 'documentLoader' => $jsonld_default_load_document,
'link' => false)); 'link' => false]);
if ($options['link']) { if ($options['link']) {
// force skip expansion when linking, "link" is not part of the // force skip expansion when linking, "link" is not part of the
// public API, it should only be called from framing // public API, it should only be called from framing
@ -871,8 +908,7 @@ class JsonLdProcessor {
$expanded = $this->expand($input, $options); $expanded = $this->expand($input, $options);
} catch (JsonLdException $e) { } catch (JsonLdException $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not expand input before compaction.', 'Could not expand input before compaction.', 'jsonld.CompactError', null, null, $e);
'jsonld.CompactError', null, null, $e);
} }
} }
@ -882,8 +918,7 @@ class JsonLdProcessor {
$active_ctx = $this->processContext($active_ctx, $ctx, $options); $active_ctx = $this->processContext($active_ctx, $ctx, $options);
} catch (JsonLdException $e) { } catch (JsonLdException $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not process context before compaction.', 'Could not process context before compaction.', 'jsonld.CompactError', null, null, $e);
'jsonld.CompactError', null, null, $e);
} }
// do compaction // do compaction
@ -914,7 +949,7 @@ class JsonLdProcessor {
// remove empty contexts // remove empty contexts
$tmp = $ctx; $tmp = $ctx;
$ctx = array(); $ctx = [];
foreach ($tmp as $v) { foreach ($tmp as $v) {
if (!is_object($v) || count(array_keys((array) $v)) > 0) { if (!is_object($v) || count(array_keys((array) $v)) > 0) {
$ctx[] = $v; $ctx[] = $v;
@ -949,7 +984,7 @@ class JsonLdProcessor {
} }
if ($options['activeCtx']) { if ($options['activeCtx']) {
return array('compacted' => $compacted, 'activeCtx' => $active_ctx); return ['compacted' => $compacted, 'activeCtx' => $active_ctx];
} }
return $compacted; return $compacted;
@ -968,53 +1003,51 @@ class JsonLdProcessor {
* *
* @return array the expanded JSON-LD output. * @return array the expanded JSON-LD output.
*/ */
public function expand($input, $options) { public function expand($input, $options)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
self::setdefaults($options, array( self::setdefaults($options, [
'keepFreeFloatingNodes' => false, 'keepFreeFloatingNodes' => false,
'documentLoader' => $jsonld_default_load_document)); 'documentLoader' => $jsonld_default_load_document]);
// if input is a string, attempt to dereference remote document // if input is a string, attempt to dereference remote document
if (is_string($input)) { if (is_string($input)) {
$remote_doc = call_user_func($options['documentLoader'], $input); $remote_doc = call_user_func($options['documentLoader'], $input);
} else { } else {
$remote_doc = (object)array( $remote_doc = (object) [
'contextUrl' => null, 'contextUrl' => null,
'documentUrl' => null, 'documentUrl' => null,
'document' => $input); 'document' => $input];
} }
try { try {
if ($remote_doc->document === null) { if ($remote_doc->document === null) {
throw new JsonLdException( throw new JsonLdException(
'No remote document found at the given URL.', 'No remote document found at the given URL.', 'jsonld.NullRemoteDocument');
'jsonld.NullRemoteDocument');
} }
if (is_string($remote_doc->document)) { if (is_string($remote_doc->document)) {
$remote_doc->document = self::_parse_json($remote_doc->document); $remote_doc->document = self::_parse_json($remote_doc->document);
} }
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not retrieve a JSON-LD document from the URL.', 'Could not retrieve a JSON-LD document from the URL.', 'jsonld.LoadDocumentError', 'loading document failed', ['remoteDoc' => $remote_doc], $e);
'jsonld.LoadDocumentError', 'loading document failed',
array('remoteDoc' => $remote_doc), $e);
} }
// set default base // set default base
self::setdefault($options, 'base', $remote_doc->documentUrl ?: ''); self::setdefault($options, 'base', $remote_doc->documentUrl ?: '');
// build meta-object and retrieve all @context urls // build meta-object and retrieve all @context urls
$input = (object)array( $input = (object) [
'document' => self::copy($remote_doc->document), 'document' => self::copy($remote_doc->document),
'remoteContext' => (object)array( 'remoteContext' => (object) [
'@context' => $remote_doc->contextUrl)); '@context' => $remote_doc->contextUrl]];
if (isset($options['expandContext'])) { if (isset($options['expandContext'])) {
$expand_context = self::copy($options['expandContext']); $expand_context = self::copy($options['expandContext']);
if (is_object($expand_context) && if (is_object($expand_context) &&
property_exists($expand_context, '@context')) { property_exists($expand_context, '@context')) {
$input->expandContext = $expand_context; $input->expandContext = $expand_context;
} else { } else {
$input->expandContext = (object)array('@context' => $expand_context); $input->expandContext = (object) ['@context' => $expand_context];
} }
} }
@ -1024,8 +1057,7 @@ class JsonLdProcessor {
$input, new stdClass(), $options['documentLoader'], $options['base']); $input, new stdClass(), $options['documentLoader'], $options['base']);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not perform JSON-LD expansion.', 'Could not perform JSON-LD expansion.', 'jsonld.ExpandError', null, null, $e);
'jsonld.ExpandError', null, null, $e);
} }
$active_ctx = $this->_getInitialContext($options); $active_ctx = $this->_getInitialContext($options);
@ -1052,7 +1084,7 @@ class JsonLdProcessor {
count(array_keys((array) $expanded)) === 1) { count(array_keys((array) $expanded)) === 1) {
$expanded = $expanded->{'@graph'}; $expanded = $expanded->{'@graph'};
} else if ($expanded === null) { } else if ($expanded === null) {
$expanded = array(); $expanded = [];
} }
// normalize to an array // normalize to an array
return self::arrayify($expanded); return self::arrayify($expanded);
@ -1070,19 +1102,19 @@ class JsonLdProcessor {
* *
* @return array the flattened output. * @return array the flattened output.
*/ */
public function flatten($input, $ctx, $options) { public function flatten($input, $ctx, $options)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
self::setdefaults($options, array( self::setdefaults($options, [
'base' => is_string($input) ? $input : '', 'base' => is_string($input) ? $input : '',
'documentLoader' => $jsonld_default_load_document)); 'documentLoader' => $jsonld_default_load_document]);
try { try {
// expand input // expand input
$expanded = $this->expand($input, $options); $expanded = $this->expand($input, $options);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not expand input before flattening.', 'Could not expand input before flattening.', 'jsonld.FlattenError', null, null, $e);
'jsonld.FlattenError', null, null, $e);
} }
// do flattening // do flattening
@ -1099,8 +1131,7 @@ class JsonLdProcessor {
$compacted = $this->compact($flattened, $ctx, $options); $compacted = $this->compact($flattened, $ctx, $options);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not compact flattened output.', 'Could not compact flattened output.', 'jsonld.FlattenError', null, null, $e);
'jsonld.FlattenError', null, null, $e);
} }
return $compacted; return $compacted;
@ -1123,41 +1154,39 @@ class JsonLdProcessor {
* *
* @return stdClass the framed JSON-LD output. * @return stdClass the framed JSON-LD output.
*/ */
public function frame($input, $frame, $options) { public function frame($input, $frame, $options)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
self::setdefaults($options, array( self::setdefaults($options, [
'base' => is_string($input) ? $input : '', 'base' => is_string($input) ? $input : '',
'compactArrays' => true, 'compactArrays' => true,
'embed' => '@last', 'embed' => '@last',
'explicit' => false, 'explicit' => false,
'requireAll' => true, 'requireAll' => true,
'omitDefault' => false, 'omitDefault' => false,
'documentLoader' => $jsonld_default_load_document)); 'documentLoader' => $jsonld_default_load_document]);
// if frame is a string, attempt to dereference remote document // if frame is a string, attempt to dereference remote document
if (is_string($frame)) { if (is_string($frame)) {
$remote_frame = call_user_func($options['documentLoader'], $frame); $remote_frame = call_user_func($options['documentLoader'], $frame);
} else { } else {
$remote_frame = (object)array( $remote_frame = (object) [
'contextUrl' => null, 'contextUrl' => null,
'documentUrl' => null, 'documentUrl' => null,
'document' => $frame); 'document' => $frame];
} }
try { try {
if ($remote_frame->document === null) { if ($remote_frame->document === null) {
throw new JsonLdException( throw new JsonLdException(
'No remote document found at the given URL.', 'No remote document found at the given URL.', 'jsonld.NullRemoteDocument');
'jsonld.NullRemoteDocument');
} }
if (is_string($remote_frame->document)) { if (is_string($remote_frame->document)) {
$remote_frame->document = self::_parse_json($remote_frame->document); $remote_frame->document = self::_parse_json($remote_frame->document);
} }
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not retrieve a JSON-LD document from the URL.', 'Could not retrieve a JSON-LD document from the URL.', 'jsonld.LoadDocumentError', 'loading document failed', ['remoteDoc' => $remote_frame], $e);
'jsonld.LoadDocumentError', 'loading document failed',
array('remoteDoc' => $remote_frame), $e);
} }
// preserve frame context // preserve frame context
@ -1181,8 +1210,7 @@ class JsonLdProcessor {
$expanded = $this->expand($input, $options); $expanded = $this->expand($input, $options);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not expand input before framing.', 'Could not expand input before framing.', 'jsonld.FrameError', null, null, $e);
'jsonld.FrameError', null, null, $e);
} }
try { try {
@ -1192,8 +1220,7 @@ class JsonLdProcessor {
$expanded_frame = $this->expand($frame, $opts); $expanded_frame = $this->expand($frame, $opts);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not expand frame before framing.', 'Could not expand frame before framing.', 'jsonld.FrameError', null, null, $e);
'jsonld.FrameError', null, null, $e);
} }
// do framing // do framing
@ -1209,8 +1236,7 @@ class JsonLdProcessor {
$result = $this->compact($framed, $ctx, $options); $result = $this->compact($framed, $ctx, $options);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not compact framed output.', 'Could not compact framed output.', 'jsonld.FrameError', null, null, $e);
'jsonld.FrameError', null, null, $e);
} }
$compacted = $result['compacted']; $compacted = $result['compacted'];
@ -1240,11 +1266,12 @@ class JsonLdProcessor {
* *
* @return mixed the normalized output. * @return mixed the normalized output.
*/ */
public function normalize($input, $options) { public function normalize($input, $options)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
self::setdefaults($options, array( self::setdefaults($options, [
'base' => is_string($input) ? $input : '', 'base' => is_string($input) ? $input : '',
'documentLoader' => $jsonld_default_load_document)); 'documentLoader' => $jsonld_default_load_document]);
if (isset($options['inputFormat'])) { if (isset($options['inputFormat'])) {
if ($options['inputFormat'] != 'application/nquads') { if ($options['inputFormat'] != 'application/nquads') {
@ -1263,8 +1290,7 @@ class JsonLdProcessor {
$dataset = $this->toRDF($input, $opts); $dataset = $this->toRDF($input, $opts);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not convert input to RDF dataset before normalization.', 'Could not convert input to RDF dataset before normalization.', 'jsonld.NormalizeError', null, null, $e);
'jsonld.NormalizeError', null, null, $e);
} }
} }
@ -1287,12 +1313,13 @@ class JsonLdProcessor {
* *
* @return array the JSON-LD output. * @return array the JSON-LD output.
*/ */
public function fromRDF($dataset, $options) { public function fromRDF($dataset, $options)
{
global $jsonld_rdf_parsers; global $jsonld_rdf_parsers;
self::setdefaults($options, array( self::setdefaults($options, [
'useRdfType' => false, 'useRdfType' => false,
'useNativeTypes' => false)); 'useNativeTypes' => false]);
if (!isset($options['format']) && is_string($dataset)) { if (!isset($options['format']) && is_string($dataset)) {
// set default format to nquads // set default format to nquads
@ -1307,8 +1334,7 @@ class JsonLdProcessor {
$this->rdfParsers === null && $this->rdfParsers === null &&
!property_exists($jsonld_rdf_parsers, $options['format'])) { !property_exists($jsonld_rdf_parsers, $options['format'])) {
throw new JsonLdException( throw new JsonLdException(
'Unknown input format.', 'Unknown input format.', 'jsonld.UnknownFormat', null, ['format' => $options['format']]);
'jsonld.UnknownFormat', null, array('format' => $options['format']));
} }
if ($this->rdfParsers !== null) { if ($this->rdfParsers !== null) {
$callable = $this->rdfParsers->{$options['format']}; $callable = $this->rdfParsers->{$options['format']};
@ -1337,25 +1363,25 @@ class JsonLdProcessor {
* *
* @return mixed the resulting RDF dataset (or a serialization of it). * @return mixed the resulting RDF dataset (or a serialization of it).
*/ */
public function toRDF($input, $options) { public function toRDF($input, $options)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
self::setdefaults($options, array( self::setdefaults($options, [
'base' => is_string($input) ? $input : '', 'base' => is_string($input) ? $input : '',
'produceGeneralizedRdf' => false, 'produceGeneralizedRdf' => false,
'documentLoader' => $jsonld_default_load_document)); 'documentLoader' => $jsonld_default_load_document]);
try { try {
// expand input // expand input
$expanded = $this->expand($input, $options); $expanded = $this->expand($input, $options);
} catch (JsonLdException $e) { } catch (JsonLdException $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not expand input before serialization to RDF.', 'Could not expand input before serialization to RDF.', 'jsonld.RdfError', null, null, $e);
'jsonld.RdfError', null, null, $e);
} }
// create node map for default graph (and any named graphs) // create node map for default graph (and any named graphs)
$namer = new UniqueNamer('_:b'); $namer = new UniqueNamer('_:b');
$node_map = (object)array('@default' => new stdClass()); $node_map = (object) ['@default' => new stdClass()];
$this->_createNodeMap($expanded, $node_map, '@default', $namer); $this->_createNodeMap($expanded, $node_map, '@default', $namer);
// output RDF dataset // output RDF dataset
@ -1379,8 +1405,7 @@ class JsonLdProcessor {
$rval = self::toNQuads($dataset); $rval = self::toNQuads($dataset);
} else { } else {
throw new JsonLdException( throw new JsonLdException(
'Unknown output format.', 'jsonld.UnknownFormat', 'Unknown output format.', 'jsonld.UnknownFormat', null, ['format' => $options['format']]);
null, array('format' => $options['format']));
} }
} }
@ -1398,11 +1423,12 @@ class JsonLdProcessor {
* *
* @return stdClass the new active context. * @return stdClass the new active context.
*/ */
public function processContext($active_ctx, $local_ctx, $options) { public function processContext($active_ctx, $local_ctx, $options)
{
global $jsonld_default_load_document; global $jsonld_default_load_document;
self::setdefaults($options, array( self::setdefaults($options, [
'base' => '', 'base' => '',
'documentLoader' => $jsonld_default_load_document)); 'documentLoader' => $jsonld_default_load_document]);
// return initial context early for null context // return initial context early for null context
if ($local_ctx === null) { if ($local_ctx === null) {
@ -1413,16 +1439,14 @@ class JsonLdProcessor {
$local_ctx = self::copy($local_ctx); $local_ctx = self::copy($local_ctx);
if (is_string($local_ctx) or ( if (is_string($local_ctx) or (
is_object($local_ctx) && !property_exists($local_ctx, '@context'))) { is_object($local_ctx) && !property_exists($local_ctx, '@context'))) {
$local_ctx = (object)array('@context' => $local_ctx); $local_ctx = (object) ['@context' => $local_ctx];
} }
try { try {
$this->_retrieveContextUrls( $this->_retrieveContextUrls(
$local_ctx, new stdClass(), $local_ctx, new stdClass(), $options['documentLoader'], $options['base']);
$options['documentLoader'], $options['base']);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not process JSON-LD context.', 'Could not process JSON-LD context.', 'jsonld.ContextError', null, null, $e);
'jsonld.ContextError', null, null, $e);
} }
// process context // process context
@ -1437,7 +1461,8 @@ class JsonLdProcessor {
* *
* @return bool true if the subject has the given property, false if not. * @return bool true if the subject has the given property, false if not.
*/ */
public static function hasProperty($subject, $property) { public static function hasProperty($subject, $property)
{
$rval = false; $rval = false;
if (property_exists($subject, $property)) { if (property_exists($subject, $property)) {
$value = $subject->{$property}; $value = $subject->{$property};
@ -1455,7 +1480,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value exists, false if not. * @return bool true if the value exists, false if not.
*/ */
public static function hasValue($subject, $property, $value) { public static function hasValue($subject, $property, $value)
{
$rval = false; $rval = false;
if (self::hasProperty($subject, $property)) { if (self::hasProperty($subject, $property)) {
$val = $subject->{$property}; $val = $subject->{$property};
@ -1497,15 +1523,16 @@ class JsonLdProcessor {
* (default: true). * (default: true).
*/ */
public static function addValue( public static function addValue(
$subject, $property, $value, $options=array()) { $subject, $property, $value, $options = [])
self::setdefaults($options, array( {
self::setdefaults($options, [
'allowDuplicate' => true, 'allowDuplicate' => true,
'propertyIsArray' => false)); 'propertyIsArray' => false]);
if (is_array($value)) { if (is_array($value)) {
if (count($value) === 0 && $options['propertyIsArray'] && if (count($value) === 0 && $options['propertyIsArray'] &&
!property_exists($subject, $property)) { !property_exists($subject, $property)) {
$subject->{$property} = array(); $subject->{$property} = [];
} }
foreach ($value as $v) { foreach ($value as $v) {
self::addValue($subject, $property, $v, $options); self::addValue($subject, $property, $v, $options);
@ -1518,7 +1545,7 @@ class JsonLdProcessor {
// make property an array if value not present or always an array // make property an array if value not present or always an array
if (!is_array($subject->{$property}) && if (!is_array($subject->{$property}) &&
(!$has_value || $options['propertyIsArray'])) { (!$has_value || $options['propertyIsArray'])) {
$subject->{$property} = array($subject->{$property}); $subject->{$property} = [$subject->{$property}];
} }
// add new value // add new value
@ -1528,7 +1555,7 @@ class JsonLdProcessor {
} else { } else {
// add new value as set or single value // add new value as set or single value
$subject->{$property} = ($options['propertyIsArray'] ? $subject->{$property} = ($options['propertyIsArray'] ?
array($value) : $value); [$value] : $value);
} }
} }
@ -1540,9 +1567,10 @@ class JsonLdProcessor {
* *
* @return array all of the values for a subject's property as an array. * @return array all of the values for a subject's property as an array.
*/ */
public static function getValues($subject, $property) { public static function getValues($subject, $property)
{
$rval = (property_exists($subject, $property) ? $rval = (property_exists($subject, $property) ?
$subject->{$property} : array()); $subject->{$property} : []);
return self::arrayify($rval); return self::arrayify($rval);
} }
@ -1552,7 +1580,8 @@ class JsonLdProcessor {
* @param stdClass $subject the subject. * @param stdClass $subject the subject.
* @param string $property the property. * @param string $property the property.
*/ */
public static function removeProperty($subject, $property) { public static function removeProperty($subject, $property)
{
unset($subject->{$property}); unset($subject->{$property});
} }
@ -1567,9 +1596,10 @@ class JsonLdProcessor {
* false if not (default: false). * false if not (default: false).
*/ */
public static function removeValue( public static function removeValue(
$subject, $property, $value, $options=array()) { $subject, $property, $value, $options = [])
self::setdefaults($options, array( {
'propertyIsArray' => false)); self::setdefaults($options, [
'propertyIsArray' => false]);
// filter out value // filter out value
$filter = function($e) use ($value) { $filter = function($e) use ($value) {
@ -1601,7 +1631,8 @@ class JsonLdProcessor {
* *
* @return bool true if v1 and v2 are considered equal, false if not. * @return bool true if v1 and v2 are considered equal, false if not.
*/ */
public static function compareValues($v1, $v2) { public static function compareValues($v1, $v2)
{
// 1. equal primitives // 1. equal primitives
if ($v1 === $v2) { if ($v1 === $v2) {
return true; return true;
@ -1636,7 +1667,8 @@ class JsonLdProcessor {
* *
* @return mixed the value. * @return mixed the value.
*/ */
public static function getContextValue($ctx, $key, $type) { public static function getContextValue($ctx, $key, $type)
{
$rval = null; $rval = null;
// return null for invalid key // return null for invalid key
@ -1675,7 +1707,8 @@ class JsonLdProcessor {
* *
* @return stdClass an RDF dataset. * @return stdClass an RDF dataset.
*/ */
public static function parseNQuads($input) { public static function parseNQuads($input)
{
// define partial regexes // define partial regexes
$iri = '(?:<([^:]+:[^>]*)>)'; $iri = '(?:<([^:]+:[^>]*)>)';
$bnode = '(_:(?:[A-Za-z][A-Za-z0-9]*))'; $bnode = '(_:(?:[A-Za-z][A-Za-z0-9]*))';
@ -1713,15 +1746,14 @@ class JsonLdProcessor {
// parse quad // parse quad
if (!preg_match($quad, $line, $match)) { if (!preg_match($quad, $line, $match)) {
throw new JsonLdException( throw new JsonLdException(
'Error while parsing N-Quads; invalid quad.', 'Error while parsing N-Quads; invalid quad.', 'jsonld.ParseError', null, ['line' => $line_number]);
'jsonld.ParseError', null, array('line' => $line_number));
} }
// create RDF triple // create RDF triple
$triple = (object)array( $triple = (object) [
'subject' => new stdClass(), 'subject' => new stdClass(),
'predicate' => new stdClass(), 'predicate' => new stdClass(),
'object' => new stdClass()); 'object' => new stdClass()];
// get subject // get subject
if ($match[1] !== '') { if ($match[1] !== '') {
@ -1746,9 +1778,7 @@ class JsonLdProcessor {
} else { } else {
$triple->object->type = 'literal'; $triple->object->type = 'literal';
$unescaped = str_replace( $unescaped = str_replace(
array('\"', '\t', '\n', '\r', '\\\\'), ['\"', '\t', '\n', '\r', '\\\\'], ['"', "\t", "\n", "\r", '\\'], $match[6]);
array('"', "\t", "\n", "\r", '\\'),
$match[6]);
if (isset($match[7]) && $match[7] !== '') { if (isset($match[7]) && $match[7] !== '') {
$triple->object->datatype = $match[7]; $triple->object->datatype = $match[7];
} else if (isset($match[8]) && $match[8] !== '') { } else if (isset($match[8]) && $match[8] !== '') {
@ -1770,7 +1800,7 @@ class JsonLdProcessor {
// initialize graph in dataset // initialize graph in dataset
if (!property_exists($dataset, $name)) { if (!property_exists($dataset, $name)) {
$dataset->{$name} = array($triple); $dataset->{$name} = [$triple];
} else { } else {
// add triple if unique to its graph // add triple if unique to its graph
$unique = true; $unique = true;
@ -1797,8 +1827,9 @@ class JsonLdProcessor {
* *
* @return string the N-Quads string. * @return string the N-Quads string.
*/ */
public static function toNQuads($dataset) { public static function toNQuads($dataset)
$quads = array(); {
$quads = [];
foreach ($dataset as $graph_name => $triples) { foreach ($dataset as $graph_name => $triples) {
foreach ($triples as $triple) { foreach ($triples as $triple) {
if ($graph_name === '@default') { if ($graph_name === '@default') {
@ -1822,7 +1853,8 @@ class JsonLdProcessor {
* *
* @return string the N-Quad string. * @return string the N-Quad string.
*/ */
public static function toNQuad($triple, $graph_name, $bnode=null) { public static function toNQuad($triple, $graph_name, $bnode = null)
{
$s = $triple->subject; $s = $triple->subject;
$p = $triple->predicate; $p = $triple->predicate;
$o = $triple->object; $o = $triple->object;
@ -1868,9 +1900,7 @@ class JsonLdProcessor {
} }
} else { } else {
$escaped = str_replace( $escaped = str_replace(
array('\\', "\t", "\n", "\r", '"'), ['\\', "\t", "\n", "\r", '"'], ['\\\\', '\t', '\n', '\r', '\"'], $o->value);
array('\\\\', '\t', '\n', '\r', '\"'),
$o->value);
$quad .= '"' . $escaped . '"'; $quad .= '"' . $escaped . '"';
if ($o->datatype === self::RDF_LANGSTRING) { if ($o->datatype === self::RDF_LANGSTRING) {
if ($o->language) { if ($o->language) {
@ -1904,7 +1934,8 @@ class JsonLdProcessor {
* @param callable $parser(input) the parser function (takes a string as * @param callable $parser(input) the parser function (takes a string as
* a parameter and returns an RDF dataset). * a parameter and returns an RDF dataset).
*/ */
public function registerRDFParser($content_type, $parser) { public function registerRDFParser($content_type, $parser)
{
if ($this->rdfParsers === null) { if ($this->rdfParsers === null) {
$this->rdfParsers = new stdClass(); $this->rdfParsers = new stdClass();
} }
@ -1918,7 +1949,8 @@ class JsonLdProcessor {
* *
* @param string $content_type the content-type for the parser. * @param string $content_type the content-type for the parser.
*/ */
public function unregisterRDFParser($content_type) { public function unregisterRDFParser($content_type)
{
if ($this->rdfParsers !== null && if ($this->rdfParsers !== null &&
property_exists($this->rdfParsers, $content_type)) { property_exists($this->rdfParsers, $content_type)) {
unset($this->rdfParsers->{$content_type}); unset($this->rdfParsers->{$content_type});
@ -1936,8 +1968,9 @@ class JsonLdProcessor {
* *
* @return array an array. * @return array an array.
*/ */
public static function arrayify($value) { public static function arrayify($value)
return is_array($value) ? $value : array($value); {
return is_array($value) ? $value : [$value];
} }
/** /**
@ -1947,7 +1980,8 @@ class JsonLdProcessor {
* *
* @return mixed the cloned value. * @return mixed the cloned value.
*/ */
public static function copy($value) { public static function copy($value)
{
if (is_object($value) || is_array($value)) { if (is_object($value) || is_array($value)) {
return unserialize(serialize($value)); return unserialize(serialize($value));
} }
@ -1962,7 +1996,8 @@ class JsonLdProcessor {
* @param string $key the key to update. * @param string $key the key to update.
* @param mixed $value the value to set. * @param mixed $value the value to set.
*/ */
public static function setdefault(&$arr, $key, $value) { public static function setdefault(&$arr, $key, $value)
{
isset($arr[$key]) or $arr[$key] = $value; isset($arr[$key]) or $arr[$key] = $value;
} }
@ -1972,7 +2007,8 @@ class JsonLdProcessor {
* @param &assoc $arr the object to update. * @param &assoc $arr the object to update.
* @param assoc $defaults the default keys and values. * @param assoc $defaults the default keys and values.
*/ */
public static function setdefaults(&$arr, $defaults) { public static function setdefaults(&$arr, $defaults)
{
foreach ($defaults as $key => $value) { foreach ($defaults as $key => $value) {
self::setdefault($arr, $key, $value); self::setdefault($arr, $key, $value);
} }
@ -1991,10 +2027,11 @@ class JsonLdProcessor {
* @return mixed the compacted value. * @return mixed the compacted value.
*/ */
protected function _compact( protected function _compact(
$active_ctx, $active_property, $element, $options) { $active_ctx, $active_property, $element, $options)
{
// recursively compact array // recursively compact array
if (is_array($element)) { if (is_array($element)) {
$rval = array(); $rval = [];
foreach ($element as $e) { foreach ($element as $e) {
// compact, dropping any null values // compact, dropping any null values
$compacted = $this->_compact( $compacted = $this->_compact(
@ -2033,10 +2070,10 @@ class JsonLdProcessor {
if ($options['link'] && self::_isSubjectReference($element)) { if ($options['link'] && self::_isSubjectReference($element)) {
// store linked element // store linked element
if (!isset($options['link'][$element->{'@id'}])) { if (!isset($options['link'][$element->{'@id'}])) {
$options['link'][$element->{'@id'}] = array(); $options['link'][$element->{'@id'}] = [];
} }
$options['link'][$element->{'@id'}][] = array( $options['link'][$element->{'@id'}][] = [
'expanded' => $element, 'compacted' => $rval); 'expanded' => $element, 'compacted' => $rval];
} }
return $rval; return $rval;
} }
@ -2049,10 +2086,10 @@ class JsonLdProcessor {
if ($options['link'] && property_exists($element, '@id')) { if ($options['link'] && property_exists($element, '@id')) {
// store linked element // store linked element
if (!isset($options['link'][$element->{'@id'}])) { if (!isset($options['link'][$element->{'@id'}])) {
$options['link'][$element->{'@id'}] = array(); $options['link'][$element->{'@id'}] = [];
} }
$options['link'][$element->{'@id'}][] = array( $options['link'][$element->{'@id'}][] = [
'expanded' => $element, 'compacted' => $rval); 'expanded' => $element, 'compacted' => $rval];
} }
// process element keys in order // process element keys in order
@ -2066,14 +2103,13 @@ class JsonLdProcessor {
if (is_string($expanded_value)) { if (is_string($expanded_value)) {
// compact single @id // compact single @id
$compacted_value = $this->_compactIri( $compacted_value = $this->_compactIri(
$active_ctx, $expanded_value, null, $active_ctx, $expanded_value, null, ['vocab' => ($expanded_property === '@type')]);
array('vocab' => ($expanded_property === '@type')));
} else { } else {
// expanded value must be a @type array // expanded value must be a @type array
$compacted_value = array(); $compacted_value = [];
foreach ($expanded_value as $ev) { foreach ($expanded_value as $ev) {
$compacted_value[] = $this->_compactIri( $compacted_value[] = $this->_compactIri(
$active_ctx, $ev, null, array('vocab' => true)); $active_ctx, $ev, null, ['vocab' => true]);
} }
} }
@ -2082,8 +2118,7 @@ class JsonLdProcessor {
$is_array = (is_array($compacted_value) && $is_array = (is_array($compacted_value) &&
count($expanded_value) === 0); count($expanded_value) === 0);
self::addValue( self::addValue(
$rval, $alias, $compacted_value, $rval, $alias, $compacted_value, ['propertyIsArray' => $is_array]);
array('propertyIsArray' => $is_array));
continue; continue;
} }
@ -2103,8 +2138,7 @@ class JsonLdProcessor {
$use_array = ($container === '@set' || $use_array = ($container === '@set' ||
!$options['compactArrays']); !$options['compactArrays']);
self::addValue( self::addValue(
$rval, $compacted_property, $value, $rval, $compacted_property, $value, ['propertyIsArray' => $use_array]);
array('propertyIsArray' => $use_array));
unset($compacted_value->{$compacted_property}); unset($compacted_value->{$compacted_property});
} }
} }
@ -2143,23 +2177,19 @@ class JsonLdProcessor {
} }
// Note: expanded value must be an array due to expansion algorithm. // Note: expanded value must be an array due to expansion algorithm.
// preserve empty arrays // preserve empty arrays
if (count($expanded_value) === 0) { if (count($expanded_value) === 0) {
$item_active_property = $this->_compactIri( $item_active_property = $this->_compactIri(
$active_ctx, $expanded_property, $expanded_value, $active_ctx, $expanded_property, $expanded_value, ['vocab' => true], $inside_reverse);
array('vocab' => true), $inside_reverse);
self::addValue( self::addValue(
$rval, $item_active_property, array(), $rval, $item_active_property, [], ['propertyIsArray' => true]);
array('propertyIsArray' => true));
} }
// recusively process array values // recusively process array values
foreach ($expanded_value as $expanded_item) { foreach ($expanded_value as $expanded_item) {
// compact property and get container type // compact property and get container type
$item_active_property = $this->_compactIri( $item_active_property = $this->_compactIri(
$active_ctx, $expanded_property, $expanded_item, $active_ctx, $expanded_property, $expanded_item, ['vocab' => true], $inside_reverse);
array('vocab' => true), $inside_reverse);
$container = self::getContextValue( $container = self::getContextValue(
$active_ctx, $item_active_property, '@container'); $active_ctx, $item_active_property, '@container');
@ -2172,8 +2202,7 @@ class JsonLdProcessor {
// recursively compact expanded item // recursively compact expanded item
$compacted_item = $this->_compact( $compacted_item = $this->_compact(
$active_ctx, $item_active_property, $active_ctx, $item_active_property, $is_list ? $list : $expanded_item, $options);
$is_list ? $list : $expanded_item, $options);
// handle @list // handle @list
if ($is_list) { if ($is_list) {
@ -2182,13 +2211,12 @@ class JsonLdProcessor {
if ($container !== '@list') { if ($container !== '@list') {
// wrap using @list alias // wrap using @list alias
$compacted_item = (object)array( $compacted_item = (object) [
$this->_compactIri($active_ctx, '@list') => $compacted_item); $this->_compactIri($active_ctx, '@list') => $compacted_item];
// include @index from expanded @list, if any // include @index from expanded @list, if any
if (property_exists($expanded_item, '@index')) { if (property_exists($expanded_item, '@index')) {
$compacted_item->{$this->_compactIri($active_ctx, '@index')} = $compacted_item->{$this->_compactIri($active_ctx, '@index')} = $expanded_item->{'@index'};
$expanded_item->{'@index'};
} }
} else if (property_exists($rval, $item_active_property)) { } else if (property_exists($rval, $item_active_property)) {
// can't use @list container for more than 1 list // can't use @list container for more than 1 list
@ -2196,8 +2224,7 @@ class JsonLdProcessor {
'JSON-LD compact error; property has a "@list" @container ' . 'JSON-LD compact error; property has a "@list" @container ' .
'rule but there is more than a single @list that matches ' . 'rule but there is more than a single @list that matches ' .
'the compacted term in the document. Compaction might mix ' . 'the compacted term in the document. Compaction might mix ' .
'unwanted items into the list.', 'jsonld.SyntaxError', 'unwanted items into the list.', 'jsonld.SyntaxError', 'compaction to list of lists');
'compaction to list of lists');
} }
} }
@ -2232,8 +2259,7 @@ class JsonLdProcessor {
// add compact value // add compact value
self::addValue( self::addValue(
$rval, $item_active_property, $compacted_item, $rval, $item_active_property, $compacted_item, ['propertyIsArray' => $is_array]);
array('propertyIsArray' => $is_array));
} }
} }
} }
@ -2259,7 +2285,8 @@ class JsonLdProcessor {
* @return mixed the expanded value. * @return mixed the expanded value.
*/ */
protected function _expand( protected function _expand(
$active_ctx, $active_property, $element, $options, $inside_list) { $active_ctx, $active_property, $element, $options, $inside_list)
{
// nothing to expand // nothing to expand
if ($element === null) { if ($element === null) {
return $element; return $element;
@ -2267,7 +2294,7 @@ class JsonLdProcessor {
// recursively expand array // recursively expand array
if (is_array($element)) { if (is_array($element)) {
$rval = array(); $rval = [];
$container = self::getContextValue( $container = self::getContextValue(
$active_ctx, $active_property, '@container'); $active_ctx, $active_property, '@container');
$inside_list = $inside_list || $container === '@list'; $inside_list = $inside_list || $container === '@list';
@ -2278,8 +2305,7 @@ class JsonLdProcessor {
if ($inside_list && (is_array($e) || self::_isList($e))) { if ($inside_list && (is_array($e) || self::_isList($e))) {
// lists of lists are illegal // lists of lists are illegal
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; lists of lists are not permitted.', 'Invalid JSON-LD syntax; lists of lists are not permitted.', 'jsonld.SyntaxError', 'list of lists');
'jsonld.SyntaxError', 'list of lists');
} }
// drop null values // drop null values
if ($e !== null) { if ($e !== null) {
@ -2297,8 +2323,7 @@ class JsonLdProcessor {
// drop free-floating scalars that are not in lists // drop free-floating scalars that are not in lists
if (!$inside_list && if (!$inside_list &&
($active_property === null || ($active_property === null ||
$this->_expandIri($active_ctx, $active_property, $this->_expandIri($active_ctx, $active_property, ['vocab' => true]) === '@graph')) {
array('vocab' => true)) === '@graph')) {
return null; return null;
} }
@ -2307,7 +2332,6 @@ class JsonLdProcessor {
} }
// recursively expand object: // recursively expand object:
// if element has a context, process it // if element has a context, process it
if (property_exists($element, '@context')) { if (property_exists($element, '@context')) {
$active_ctx = $this->_processContext( $active_ctx = $this->_processContext(
@ -2316,7 +2340,7 @@ class JsonLdProcessor {
// expand the active property // expand the active property
$expanded_active_property = $this->_expandIri( $expanded_active_property = $this->_expandIri(
$active_ctx, $active_property, array('vocab' => true)); $active_ctx, $active_property, ['vocab' => true]);
$rval = new stdClass(); $rval = new stdClass();
$keys = array_keys((array) $element); $keys = array_keys((array) $element);
@ -2330,7 +2354,7 @@ class JsonLdProcessor {
// expand key to IRI // expand key to IRI
$expanded_property = $this->_expandIri( $expanded_property = $this->_expandIri(
$active_ctx, $key, array('vocab' => true)); $active_ctx, $key, ['vocab' => true]);
// drop non-absolute IRI keys that aren't keywords // drop non-absolute IRI keys that aren't keywords
if ($expanded_property === null || if ($expanded_property === null ||
@ -2343,14 +2367,11 @@ class JsonLdProcessor {
if ($expanded_active_property === '@reverse') { if ($expanded_active_property === '@reverse') {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; a keyword cannot be used as a @reverse ' . 'Invalid JSON-LD syntax; a keyword cannot be used as a @reverse ' .
'property.', 'jsonld.SyntaxError', 'invalid reverse property map', 'property.', 'jsonld.SyntaxError', 'invalid reverse property map', ['value' => $value]);
array('value' => $value));
} }
if (property_exists($rval, $expanded_property)) { if (property_exists($rval, $expanded_property)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; colliding keywords detected.', 'Invalid JSON-LD syntax; colliding keywords detected.', 'jsonld.SyntaxError', 'colliding keywords', ['keyword' => $expanded_property]);
'jsonld.SyntaxError', 'colliding keywords',
array('keyword' => $expanded_property));
} }
} }
@ -2358,15 +2379,11 @@ class JsonLdProcessor {
if ($expanded_property === '@id' && !is_string($value)) { if ($expanded_property === '@id' && !is_string($value)) {
if (!isset($options['isFrame']) || !$options['isFrame']) { if (!isset($options['isFrame']) || !$options['isFrame']) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@id" value must a string.', 'Invalid JSON-LD syntax; "@id" value must a string.', 'jsonld.SyntaxError', 'invalid @id value', ['value' => $value]);
'jsonld.SyntaxError', 'invalid @id value',
array('value' => $value));
} }
if (!is_object($value)) { if (!is_object($value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@id" value must a string or an object.', 'Invalid JSON-LD syntax; "@id" value must a string or an object.', 'jsonld.SyntaxError', 'invalid @id value', ['value' => $value]);
'jsonld.SyntaxError', 'invalid @id value',
array('value' => $value));
} }
} }
@ -2380,8 +2397,7 @@ class JsonLdProcessor {
!(is_object($value) || is_array($value))) { !(is_object($value) || is_array($value))) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@graph" value must not be an ' . 'Invalid JSON-LD syntax; "@graph" value must not be an ' .
'object or an array.', 'jsonld.SyntaxError', 'object or an array.', 'jsonld.SyntaxError', 'invalid @graph value', ['value' => $value]);
'invalid @graph value', array('value' => $value));
} }
// @value must not be an object or an array // @value must not be an object or an array
@ -2389,8 +2405,7 @@ class JsonLdProcessor {
(is_object($value) || is_array($value))) { (is_object($value) || is_array($value))) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@value" value must not be an ' . 'Invalid JSON-LD syntax; "@value" value must not be an ' .
'object or an array.', 'jsonld.SyntaxError', 'object or an array.', 'jsonld.SyntaxError', 'invalid value object value', ['value' => $value]);
'invalid value object value', array('value' => $value));
} }
// @language must be a string // @language must be a string
@ -2401,9 +2416,7 @@ class JsonLdProcessor {
} }
if (!is_string($value)) { if (!is_string($value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@language" value must not be a string.', 'Invalid JSON-LD syntax; "@language" value must not be a string.', 'jsonld.SyntaxError', 'invalid language-tagged string', ['value' => $value]);
'jsonld.SyntaxError', 'invalid language-tagged string',
array('value' => $value));
} }
// ensure language value is lowercase // ensure language value is lowercase
$value = strtolower($value); $value = strtolower($value);
@ -2413,9 +2426,7 @@ class JsonLdProcessor {
if ($expanded_property === '@index') { if ($expanded_property === '@index') {
if (!is_string($value)) { if (!is_string($value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@index" value must be a string.', 'Invalid JSON-LD syntax; "@index" value must be a string.', 'jsonld.SyntaxError', 'invalid @index value', ['value' => $value]);
'jsonld.SyntaxError', 'invalid @index value',
array('value' => $value));
} }
} }
@ -2423,9 +2434,7 @@ class JsonLdProcessor {
if ($expanded_property === '@reverse') { if ($expanded_property === '@reverse') {
if (!is_object($value)) { if (!is_object($value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@reverse" value must be an object.', 'Invalid JSON-LD syntax; "@reverse" value must be an object.', 'jsonld.SyntaxError', 'invalid @reverse value', ['value' => $value]);
'jsonld.SyntaxError', 'invalid @reverse value',
array('value' => $value));
} }
$expanded_value = $this->_expand( $expanded_value = $this->_expand(
@ -2435,7 +2444,7 @@ class JsonLdProcessor {
if (property_exists($expanded_value, '@reverse')) { if (property_exists($expanded_value, '@reverse')) {
foreach ($expanded_value->{'@reverse'} as $rproperty => $rvalue) { foreach ($expanded_value->{'@reverse'} as $rproperty => $rvalue) {
self::addValue( self::addValue(
$rval, $rproperty, $rvalue, array('propertyIsArray' => true)); $rval, $rproperty, $rvalue, ['propertyIsArray' => true]);
} }
} }
@ -2454,19 +2463,15 @@ class JsonLdProcessor {
$reverse_map = $rval->{'@reverse'} = new stdClass(); $reverse_map = $rval->{'@reverse'} = new stdClass();
} }
self::addValue( self::addValue(
$reverse_map, $property, array(), $reverse_map, $property, [], ['propertyIsArray' => true]);
array('propertyIsArray' => true));
foreach ($items as $item) { foreach ($items as $item) {
if (self::_isValue($item) || self::_isList($item)) { if (self::_isValue($item) || self::_isList($item)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@reverse" value must not be a ' + 'Invalid JSON-LD syntax; "@reverse" value must not be a ' +
'@value or an @list.', 'jsonld.SyntaxError', '@value or an @list.', 'jsonld.SyntaxError', 'invalid reverse property value', ['value' => $expanded_value]);
'invalid reverse property value',
array('value' => $expanded_value));
} }
self::addValue( self::addValue(
$reverse_map, $property, $item, $reverse_map, $property, $item, ['propertyIsArray' => true]);
array('propertyIsArray' => true));
} }
} }
@ -2480,7 +2485,7 @@ class JsonLdProcessor {
$expanded_value = $this->_expandLanguageMap($value); $expanded_value = $this->_expandLanguageMap($value);
} else if ($container === '@index' && is_object($value)) { } else if ($container === '@index' && is_object($value)) {
// handle index container (skip if value is not an object) // handle index container (skip if value is not an object)
$expanded_value = array(); $expanded_value = [];
$value_keys = array_keys((array) $value); $value_keys = array_keys((array) $value);
sort($value_keys); sort($value_keys);
foreach ($value_keys as $value_key) { foreach ($value_keys as $value_key) {
@ -2506,8 +2511,7 @@ class JsonLdProcessor {
$active_ctx, $next_active_property, $value, $options, $is_list); $active_ctx, $next_active_property, $value, $options, $is_list);
if ($is_list && self::_isList($expanded_value)) { if ($is_list && self::_isList($expanded_value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; lists of lists are not permitted.', 'Invalid JSON-LD syntax; lists of lists are not permitted.', 'jsonld.SyntaxError', 'list of lists');
'jsonld.SyntaxError', 'list of lists');
} }
} else { } else {
// recursively expand value with key as new active property // recursively expand value with key as new active property
@ -2525,8 +2529,8 @@ class JsonLdProcessor {
if ($expanded_property !== '@list' && !self::_isList($expanded_value) && if ($expanded_property !== '@list' && !self::_isList($expanded_value) &&
$container === '@list') { $container === '@list') {
// ensure expanded value is an array // ensure expanded value is an array
$expanded_value = (object)array( $expanded_value = (object) [
'@list' => self::arrayify($expanded_value)); '@list' => self::arrayify($expanded_value)];
} }
// FIXME: can this be merged with code above to simplify? // FIXME: can this be merged with code above to simplify?
@ -2544,13 +2548,10 @@ class JsonLdProcessor {
if (self::_isValue($item) || self::_isList($item)) { if (self::_isValue($item) || self::_isList($item)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@reverse" value must not be a ' + 'Invalid JSON-LD syntax; "@reverse" value must not be a ' +
'@value or an @list.', 'jsonld.SyntaxError', '@value or an @list.', 'jsonld.SyntaxError', 'invalid reverse property value', ['value' => $expanded_value]);
'invalid reverse property value',
array('value' => $expanded_value));
} }
self::addValue( self::addValue(
$reverse_map, $expanded_property, $item, $reverse_map, $expanded_property, $item, ['propertyIsArray' => true]);
array('propertyIsArray' => true));
} }
continue; continue;
} }
@ -2558,11 +2559,10 @@ class JsonLdProcessor {
// add value for property // add value for property
// use an array except for certain keywords // use an array except for certain keywords
$use_array = (!in_array( $use_array = (!in_array(
$expanded_property, array( $expanded_property, [
'@index', '@id', '@type', '@value', '@language'))); '@index', '@id', '@type', '@value', '@language']));
self::addValue( self::addValue(
$rval, $expanded_property, $expanded_value, $rval, $expanded_property, $expanded_value, ['propertyIsArray' => $use_array]);
array('propertyIsArray' => $use_array));
} }
// get property count on expanded output // get property count on expanded output
@ -2576,9 +2576,7 @@ class JsonLdProcessor {
property_exists($rval, '@language')) { property_exists($rval, '@language')) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; an element containing "@value" may not ' . 'Invalid JSON-LD syntax; an element containing "@value" may not ' .
'contain both "@type" and "@language".', 'contain both "@type" and "@language".', 'jsonld.SyntaxError', 'invalid value object', ['element' => $rval]);
'jsonld.SyntaxError', 'invalid value object',
array('element' => $rval));
} }
$valid_count = $count - 1; $valid_count = $count - 1;
if (property_exists($rval, '@type')) { if (property_exists($rval, '@type')) {
@ -2594,9 +2592,7 @@ class JsonLdProcessor {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; an element containing "@value" may only ' . 'Invalid JSON-LD syntax; an element containing "@value" may only ' .
'have an "@index" property and at most one other property ' . 'have an "@index" property and at most one other property ' .
'which can be "@type" or "@language".', 'which can be "@type" or "@language".', 'jsonld.SyntaxError', 'invalid value object', ['element' => $rval]);
'jsonld.SyntaxError', 'invalid value object',
array('element' => $rval));
} }
// drop null @values // drop null @values
if ($rval->{'@value'} === null) { if ($rval->{'@value'} === null) {
@ -2605,21 +2601,18 @@ class JsonLdProcessor {
!is_string($rval->{'@value'})) { !is_string($rval->{'@value'})) {
// if @language is present, @value must be a string // if @language is present, @value must be a string
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; only strings may be language-tagged.', 'Invalid JSON-LD syntax; only strings may be language-tagged.', 'jsonld.SyntaxError', 'invalid language-tagged value', ['element' => $rval]);
'jsonld.SyntaxError', 'invalid language-tagged value',
array('element' => $rval));
} else if (property_exists($rval, '@type') && } else if (property_exists($rval, '@type') &&
(!self::_isAbsoluteIri($rval->{'@type'}) || (!self::_isAbsoluteIri($rval->{'@type'}) ||
strpos($rval->{'@type'}, '_:') === 0)) { strpos($rval->{'@type'}, '_:') === 0)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; an element containing "@value" ' . 'Invalid JSON-LD syntax; an element containing "@value" ' .
'and "@type" must have an absolute IRI for the value ' . 'and "@type" must have an absolute IRI for the value ' .
'of "@type".', 'jsonld.SyntaxError', 'invalid typed value', 'of "@type".', 'jsonld.SyntaxError', 'invalid typed value', ['element' => $rval]);
array('element' => $rval));
} }
} else if (property_exists($rval, '@type') && !is_array($rval->{'@type'})) { } else if (property_exists($rval, '@type') && !is_array($rval->{'@type'})) {
// convert @type to an array // convert @type to an array
$rval->{'@type'} = array($rval->{'@type'}); $rval->{'@type'} = [$rval->{'@type'}];
} else if (property_exists($rval, '@set') || } else if (property_exists($rval, '@set') ||
property_exists($rval, '@list')) { property_exists($rval, '@list')) {
// handle @set and @list // handle @set and @list
@ -2627,8 +2620,7 @@ class JsonLdProcessor {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; if an element has the property "@set" ' . 'Invalid JSON-LD syntax; if an element has the property "@set" ' .
'or "@list", then it can have at most one other property that is ' . 'or "@list", then it can have at most one other property that is ' .
'"@index".', 'jsonld.SyntaxError', 'invalid set or list object', '"@index".', 'jsonld.SyntaxError', 'invalid set or list object', ['element' => $rval]);
array('element' => $rval));
} }
// optimize away @set // optimize away @set
if (property_exists($rval, '@set')) { if (property_exists($rval, '@set')) {
@ -2663,10 +2655,11 @@ class JsonLdProcessor {
* *
* @return array the flattened output. * @return array the flattened output.
*/ */
protected function _flatten($input) { protected function _flatten($input)
{
// produce a map of all subjects and name each bnode // produce a map of all subjects and name each bnode
$namer = new UniqueNamer('_:b'); $namer = new UniqueNamer('_:b');
$graphs = (object)array('@default' => new stdClass()); $graphs = (object) ['@default' => new stdClass()];
$this->_createNodeMap($input, $graphs, '@default', $namer); $this->_createNodeMap($input, $graphs, '@default', $namer);
// add all non-default graphs to default graph // add all non-default graphs to default graph
@ -2678,12 +2671,12 @@ class JsonLdProcessor {
} }
$node_map = $graphs->{$graph_name}; $node_map = $graphs->{$graph_name};
if (!property_exists($default_graph, $graph_name)) { if (!property_exists($default_graph, $graph_name)) {
$default_graph->{$graph_name} = (object)array( $default_graph->{$graph_name} = (object) [
'@id' => $graph_name, '@graph' => array()); '@id' => $graph_name, '@graph' => []];
} }
$subject = $default_graph->{$graph_name}; $subject = $default_graph->{$graph_name};
if (!property_exists($subject, '@graph')) { if (!property_exists($subject, '@graph')) {
$subject->{'@graph'} = array(); $subject->{'@graph'} = [];
} }
$ids = array_keys((array) $node_map); $ids = array_keys((array) $node_map);
sort($ids); sort($ids);
@ -2697,7 +2690,7 @@ class JsonLdProcessor {
} }
// produce flattened output // produce flattened output
$flattened = array(); $flattened = [];
$keys = array_keys((array) $default_graph); $keys = array_keys((array) $default_graph);
sort($keys); sort($keys);
foreach ($keys as $key) { foreach ($keys as $key) {
@ -2719,15 +2712,16 @@ class JsonLdProcessor {
* *
* @return array the framed output. * @return array the framed output.
*/ */
protected function _frame($input, $frame, $options) { protected function _frame($input, $frame, $options)
{
// create framing state // create framing state
$state = (object)array( $state = (object) [
'options' => $options, 'options' => $options,
'graphs' => (object)array( 'graphs' => (object) [
'@default' => new stdClass(), '@default' => new stdClass(),
'@merged' => new stdClass()), '@merged' => new stdClass()],
'subjectStack' => array(), 'subjectStack' => [],
'link' => new stdClass()); 'link' => new stdClass()];
// produce a map of all graphs and name each bnode // produce a map of all graphs and name each bnode
// FIXME: currently uses subjects from @merged graph only // FIXME: currently uses subjects from @merged graph only
@ -2751,9 +2745,10 @@ class JsonLdProcessor {
* *
* @return mixed the normalized output. * @return mixed the normalized output.
*/ */
protected function _normalize($dataset, $options) { protected function _normalize($dataset, $options)
{
// create quads and map bnodes to their associated quads // create quads and map bnodes to their associated quads
$quads = array(); $quads = [];
$bnodes = new stdClass(); $bnodes = new stdClass();
foreach ($dataset as $graph_name => $triples) { foreach ($dataset as $graph_name => $triples) {
if ($graph_name === '@default') { if ($graph_name === '@default') {
@ -2763,23 +2758,23 @@ class JsonLdProcessor {
$quad = $triple; $quad = $triple;
if ($graph_name !== null) { if ($graph_name !== null) {
if (strpos($graph_name, '_:') === 0) { if (strpos($graph_name, '_:') === 0) {
$quad->name = (object)array( $quad->name = (object) [
'type' => 'blank node', 'value' => $graph_name); 'type' => 'blank node', 'value' => $graph_name];
} else { } else {
$quad->name = (object)array( $quad->name = (object) [
'type' => 'IRI', 'value' => $graph_name); 'type' => 'IRI', 'value' => $graph_name];
} }
} }
$quads[] = $quad; $quads[] = $quad;
foreach(array('subject', 'object', 'name') as $attr) { foreach (['subject', 'object', 'name'] as $attr) {
if (property_exists($quad, $attr) && if (property_exists($quad, $attr) &&
$quad->{$attr}->type === 'blank node') { $quad->{$attr}->type === 'blank node') {
$id = $quad->{$attr}->value; $id = $quad->{$attr}->value;
if (property_exists($bnodes, $id)) { if (property_exists($bnodes, $id)) {
$bnodes->{$id}->quads[] = $quad; $bnodes->{$id}->quads[] = $quad;
} else { } else {
$bnodes->{$id} = (object)array('quads' => array($quad)); $bnodes->{$id} = (object) ['quads' => [$quad]];
} }
} }
} }
@ -2795,7 +2790,7 @@ class JsonLdProcessor {
$duplicates = null; $duplicates = null;
do { do {
$unnamed = $nextUnnamed; $unnamed = $nextUnnamed;
$nextUnnamed = array(); $nextUnnamed = [];
$duplicates = new stdClass(); $duplicates = new stdClass();
$unique = new stdClass(); $unique = new stdClass();
foreach ($unnamed as $bnode) { foreach ($unnamed as $bnode) {
@ -2807,7 +2802,7 @@ class JsonLdProcessor {
$duplicates->{$hash}[] = $bnode; $duplicates->{$hash}[] = $bnode;
$nextUnnamed[] = $bnode; $nextUnnamed[] = $bnode;
} else if (property_exists($unique, $hash)) { } else if (property_exists($unique, $hash)) {
$duplicates->{$hash} = array($unique->{$hash}, $bnode); $duplicates->{$hash} = [$unique->{$hash}, $bnode];
$nextUnnamed[] = $unique->{$hash}; $nextUnnamed[] = $unique->{$hash};
$nextUnnamed[] = $bnode; $nextUnnamed[] = $bnode;
unset($unique->{$hash}); unset($unique->{$hash});
@ -2822,8 +2817,7 @@ class JsonLdProcessor {
foreach ($hashes as $hash) { foreach ($hashes as $hash) {
$namer->getName($unique->{$hash}); $namer->getName($unique->{$hash});
} }
} } while (count($unnamed) > count($nextUnnamed));
while(count($unnamed) > count($nextUnnamed));
// enumerate duplicate hash groups in sorted order // enumerate duplicate hash groups in sorted order
$hashes = array_keys((array) $duplicates); $hashes = array_keys((array) $duplicates);
@ -2831,7 +2825,7 @@ class JsonLdProcessor {
foreach ($hashes as $hash) { foreach ($hashes as $hash) {
// process group // process group
$group = $duplicates->{$hash}; $group = $duplicates->{$hash};
$results = array(); $results = [];
foreach ($group as $bnode) { foreach ($group as $bnode) {
// skip already-named bnodes // skip already-named bnodes
if ($namer->isNamed($bnode)) { if ($namer->isNamed($bnode)) {
@ -2859,7 +2853,7 @@ class JsonLdProcessor {
} }
// create normalized array // create normalized array
$normalized = array(); $normalized = [];
/* Note: At this point all bnodes in the set of RDF quads have been /* Note: At this point all bnodes in the set of RDF quads have been
assigned canonical names, which have been stored in the 'namer' object. assigned canonical names, which have been stored in the 'namer' object.
@ -2868,7 +2862,7 @@ class JsonLdProcessor {
// update bnode names in each quad and serialize // update bnode names in each quad and serialize
foreach ($quads as $quad) { foreach ($quads as $quad) {
foreach(array('subject', 'object', 'name') as $attr) { foreach (['subject', 'object', 'name'] as $attr) {
if (property_exists($quad, $attr) && if (property_exists($quad, $attr) &&
$quad->{$attr}->type === 'blank node' && $quad->{$attr}->type === 'blank node' &&
strpos($quad->{$attr}->value, '_:c14n') !== 0) { strpos($quad->{$attr}->value, '_:c14n') !== 0) {
@ -2888,8 +2882,7 @@ class JsonLdProcessor {
return implode($normalized); return implode($normalized);
} }
throw new JsonLdException( throw new JsonLdException(
'Unknown output format.', 'Unknown output format.', 'jsonld.UnknownFormat', null, ['format' => $options['format']]);
'jsonld.UnknownFormat', null, array('format' => $options['format']));
} }
// return RDF dataset // return RDF dataset
@ -2904,17 +2897,18 @@ class JsonLdProcessor {
* *
* @return array the JSON-LD output. * @return array the JSON-LD output.
*/ */
protected function _fromRDF($dataset, $options) { protected function _fromRDF($dataset, $options)
{
$default_graph = new stdClass(); $default_graph = new stdClass();
$graph_map = (object)array('@default' => $default_graph); $graph_map = (object) ['@default' => $default_graph];
$referenced_once = (object)array(); $referenced_once = (object) [];
foreach ($dataset as $name => $graph) { foreach ($dataset as $name => $graph) {
if (!property_exists($graph_map, $name)) { if (!property_exists($graph_map, $name)) {
$graph_map->{$name} = new stdClass(); $graph_map->{$name} = new stdClass();
} }
if ($name !== '@default' && !property_exists($default_graph, $name)) { if ($name !== '@default' && !property_exists($default_graph, $name)) {
$default_graph->{$name} = (object)array('@id' => $name); $default_graph->{$name} = (object) ['@id' => $name];
} }
$node_map = $graph_map->{$name}; $node_map = $graph_map->{$name};
foreach ($graph as $triple) { foreach ($graph as $triple) {
@ -2924,23 +2918,23 @@ class JsonLdProcessor {
$o = $triple->object; $o = $triple->object;
if (!property_exists($node_map, $s)) { if (!property_exists($node_map, $s)) {
$node_map->{$s} = (object)array('@id' => $s); $node_map->{$s} = (object) ['@id' => $s];
} }
$node = $node_map->{$s}; $node = $node_map->{$s};
$object_is_id = ($o->type === 'IRI' || $o->type === 'blank node'); $object_is_id = ($o->type === 'IRI' || $o->type === 'blank node');
if ($object_is_id && !property_exists($node_map, $o->value)) { if ($object_is_id && !property_exists($node_map, $o->value)) {
$node_map->{$o->value} = (object)array('@id' => $o->value); $node_map->{$o->value} = (object) ['@id' => $o->value];
} }
if ($p === self::RDF_TYPE && !$options['useRdfType'] && $object_is_id) { if ($p === self::RDF_TYPE && !$options['useRdfType'] && $object_is_id) {
self::addValue( self::addValue(
$node, '@type', $o->value, array('propertyIsArray' => true)); $node, '@type', $o->value, ['propertyIsArray' => true]);
continue; continue;
} }
$value = self::_RDFToObject($o, $options['useNativeTypes']); $value = self::_RDFToObject($o, $options['useNativeTypes']);
self::addValue($node, $p, $value, array('propertyIsArray' => true)); self::addValue($node, $p, $value, ['propertyIsArray' => true]);
// object may be an RDF list/partial list node but we can't know // object may be an RDF list/partial list node but we can't know
// easily until all triples are read // easily until all triples are read
@ -2948,21 +2942,21 @@ class JsonLdProcessor {
if ($o->value === self::RDF_NIL) { if ($o->value === self::RDF_NIL) {
$object = $node_map->{$o->value}; $object = $node_map->{$o->value};
if (!property_exists($object, 'usages')) { if (!property_exists($object, 'usages')) {
$object->usages = array(); $object->usages = [];
} }
$object->usages[] = (object)array( $object->usages[] = (object) [
'node' => $node, 'node' => $node,
'property' => $p, 'property' => $p,
'value' => $value); 'value' => $value];
} else if (property_exists($referenced_once, $o->value)) { } else if (property_exists($referenced_once, $o->value)) {
// object referenced more than once // object referenced more than once
$referenced_once->{$o->value} = false; $referenced_once->{$o->value} = false;
} else { } else {
// track single reference // track single reference
$referenced_once->{$o->value} = (object)array( $referenced_once->{$o->value} = (object) [
'node' => $node, 'node' => $node,
'property' => $p, 'property' => $p,
'value' => $value); 'value' => $value];
} }
} }
} }
@ -2981,8 +2975,8 @@ class JsonLdProcessor {
$node = $usage->node; $node = $usage->node;
$property = $usage->property; $property = $usage->property;
$head = $usage->value; $head = $usage->value;
$list = array(); $list = [];
$list_nodes = array(); $list_nodes = [];
// ensure node is a well-formed list node; it must: // ensure node is a well-formed list node; it must:
// 1. Be referenced only once. // 1. Be referenced only once.
@ -3046,13 +3040,13 @@ class JsonLdProcessor {
unset($nil->usages); unset($nil->usages);
} }
$result = array(); $result = [];
$subjects = array_keys((array) $default_graph); $subjects = array_keys((array) $default_graph);
sort($subjects); sort($subjects);
foreach ($subjects as $subject) { foreach ($subjects as $subject) {
$node = $default_graph->{$subject}; $node = $default_graph->{$subject};
if (property_exists($graph_map, $subject)) { if (property_exists($graph_map, $subject)) {
$node->{'@graph'} = array(); $node->{'@graph'} = [];
$graph_object = $graph_map->{$subject}; $graph_object = $graph_map->{$subject};
$subjects_ = array_keys((array) $graph_object); $subjects_ = array_keys((array) $graph_object);
sort($subjects_); sort($subjects_);
@ -3082,7 +3076,8 @@ class JsonLdProcessor {
* *
* @return stdClass the new active context. * @return stdClass the new active context.
*/ */
protected function _processContext($active_ctx, $local_ctx, $options) { protected function _processContext($active_ctx, $local_ctx, $options)
{
global $jsonld_cache; global $jsonld_cache;
// normalize local context to an array // normalize local context to an array
@ -3115,9 +3110,7 @@ class JsonLdProcessor {
// context must be an object by now, all URLs retrieved before this call // context must be an object by now, all URLs retrieved before this call
if (!is_object($ctx)) { if (!is_object($ctx)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context must be an object.', 'Invalid JSON-LD syntax; @context must be an object.', 'jsonld.SyntaxError', 'invalid local context', ['context' => $ctx]);
'jsonld.SyntaxError', 'invalid local context',
array('context' => $ctx));
} }
// get context from cache if available // get context from cache if available
@ -3145,13 +3138,11 @@ class JsonLdProcessor {
} else if (!is_string($base)) { } else if (!is_string($base)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; the value of "@base" in a ' . 'Invalid JSON-LD syntax; the value of "@base" in a ' .
'@context must be a string or null.', '@context must be a string or null.', 'jsonld.SyntaxError', 'invalid base IRI', ['context' => $ctx]);
'jsonld.SyntaxError', 'invalid base IRI', array('context' => $ctx));
} else if ($base !== '' && !self::_isAbsoluteIri($base)) { } else if ($base !== '' && !self::_isAbsoluteIri($base)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; the value of "@base" in a ' . 'Invalid JSON-LD syntax; the value of "@base" in a ' .
'@context must be an absolute IRI or the empty string.', '@context must be an absolute IRI or the empty string.', 'jsonld.SyntaxError', 'invalid base IRI', ['context' => $ctx]);
'jsonld.SyntaxError', 'invalid base IRI', array('context' => $ctx));
} }
if ($base !== null) { if ($base !== null) {
$base = jsonld_parse_url($base); $base = jsonld_parse_url($base);
@ -3168,15 +3159,11 @@ class JsonLdProcessor {
} else if (!is_string($value)) { } else if (!is_string($value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; the value of "@vocab" in a ' . 'Invalid JSON-LD syntax; the value of "@vocab" in a ' .
'@context must be a string or null.', '@context must be a string or null.', 'jsonld.SyntaxError', 'invalid vocab mapping', ['context' => $ctx]);
'jsonld.SyntaxError', 'invalid vocab mapping',
array('context' => $ctx));
} else if (!self::_isAbsoluteIri($value)) { } else if (!self::_isAbsoluteIri($value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; the value of "@vocab" in a ' . 'Invalid JSON-LD syntax; the value of "@vocab" in a ' .
'@context must be an absolute IRI.', '@context must be an absolute IRI.', 'jsonld.SyntaxError', 'invalid vocab mapping', ['context' => $ctx]);
'jsonld.SyntaxError', 'invalid vocab mapping',
array('context' => $ctx));
} else { } else {
$rval->{'@vocab'} = $value; $rval->{'@vocab'} = $value;
} }
@ -3191,9 +3178,7 @@ class JsonLdProcessor {
} else if (!is_string($value)) { } else if (!is_string($value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; the value of "@language" in a ' . 'Invalid JSON-LD syntax; the value of "@language" in a ' .
'@context must be a string or null.', '@context must be a string or null.', 'jsonld.SyntaxError', 'invalid default language', ['context' => $ctx]);
'jsonld.SyntaxError', 'invalid default language',
array('context' => $ctx));
} else { } else {
$rval->{'@language'} = strtolower($value); $rval->{'@language'} = strtolower($value);
} }
@ -3221,8 +3206,9 @@ class JsonLdProcessor {
* *
* @return array the expanded language map. * @return array the expanded language map.
*/ */
protected function _expandLanguageMap($language_map) { protected function _expandLanguageMap($language_map)
$rval = array(); {
$rval = [];
$keys = array_keys((array) $language_map); $keys = array_keys((array) $language_map);
sort($keys); sort($keys);
foreach ($keys as $key) { foreach ($keys as $key) {
@ -3234,13 +3220,11 @@ class JsonLdProcessor {
} }
if (!is_string($item)) { if (!is_string($item)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; language map values must be strings.', 'Invalid JSON-LD syntax; language map values must be strings.', 'jsonld.SyntaxError', 'invalid language map value', ['languageMap', $language_map]);
'jsonld.SyntaxError', 'invalid language map value',
array('languageMap', $language_map));
} }
$rval[] = (object)array( $rval[] = (object) [
'@value' => $item, '@value' => $item,
'@language' => strtolower($key)); '@language' => strtolower($key)];
} }
} }
return $rval; return $rval;
@ -3254,7 +3238,8 @@ class JsonLdProcessor {
* *
* @return mixed the element. * @return mixed the element.
*/ */
public function _labelBlankNodes($namer, $element) { public function _labelBlankNodes($namer, $element)
{
if (is_array($element)) { if (is_array($element)) {
$length = count($element); $length = count($element);
for ($i = 0; $i < $length; ++$i) { for ($i = 0; $i < $length; ++$i) {
@ -3296,7 +3281,8 @@ class JsonLdProcessor {
* *
* @return mixed the expanded value. * @return mixed the expanded value.
*/ */
protected function _expandValue($active_ctx, $active_property, $value) { protected function _expandValue($active_ctx, $active_property, $value)
{
// nothing to expand // nothing to expand
if ($value === null) { if ($value === null) {
return null; return null;
@ -3304,12 +3290,12 @@ class JsonLdProcessor {
// special-case expand @id and @type (skips '@id' expansion) // special-case expand @id and @type (skips '@id' expansion)
$expanded_property = $this->_expandIri( $expanded_property = $this->_expandIri(
$active_ctx, $active_property, array('vocab' => true)); $active_ctx, $active_property, ['vocab' => true]);
if ($expanded_property === '@id') { if ($expanded_property === '@id') {
return $this->_expandIri($active_ctx, $value, array('base' => true)); return $this->_expandIri($active_ctx, $value, ['base' => true]);
} else if ($expanded_property === '@type') { } else if ($expanded_property === '@type') {
return $this->_expandIri( return $this->_expandIri(
$active_ctx, $value, array('vocab' => true, 'base' => true)); $active_ctx, $value, ['vocab' => true, 'base' => true]);
} }
// get type definition from context // get type definition from context
@ -3318,13 +3304,13 @@ class JsonLdProcessor {
// do @id expansion (automatic for @graph) // do @id expansion (automatic for @graph)
if ($type === '@id' || ($expanded_property === '@graph' && if ($type === '@id' || ($expanded_property === '@graph' &&
is_string($value))) { is_string($value))) {
return (object)array('@id' => $this->_expandIri( return (object) ['@id' => $this->_expandIri(
$active_ctx, $value, array('base' => true))); $active_ctx, $value, ['base' => true])];
} }
// do @id expansion w/vocab // do @id expansion w/vocab
if ($type === '@vocab') { if ($type === '@vocab') {
return (object)array('@id' => $this->_expandIri( return (object) ['@id' => $this->_expandIri(
$active_ctx, $value, array('vocab' => true, 'base' => true))); $active_ctx, $value, ['vocab' => true, 'base' => true])];
} }
// do not expand keyword values // do not expand keyword values
@ -3359,8 +3345,9 @@ class JsonLdProcessor {
* *
* @return array the array of RDF triples for the given graph. * @return array the array of RDF triples for the given graph.
*/ */
protected function _graphToRDF($graph, $namer, $options) { protected function _graphToRDF($graph, $namer, $options)
$rval = array(); {
$rval = [];
$ids = array_keys((array) $graph); $ids = array_keys((array) $graph);
sort($ids); sort($ids);
@ -3411,10 +3398,10 @@ class JsonLdProcessor {
$object = $this->_objectToRDF($item); $object = $this->_objectToRDF($item);
// skip null objects (they are relative IRIs) // skip null objects (they are relative IRIs)
if ($object) { if ($object) {
$rval[] = (object)array( $rval[] = (object) [
'subject' => $subject, 'subject' => $subject,
'predicate' => $predicate, 'predicate' => $predicate,
'object' => $object); 'object' => $object];
} }
} }
} }
@ -3435,35 +3422,36 @@ class JsonLdProcessor {
* @param &array $triples the array of triples to append to. * @param &array $triples the array of triples to append to.
*/ */
protected function _listToRDF( protected function _listToRDF(
$list, $namer, $subject, $predicate, &$triples) { $list, $namer, $subject, $predicate, &$triples)
$first = (object)array('type' => 'IRI', 'value' => self::RDF_FIRST); {
$rest = (object)array('type' => 'IRI', 'value' => self::RDF_REST); $first = (object) ['type' => 'IRI', 'value' => self::RDF_FIRST];
$nil = (object)array('type' => 'IRI', 'value' => self::RDF_NIL); $rest = (object) ['type' => 'IRI', 'value' => self::RDF_REST];
$nil = (object) ['type' => 'IRI', 'value' => self::RDF_NIL];
foreach ($list as $item) { foreach ($list as $item) {
$blank_node = (object)array( $blank_node = (object) [
'type' => 'blank node', 'value' => $namer->getName()); 'type' => 'blank node', 'value' => $namer->getName()];
$triples[] = (object)array( $triples[] = (object) [
'subject' => $subject, 'subject' => $subject,
'predicate' => $predicate, 'predicate' => $predicate,
'object' => $blank_node); 'object' => $blank_node];
$subject = $blank_node; $subject = $blank_node;
$predicate = $first; $predicate = $first;
$object = $this->_objectToRDF($item); $object = $this->_objectToRDF($item);
// skip null objects (they are relative IRIs) // skip null objects (they are relative IRIs)
if ($object) { if ($object) {
$triples[] = (object)array( $triples[] = (object) [
'subject' => $subject, 'subject' => $subject,
'predicate' => $predicate, 'predicate' => $predicate,
'object' => $object); 'object' => $object];
} }
$predicate = $rest; $predicate = $rest;
} }
$triples[] = (object)array( $triples[] = (object) [
'subject' => $subject, 'predicate' => $predicate, 'object' => $nil); 'subject' => $subject, 'predicate' => $predicate, 'object' => $nil];
} }
/** /**
@ -3474,7 +3462,8 @@ class JsonLdProcessor {
* *
* @return stdClass the RDF literal or RDF resource. * @return stdClass the RDF literal or RDF resource.
*/ */
protected function _objectToRDF($item) { protected function _objectToRDF($item)
{
$object = new stdClass(); $object = new stdClass();
if (self::_isValue($item)) { if (self::_isValue($item)) {
@ -3525,14 +3514,15 @@ class JsonLdProcessor {
* *
* @return stdClass the JSON-LD object. * @return stdClass the JSON-LD object.
*/ */
protected function _RDFToObject($o, $use_native_types) { protected function _RDFToObject($o, $use_native_types)
{
// convert IRI/blank node object to JSON-LD // convert IRI/blank node object to JSON-LD
if ($o->type === 'IRI' || $o->type === 'blank node') { if ($o->type === 'IRI' || $o->type === 'blank node') {
return (object)array('@id' => $o->value); return (object) ['@id' => $o->value];
} }
// convert literal object to JSON-LD // convert literal object to JSON-LD
$rval = (object)array('@value' => $o->value); $rval = (object) ['@value' => $o->value];
if (property_exists($o, 'language')) { if (property_exists($o, 'language')) {
// add language // add language
@ -3559,9 +3549,9 @@ class JsonLdProcessor {
} }
} }
// do not add native type // do not add native type
if(!in_array($type, array( if (!in_array($type, [
self::XSD_BOOLEAN, self::XSD_INTEGER, self::XSD_DOUBLE, self::XSD_BOOLEAN, self::XSD_INTEGER, self::XSD_DOUBLE,
self::XSD_STRING))) { self::XSD_STRING])) {
$rval->{'@type'} = $type; $rval->{'@type'} = $type;
} }
} else if ($type !== self::XSD_STRING) { } else if ($type !== self::XSD_STRING) {
@ -3584,7 +3574,8 @@ class JsonLdProcessor {
* @param mixed $list the list to append to, null for none. * @param mixed $list the list to append to, null for none.
*/ */
protected function _createNodeMap( protected function _createNodeMap(
$input, $graphs, $graph, $namer, $name=null, $list=null) { $input, $graphs, $graph, $namer, $name = null, $list = null)
{
// recurse through array // recurse through array
if (is_array($input)) { if (is_array($input)) {
foreach ($input as $e) { foreach ($input as $e) {
@ -3617,7 +3608,6 @@ class JsonLdProcessor {
} }
// Note: At this point, input must be a subject. // Note: At this point, input must be a subject.
// spec requires @type to be named first, so assign names early // spec requires @type to be named first, so assign names early
if (property_exists($input, '@type')) { if (property_exists($input, '@type')) {
foreach ($input->{'@type'} as $type) { foreach ($input->{'@type'} as $type) {
@ -3639,7 +3629,7 @@ class JsonLdProcessor {
// add subject reference to list // add subject reference to list
if ($list !== null) { if ($list !== null) {
$list[] = (object)array('@id' => $name); $list[] = (object) ['@id' => $name];
} }
// create new subject or merge into existing one // create new subject or merge into existing one
@ -3670,7 +3660,7 @@ class JsonLdProcessor {
// handle reverse properties // handle reverse properties
if ($property === '@reverse') { if ($property === '@reverse') {
$referenced_node = (object)array('@id' => $name); $referenced_node = (object) ['@id' => $name];
$reverse_map = $input->{'@reverse'}; $reverse_map = $input->{'@reverse'};
foreach ($reverse_map as $reverse_property => $items) { foreach ($reverse_map as $reverse_property => $items) {
foreach ($items as $item) { foreach ($items as $item) {
@ -3686,8 +3676,7 @@ class JsonLdProcessor {
$item_name = '"'; $item_name = '"';
} }
self::addValue( self::addValue(
$subjects->{$item_name}, $reverse_property, $referenced_node, $subjects->{$item_name}, $reverse_property, $referenced_node, ['propertyIsArray' => true, 'allowDuplicate' => false]);
array('propertyIsArray' => true, 'allowDuplicate' => false));
} }
} }
continue; continue;
@ -3715,9 +3704,7 @@ class JsonLdProcessor {
($input->{'@index'} !== $subject->{'@index'} || ($input->{'@index'} !== $subject->{'@index'} ||
$input->{'@index'}->{'@id'} !== $subject->{'@index'}->{'@id'})) { $input->{'@index'}->{'@id'} !== $subject->{'@index'}->{'@id'})) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; conflicting @index property detected.', 'Invalid JSON-LD syntax; conflicting @index property detected.', 'jsonld.SyntaxError', 'conflicting indexes', ['subject' => $subject]);
'jsonld.SyntaxError', 'conflicting indexes',
array('subject' => $subject));
} }
$subject->{$property} = $input->{$property}; $subject->{$property} = $input->{$property};
continue; continue;
@ -3734,7 +3721,7 @@ class JsonLdProcessor {
// ensure property is added for empty arrays // ensure property is added for empty arrays
if (count($objects) === 0) { if (count($objects) === 0) {
self::addValue( self::addValue(
$subject, $property, array(), array('propertyIsArray' => true)); $subject, $property, [], ['propertyIsArray' => true]);
continue; continue;
} }
foreach ($objects as $o) { foreach ($objects as $o) {
@ -3753,24 +3740,21 @@ class JsonLdProcessor {
// add reference and recurse // add reference and recurse
self::addValue( self::addValue(
$subject, $property, (object)array('@id' => $id), $subject, $property, (object) ['@id' => $id], ['propertyIsArray' => true, 'allowDuplicate' => false]);
array('propertyIsArray' => true, 'allowDuplicate' => false));
$this->_createNodeMap($o, $graphs, $graph, $namer, $id, null); $this->_createNodeMap($o, $graphs, $graph, $namer, $id, null);
} else if (self::_isList($o)) { } else if (self::_isList($o)) {
// handle @list // handle @list
$_list = new ArrayObject(); $_list = new ArrayObject();
$this->_createNodeMap( $this->_createNodeMap(
$o->{'@list'}, $graphs, $graph, $namer, $name, $_list); $o->{'@list'}, $graphs, $graph, $namer, $name, $_list);
$o = (object)array('@list' => (array)$_list); $o = (object) ['@list' => (array) $_list];
self::addValue( self::addValue(
$subject, $property, $o, $subject, $property, $o, ['propertyIsArray' => true, 'allowDuplicate' => false]);
array('propertyIsArray' => true, 'allowDuplicate' => false));
} else { } else {
// handle @value // handle @value
$this->_createNodeMap($o, $graphs, $graph, $namer, $name, null); $this->_createNodeMap($o, $graphs, $graph, $namer, $name, null);
self::addValue( self::addValue(
$subject, $property, $o, $subject, $property, $o, ['propertyIsArray' => true, 'allowDuplicate' => false]);
array('propertyIsArray' => true, 'allowDuplicate' => false));
} }
} }
} }
@ -3786,17 +3770,18 @@ class JsonLdProcessor {
* @param mixed $property the parent property, initialized to null. * @param mixed $property the parent property, initialized to null.
*/ */
protected function _matchFrame( protected function _matchFrame(
$state, $subjects, $frame, $parent, $property) { $state, $subjects, $frame, $parent, $property)
{
// validate the frame // validate the frame
$this->_validateFrame($frame); $this->_validateFrame($frame);
$frame = $frame[0]; $frame = $frame[0];
// get flags for current frame // get flags for current frame
$options = $state->options; $options = $state->options;
$flags = array( $flags = [
'embed' => $this->_getFrameFlag($frame, $options, 'embed'), 'embed' => $this->_getFrameFlag($frame, $options, 'embed'),
'explicit' => $this->_getFrameFlag($frame, $options, 'explicit'), 'explicit' => $this->_getFrameFlag($frame, $options, 'explicit'),
'requireAll' => $this->_getFrameFlag($frame, $options, 'requireAll')); 'requireAll' => $this->_getFrameFlag($frame, $options, 'requireAll')];
// filter out subjects that match the frame // filter out subjects that match the frame
$matches = $this->_filterSubjects($state, $subjects, $frame, $flags); $matches = $this->_filterSubjects($state, $subjects, $frame, $flags);
@ -3807,7 +3792,6 @@ class JsonLdProcessor {
// TODO: may want to also match an existing linked subject against // TODO: may want to also match an existing linked subject against
// the current frame ... so different frames could produce different // the current frame ... so different frames could produce different
// subjects that are only shared in-memory when the frames are the same // subjects that are only shared in-memory when the frames are the same
// add existing linked subject // add existing linked subject
$this->_addFrameOutput($parent, $property, $state->link->{$id}); $this->_addFrameOutput($parent, $property, $state->link->{$id});
continue; continue;
@ -3841,8 +3825,8 @@ class JsonLdProcessor {
if (property_exists($state->uniqueEmbeds, $id)) { if (property_exists($state->uniqueEmbeds, $id)) {
$this->_removeEmbed($state, $id); $this->_removeEmbed($state, $id);
} }
$state->uniqueEmbeds->{$id} = array( $state->uniqueEmbeds->{$id} = [
'parent' => $parent, 'property' => $property); 'parent' => $parent, 'property' => $property];
} }
// push matching subject onto stack to enable circular embed checks // push matching subject onto stack to enable circular embed checks
@ -3869,7 +3853,7 @@ class JsonLdProcessor {
// recurse into list // recurse into list
if (self::_isList($o)) { if (self::_isList($o)) {
// add empty list // add empty list
$list = (object)array('@list' => array()); $list = (object) ['@list' => []];
$this->_addFrameOutput($output, $prop, $list); $this->_addFrameOutput($output, $prop, $list);
// add list objects // add list objects
@ -3881,7 +3865,7 @@ class JsonLdProcessor {
$frame->{$prop}[0]->{'@list'} : $frame->{$prop}[0]->{'@list'} :
$this->_createImplicitFrame($flags)); $this->_createImplicitFrame($flags));
$this->_matchFrame( $this->_matchFrame(
$state, array($o->{'@id'}), $subframe, $list, '@list'); $state, [$o->{'@id'}], $subframe, $list, '@list');
} else { } else {
// include other values automatically // include other values automatically
$this->_addFrameOutput($list, '@list', self::copy($o)); $this->_addFrameOutput($list, '@list', self::copy($o));
@ -3895,7 +3879,7 @@ class JsonLdProcessor {
$subframe = (property_exists($frame, $prop) ? $subframe = (property_exists($frame, $prop) ?
$frame->{$prop} : $this->_createImplicitFrame($flags)); $frame->{$prop} : $this->_createImplicitFrame($flags));
$this->_matchFrame( $this->_matchFrame(
$state, array($o->{'@id'}), $subframe, $output, $prop); $state, [$o->{'@id'}], $subframe, $output, $prop);
} else { } else {
// include other values automatically // include other values automatically
$this->_addFrameOutput($output, $prop, self::copy($o)); $this->_addFrameOutput($output, $prop, self::copy($o));
@ -3923,7 +3907,7 @@ class JsonLdProcessor {
$preserve = self::copy($next->{'@default'}); $preserve = self::copy($next->{'@default'});
} }
$preserve = self::arrayify($preserve); $preserve = self::arrayify($preserve);
$output->{$prop} = array((object)array('@preserve' => $preserve)); $output->{$prop} = [(object) ['@preserve' => $preserve]];
} }
} }
@ -3945,12 +3929,13 @@ class JsonLdProcessor {
* *
* @return array the implicit frame. * @return array the implicit frame.
*/ */
function _createImplicitFrame($flags) { function _createImplicitFrame($flags)
{
$frame = new stdClass(); $frame = new stdClass();
foreach ($flags as $key => $value) { foreach ($flags as $key => $value) {
$frame->{'@' . $key} = array($flags[$key]); $frame->{'@' . $key} = [$flags[$key]];
} }
return array($frame); return [$frame];
} }
/** /**
@ -3962,7 +3947,8 @@ class JsonLdProcessor {
* *
* @return bool true if a circular reference would be created, false if not. * @return bool true if a circular reference would be created, false if not.
*/ */
function _createsCircularReference($subject_to_embed, $subject_stack) { function _createsCircularReference($subject_to_embed, $subject_stack)
{
for ($i = count($subject_stack) - 1; $i >= 0; --$i) { for ($i = count($subject_stack) - 1; $i >= 0; --$i) {
if ($subject_stack[$i]->{'@id'} === $subject_to_embed->{'@id'}) { if ($subject_stack[$i]->{'@id'} === $subject_to_embed->{'@id'}) {
return true; return true;
@ -3980,7 +3966,8 @@ class JsonLdProcessor {
* *
* @return mixed $the flag value. * @return mixed $the flag value.
*/ */
protected function _getFrameFlag($frame, $options, $name) { protected function _getFrameFlag($frame, $options, $name)
{
$flag = "@$name"; $flag = "@$name";
$rval = (property_exists($frame, $flag) ? $rval = (property_exists($frame, $flag) ?
$frame->{$flag}[0] : $options[$name]); $frame->{$flag}[0] : $options[$name]);
@ -4006,11 +3993,11 @@ class JsonLdProcessor {
* *
* @param array $frame the frame to validate. * @param array $frame the frame to validate.
*/ */
protected function _validateFrame($frame) { protected function _validateFrame($frame)
{
if (!is_array($frame) || count($frame) !== 1 || !is_object($frame[0])) { if (!is_array($frame) || count($frame) !== 1 || !is_object($frame[0])) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; a JSON-LD frame must be a single object.', 'Invalid JSON-LD syntax; a JSON-LD frame must be a single object.', 'jsonld.SyntaxError', null, ['frame' => $frame]);
'jsonld.SyntaxError', null, array('frame' => $frame));
} }
} }
@ -4024,7 +4011,8 @@ class JsonLdProcessor {
* *
* @return stdClass all of the matched subjects. * @return stdClass all of the matched subjects.
*/ */
protected function _filterSubjects($state, $subjects, $frame, $flags) { protected function _filterSubjects($state, $subjects, $frame, $flags)
{
$rval = new stdClass(); $rval = new stdClass();
sort($subjects); sort($subjects);
foreach ($subjects as $id) { foreach ($subjects as $id) {
@ -4045,7 +4033,8 @@ class JsonLdProcessor {
* *
* @return bool true if the subject matches, false if not. * @return bool true if the subject matches, false if not.
*/ */
protected function _filterSubject($subject, $frame, $flags) { protected function _filterSubject($subject, $frame, $flags)
{
// check @type (object value means 'any' type, fall through to ducktyping) // check @type (object value means 'any' type, fall through to ducktyping)
if (property_exists($frame, '@type') && if (property_exists($frame, '@type') &&
!(count($frame->{'@type'}) === 1 && is_object($frame->{'@type'}[0]))) { !(count($frame->{'@type'}) === 1 && is_object($frame->{'@type'}[0]))) {
@ -4109,14 +4098,15 @@ class JsonLdProcessor {
* @param stdClass $state the current framing state. * @param stdClass $state the current framing state.
* @param string $id the @id of the embed to remove. * @param string $id the @id of the embed to remove.
*/ */
protected function _removeEmbed($state, $id) { protected function _removeEmbed($state, $id)
{
// get existing embed // get existing embed
$embeds = $state->uniqueEmbeds; $embeds = $state->uniqueEmbeds;
$embed = $embeds->{$id}; $embed = $embeds->{$id};
$property = $embed['property']; $property = $embed['property'];
// create reference to replace embed // create reference to replace embed
$subject = (object)array('@id' => $id); $subject = (object) ['@id' => $id];
// remove existing embed // remove existing embed
if (is_array($embed->parent)) { if (is_array($embed->parent)) {
@ -4130,10 +4120,8 @@ class JsonLdProcessor {
} else { } else {
// replace subject with reference // replace subject with reference
$use_array = is_array($embed->parent->{$property}); $use_array = is_array($embed->parent->{$property});
self::removeValue($embed->parent, $property, $subject, self::removeValue($embed->parent, $property, $subject, ['propertyIsArray' => $use_array]);
array('propertyIsArray' => $use_array)); self::addValue($embed->parent, $property, $subject, ['propertyIsArray' => $use_array]);
self::addValue($embed->parent, $property, $subject,
array('propertyIsArray' => $use_array));
} }
// recursively remove dependent dangling embeds // recursively remove dependent dangling embeds
@ -4159,10 +4147,11 @@ class JsonLdProcessor {
* @param string $property the parent property. * @param string $property the parent property.
* @param mixed $output the output to add. * @param mixed $output the output to add.
*/ */
protected function _addFrameOutput($parent, $property, $output) { protected function _addFrameOutput($parent, $property, $output)
{
if (is_object($parent) && !($parent instanceof ArrayObject)) { if (is_object($parent) && !($parent instanceof ArrayObject)) {
self::addValue( self::addValue(
$parent, $property, $output, array('propertyIsArray' => true)); $parent, $property, $output, ['propertyIsArray' => true]);
} else { } else {
$parent[] = $output; $parent[] = $output;
} }
@ -4177,10 +4166,11 @@ class JsonLdProcessor {
* *
* @return mixed the resulting output. * @return mixed the resulting output.
*/ */
protected function _removePreserve($ctx, $input, $options) { protected function _removePreserve($ctx, $input, $options)
{
// recurse through arrays // recurse through arrays
if (is_array($input)) { if (is_array($input)) {
$output = array(); $output = [];
foreach ($input as $e) { foreach ($input as $e) {
$result = $this->_removePreserve($ctx, $e, $options); $result = $this->_removePreserve($ctx, $e, $options);
// drop nulls from arrays // drop nulls from arrays
@ -4225,7 +4215,7 @@ class JsonLdProcessor {
} }
} else { } else {
// prevent circular visitation // prevent circular visitation
$options['link'][$id] = array($input); $options['link'][$id] = [$input];
} }
} }
@ -4252,15 +4242,15 @@ class JsonLdProcessor {
* *
* @return true if the triples are the same, false if not. * @return true if the triples are the same, false if not.
*/ */
protected static function _compareRDFTriples($t1, $t2) { protected static function _compareRDFTriples($t1, $t2)
foreach(array('subject', 'predicate', 'object') as $attr) { {
foreach (['subject', 'predicate', 'object'] as $attr) {
if ($t1->{$attr}->type !== $t2->{$attr}->type || if ($t1->{$attr}->type !== $t2->{$attr}->type ||
$t1->{$attr}->value !== $t2->{$attr}->value) { $t1->{$attr}->value !== $t2->{$attr}->value) {
return false; return false;
} }
} }
if(property_exists($t1->object, 'language') !== if (property_exists($t1->object, 'language') !== property_exists($t1->object, 'language')) {
property_exists($t1->object, 'language')) {
return false; return false;
} }
if (property_exists($t1->object, 'language') && if (property_exists($t1->object, 'language') &&
@ -4283,7 +4273,8 @@ class JsonLdProcessor {
* *
* @return string the new hash. * @return string the new hash.
*/ */
protected function _hashQuads($id, $bnodes, $namer) { protected function _hashQuads($id, $bnodes, $namer)
{
// return cached hash // return cached hash
if (property_exists($bnodes->{$id}, 'hash')) { if (property_exists($bnodes->{$id}, 'hash')) {
return $bnodes->{$id}->hash; return $bnodes->{$id}->hash;
@ -4291,7 +4282,7 @@ class JsonLdProcessor {
// serialize all of bnode's quads // serialize all of bnode's quads
$quads = $bnodes->{$id}->quads; $quads = $bnodes->{$id}->quads;
$nquads = array(); $nquads = [];
foreach ($quads as $quad) { foreach ($quads as $quad) {
$nquads[] = $this->toNQuad($quad, property_exists($quad, 'name') ? $nquads[] = $this->toNQuad($quad, property_exists($quad, 'name') ?
$quad->name->value : null, $id); $quad->name->value : null, $id);
@ -4319,7 +4310,8 @@ class JsonLdProcessor {
* *
* @return stdClass the hash and path namer used. * @return stdClass the hash and path namer used.
*/ */
protected function _hashPaths($id, $bnodes, $namer, $path_namer) { protected function _hashPaths($id, $bnodes, $namer, $path_namer)
{
// create SHA-1 digest // create SHA-1 digest
$md = hash_init('sha1'); $md = hash_init('sha1');
@ -4360,7 +4352,7 @@ class JsonLdProcessor {
if (property_exists($groups, $group_hash)) { if (property_exists($groups, $group_hash)) {
$groups->{$group_hash}[] = $bnode; $groups->{$group_hash}[] = $bnode;
} else { } else {
$groups->{$group_hash} = array($bnode); $groups->{$group_hash} = [$bnode];
} }
} }
} }
@ -4383,7 +4375,7 @@ class JsonLdProcessor {
// build adjacent path // build adjacent path
$path = ''; $path = '';
$skipped = false; $skipped = false;
$recurse = array(); $recurse = [];
foreach ($permutation as $bnode) { foreach ($permutation as $bnode) {
// use canonical name if available // use canonical name if available
if ($namer->isNamed($bnode)) { if ($namer->isNamed($bnode)) {
@ -4434,8 +4426,8 @@ class JsonLdProcessor {
} }
// return SHA-1 hash and path namer // return SHA-1 hash and path namer
return (object)array( return (object) [
'hash' => hash_final($md), 'pathNamer' => $path_namer); 'hash' => hash_final($md), 'pathNamer' => $path_namer];
} }
/** /**
@ -4448,7 +4440,8 @@ class JsonLdProcessor {
* *
* @return mixed the adjacent blank node name or null if none was found. * @return mixed the adjacent blank node name or null if none was found.
*/ */
protected function _getAdjacentBlankNodeName($node, $id) { protected function _getAdjacentBlankNodeName($node, $id)
{
if ($node->type === 'blank node' && $node->value !== $id) { if ($node->type === 'blank node' && $node->value !== $id) {
return $node->value; return $node->value;
} }
@ -4463,7 +4456,8 @@ class JsonLdProcessor {
* *
* @return integer -1 if a < b, 1 if a > b, 0 if a == b. * @return integer -1 if a < b, 1 if a > b, 0 if a == b.
*/ */
protected function _compareShortestLeast($a, $b) { protected function _compareShortestLeast($a, $b)
{
$len_a = strlen($a); $len_a = strlen($a);
$len_b = strlen($b); $len_b = strlen($b);
if ($len_a < $len_b) { if ($len_a < $len_b) {
@ -4492,14 +4486,14 @@ class JsonLdProcessor {
* @return mixed the preferred term. * @return mixed the preferred term.
*/ */
protected function _selectTerm( protected function _selectTerm(
$active_ctx, $iri, $value, $containers, $active_ctx, $iri, $value, $containers, $type_or_language, $type_or_language_value)
$type_or_language, $type_or_language_value) { {
if ($type_or_language_value === null) { if ($type_or_language_value === null) {
$type_or_language_value = '@null'; $type_or_language_value = '@null';
} }
// options for the value of @type or @language // options for the value of @type or @language
$prefs = array(); $prefs = [];
// determine prefs for @id based on whether or not value compacts to a term // determine prefs for @id based on whether or not value compacts to a term
if (($type_or_language_value === '@id' || if (($type_or_language_value === '@id' ||
@ -4511,7 +4505,7 @@ class JsonLdProcessor {
} }
// try to compact value to a term // try to compact value to a term
$term = $this->_compactIri( $term = $this->_compactIri(
$active_ctx, $value->{'@id'}, null, array('vocab' => true)); $active_ctx, $value->{'@id'}, null, ['vocab' => true]);
if (property_exists($active_ctx->mappings, $term) && if (property_exists($active_ctx->mappings, $term) &&
$active_ctx->mappings->{$term} && $active_ctx->mappings->{$term} &&
$active_ctx->mappings->{$term}->{'@id'} === $value->{'@id'}) { $active_ctx->mappings->{$term}->{'@id'} === $value->{'@id'}) {
@ -4533,8 +4527,7 @@ class JsonLdProcessor {
continue; continue;
} }
$type_or_language_value_map = $type_or_language_value_map = $container_map->{$container}->{$type_or_language};
$container_map->{$container}->{$type_or_language};
foreach ($prefs as $pref) { foreach ($prefs as $pref) {
// if type/language option not available in the map, continue // if type/language option not available in the map, continue
if (!property_exists($type_or_language_value_map, $pref)) { if (!property_exists($type_or_language_value_map, $pref)) {
@ -4563,7 +4556,8 @@ class JsonLdProcessor {
* @return string the compacted term, prefix, keyword alias, or original IRI. * @return string the compacted term, prefix, keyword alias, or original IRI.
*/ */
protected function _compactIri( protected function _compactIri(
$active_ctx, $iri, $value=null, $relative_to=array(), $reverse=false) { $active_ctx, $iri, $value = null, $relative_to = [], $reverse = false)
{
// can't compact null // can't compact null
if ($iri === null) { if ($iri === null) {
return $iri; return $iri;
@ -4591,7 +4585,7 @@ class JsonLdProcessor {
} }
// prefer @index if available in value // prefer @index if available in value
$containers = array(); $containers = [];
if (is_object($value) && property_exists($value, '@index')) { if (is_object($value) && property_exists($value, '@index')) {
$containers[] = '@index'; $containers[] = '@index';
} }
@ -4677,8 +4671,7 @@ class JsonLdProcessor {
// do term selection // do term selection
$containers[] = '@none'; $containers[] = '@none';
$term = $this->_selectTerm( $term = $this->_selectTerm(
$active_ctx, $iri, $value, $active_ctx, $iri, $value, $containers, $type_or_language, $type_or_language_value);
$containers, $type_or_language, $type_or_language_value);
if ($term !== null) { if ($term !== null) {
return $term; return $term;
} }
@ -4703,7 +4696,7 @@ class JsonLdProcessor {
// no term or @vocab match, check for possible CURIEs // no term or @vocab match, check for possible CURIEs
$choice = null; $choice = null;
$idx = 0; $idx = 0;
$partial_matches = array(); $partial_matches = [];
$iri_map = $active_ctx->fast_curie_map; $iri_map = $active_ctx->fast_curie_map;
// check for partial matches of against `iri`, which means look until // check for partial matches of against `iri`, which means look until
// iri.length - 1, not full length // iri.length - 1, not full length
@ -4764,7 +4757,8 @@ class JsonLdProcessor {
* *
* @return mixed the compaction result. * @return mixed the compaction result.
*/ */
protected function _compactValue($active_ctx, $active_property, $value) { protected function _compactValue($active_ctx, $active_property, $value)
{
// value is a @value // value is a @value
if (self::_isValue($value)) { if (self::_isValue($value)) {
// get context rules // get context rules
@ -4817,11 +4811,10 @@ class JsonLdProcessor {
// compact @type IRI // compact @type IRI
if (property_exists($value, '@type')) { if (property_exists($value, '@type')) {
$rval->{$this->_compactIri($active_ctx, '@type')} = $this->_compactIri( $rval->{$this->_compactIri($active_ctx, '@type')} = $this->_compactIri(
$active_ctx, $value->{'@type'}, null, array('vocab' => true)); $active_ctx, $value->{'@type'}, null, ['vocab' => true]);
} else if (property_exists($value, '@language')) { } else if (property_exists($value, '@language')) {
// alias @language // alias @language
$rval->{$this->_compactIri($active_ctx, '@language')} = $rval->{$this->_compactIri($active_ctx, '@language')} = $value->{'@language'};
$value->{'@language'};
} }
// alias @value // alias @value
@ -4832,11 +4825,10 @@ class JsonLdProcessor {
// value is a subject reference // value is a subject reference
$expanded_property = $this->_expandIri( $expanded_property = $this->_expandIri(
$active_ctx, $active_property, array('vocab' => true)); $active_ctx, $active_property, ['vocab' => true]);
$type = self::getContextValue($active_ctx, $active_property, '@type'); $type = self::getContextValue($active_ctx, $active_property, '@type');
$compacted = $this->_compactIri( $compacted = $this->_compactIri(
$active_ctx, $value->{'@id'}, null, $active_ctx, $value->{'@id'}, null, ['vocab' => ($type === '@vocab')]);
array('vocab' => ($type === '@vocab')));
// compact to scalar // compact to scalar
if ($type === '@id' || $type === '@vocab' || if ($type === '@id' || $type === '@vocab' ||
@ -4844,8 +4836,8 @@ class JsonLdProcessor {
return $compacted; return $compacted;
} }
$rval = (object)array( $rval = (object) [
$this->_compactIri($active_ctx, '@id') => $compacted); $this->_compactIri($active_ctx, '@id') => $compacted];
return $rval; return $rval;
} }
@ -4859,7 +4851,8 @@ class JsonLdProcessor {
* and prevent double definitions. * and prevent double definitions.
*/ */
protected function _createTermDefinition( protected function _createTermDefinition(
$active_ctx, $local_ctx, $term, $defined) { $active_ctx, $local_ctx, $term, $defined)
{
if (property_exists($defined, $term)) { if (property_exists($defined, $term)) {
// term already defined // term already defined
if ($defined->{$term}) { if ($defined->{$term}) {
@ -4867,9 +4860,7 @@ class JsonLdProcessor {
} }
// cycle detected // cycle detected
throw new JsonLdException( throw new JsonLdException(
'Cyclical context definition detected.', 'Cyclical context definition detected.', 'jsonld.CyclicalContext', 'cyclic IRI mapping', ['context' => $local_ctx, 'term' => $term]);
'jsonld.CyclicalContext', 'cyclic IRI mapping',
array('context' => $local_ctx, 'term' => $term));
} }
// now defining term // now defining term
@ -4877,9 +4868,7 @@ class JsonLdProcessor {
if (self::_isKeyword($term)) { if (self::_isKeyword($term)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; keywords cannot be overridden.', 'Invalid JSON-LD syntax; keywords cannot be overridden.', 'jsonld.SyntaxError', 'keyword redefinition', ['context' => $local_ctx, 'term' => $term]);
'jsonld.SyntaxError', 'keyword redefinition',
array('context' => $local_ctx, 'term' => $term));
} }
// remove old mapping // remove old mapping
@ -4900,14 +4889,13 @@ class JsonLdProcessor {
// convert short-hand value to object w/@id // convert short-hand value to object w/@id
if (is_string($value)) { if (is_string($value)) {
$value = (object)array('@id' => $value); $value = (object) ['@id' => $value];
} }
if (!is_object($value)) { if (!is_object($value)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context property values must be ' . 'Invalid JSON-LD syntax; @context property values must be ' .
'strings or objects.', 'jsonld.SyntaxError', 'invalid term definition', 'strings or objects.', 'jsonld.SyntaxError', 'invalid term definition', ['context' => $local_ctx]);
array('context' => $local_ctx));
} }
// create new mapping // create new mapping
@ -4918,27 +4906,21 @@ class JsonLdProcessor {
if (property_exists($value, '@id')) { if (property_exists($value, '@id')) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; a @reverse term definition must not ' + 'Invalid JSON-LD syntax; a @reverse term definition must not ' +
'contain @id.', 'jsonld.SyntaxError', 'invalid reverse property', 'contain @id.', 'jsonld.SyntaxError', 'invalid reverse property', ['context' => $local_ctx]);
array('context' => $local_ctx));
} }
$reverse = $value->{'@reverse'}; $reverse = $value->{'@reverse'};
if (!is_string($reverse)) { if (!is_string($reverse)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; a @context @reverse value must be a string.', 'Invalid JSON-LD syntax; a @context @reverse value must be a string.', 'jsonld.SyntaxError', 'invalid IRI mapping', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid IRI mapping',
array('context' => $local_ctx));
} }
// expand and add @id mapping // expand and add @id mapping
$id = $this->_expandIri( $id = $this->_expandIri(
$active_ctx, $reverse, array('vocab' => true, 'base' => false), $active_ctx, $reverse, ['vocab' => true, 'base' => false], $local_ctx, $defined);
$local_ctx, $defined);
if (!self::_isAbsoluteIri($id)) { if (!self::_isAbsoluteIri($id)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context @reverse value must be ' . 'Invalid JSON-LD syntax; @context @reverse value must be ' .
'an absolute IRI or a blank node identifier.', 'an absolute IRI or a blank node identifier.', 'jsonld.SyntaxError', 'invalid IRI mapping', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid IRI mapping',
array('context' => $local_ctx));
} }
$mapping->{'@id'} = $id; $mapping->{'@id'} = $id;
$mapping->reverse = true; $mapping->reverse = true;
@ -4946,21 +4928,16 @@ class JsonLdProcessor {
$id = $value->{'@id'}; $id = $value->{'@id'};
if (!is_string($id)) { if (!is_string($id)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context @id value must be a string.', 'Invalid JSON-LD syntax; @context @id value must be a string.', 'jsonld.SyntaxError', 'invalid IRI mapping', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid IRI mapping',
array('context' => $local_ctx));
} }
if ($id !== $term) { if ($id !== $term) {
// add @id to mapping // add @id to mapping
$id = $this->_expandIri( $id = $this->_expandIri(
$active_ctx, $id, array('vocab' => true, 'base' => false), $active_ctx, $id, ['vocab' => true, 'base' => false], $local_ctx, $defined);
$local_ctx, $defined);
if (!self::_isAbsoluteIri($id) && !self::_isKeyword($id)) { if (!self::_isAbsoluteIri($id) && !self::_isKeyword($id)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context @id value must be an ' . 'Invalid JSON-LD syntax; @context @id value must be an ' .
'absolute IRI, a blank node identifier, or a keyword.', 'absolute IRI, a blank node identifier, or a keyword.', 'jsonld.SyntaxError', 'invalid IRI mapping', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid IRI mapping',
array('context' => $local_ctx));
} }
$mapping->{'@id'} = $id; $mapping->{'@id'} = $id;
} }
@ -4995,9 +4972,7 @@ class JsonLdProcessor {
// non-IRIs *must* define @ids if @vocab is not available // non-IRIs *must* define @ids if @vocab is not available
if (!property_exists($active_ctx, '@vocab')) { if (!property_exists($active_ctx, '@vocab')) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context terms must define an @id.', 'Invalid JSON-LD syntax; @context terms must define an @id.', 'jsonld.SyntaxError', 'invalid IRI mapping', ['context' => $local_ctx, 'term' => $term]);
'jsonld.SyntaxError', 'invalid IRI mapping',
array('context' => $local_ctx, 'term' => $term));
} }
// prepend vocab to term // prepend vocab to term
$mapping->{'@id'} = $active_ctx->{'@vocab'} . $term; $mapping->{'@id'} = $active_ctx->{'@vocab'} . $term;
@ -5014,27 +4989,22 @@ class JsonLdProcessor {
$type = $value->{'@type'}; $type = $value->{'@type'};
if (!is_string($type)) { if (!is_string($type)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context @type values must be strings.', 'Invalid JSON-LD syntax; @context @type values must be strings.', 'jsonld.SyntaxError', 'invalid type mapping', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid type mapping',
array('context' => $local_ctx));
} }
if ($type !== '@id' && $type !== '@vocab') { if ($type !== '@id' && $type !== '@vocab') {
// expand @type to full IRI // expand @type to full IRI
$type = $this->_expandIri( $type = $this->_expandIri(
$active_ctx, $type, array('vocab' => true), $local_ctx, $defined); $active_ctx, $type, ['vocab' => true], $local_ctx, $defined);
if (!self::_isAbsoluteIri($type)) { if (!self::_isAbsoluteIri($type)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; an @context @type value must ' . 'Invalid JSON-LD syntax; an @context @type value must ' .
'be an absolute IRI.', 'jsonld.SyntaxError', 'be an absolute IRI.', 'jsonld.SyntaxError', 'invalid type mapping', ['context' => $local_ctx]);
'invalid type mapping', array('context' => $local_ctx));
} }
if (strpos($type, '_:') === 0) { if (strpos($type, '_:') === 0) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; an @context @type values must ' . 'Invalid JSON-LD syntax; an @context @type values must ' .
'be an IRI, not a blank node identifier.', 'be an IRI, not a blank node identifier.', 'jsonld.SyntaxError', 'invalid type mapping', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid type mapping',
array('context' => $local_ctx));
} }
} }
@ -5048,17 +5018,13 @@ class JsonLdProcessor {
$container !== '@index' && $container !== '@language') { $container !== '@index' && $container !== '@language') {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context @container value must be ' . 'Invalid JSON-LD syntax; @context @container value must be ' .
'one of the following: @list, @set, @index, or @language.', 'one of the following: @list, @set, @index, or @language.', 'jsonld.SyntaxError', 'invalid container mapping', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid container mapping',
array('context' => $local_ctx));
} }
if ($mapping->reverse && $container !== '@index' && if ($mapping->reverse && $container !== '@index' &&
$container !== '@set' && $container !== null) { $container !== '@set' && $container !== null) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context @container value for a @reverse ' + 'Invalid JSON-LD syntax; @context @container value for a @reverse ' +
'type definition must be @index or @set.', 'type definition must be @index or @set.', 'jsonld.SyntaxError', 'invalid reverse property', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid reverse property',
array('context' => $local_ctx));
} }
// add @container to mapping // add @container to mapping
@ -5071,8 +5037,7 @@ class JsonLdProcessor {
if ($language !== null && !is_string($language)) { if ($language !== null && !is_string($language)) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context @language value must be ' . 'Invalid JSON-LD syntax; @context @language value must be ' .
'a string or null.', 'jsonld.SyntaxError', 'a string or null.', 'jsonld.SyntaxError', 'invalid language mapping', ['context' => $local_ctx]);
'invalid language mapping', array('context' => $local_ctx));
} }
// add @language to mapping // add @language to mapping
@ -5086,9 +5051,7 @@ class JsonLdProcessor {
$id = $mapping->{'@id'}; $id = $mapping->{'@id'};
if ($id === '@context' || $id === '@preserve') { if ($id === '@context' || $id === '@preserve') {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; @context and @preserve cannot be aliased.', 'Invalid JSON-LD syntax; @context and @preserve cannot be aliased.', 'jsonld.SyntaxError', 'invalid keyword alias', ['context' => $local_ctx]);
'jsonld.SyntaxError', 'invalid keyword alias',
array('context' => $local_ctx));
} }
} }
@ -5110,7 +5073,8 @@ class JsonLdProcessor {
* @return mixed the expanded value. * @return mixed the expanded value.
*/ */
function _expandIri( function _expandIri(
$active_ctx, $value, $relative_to=array(), $local_ctx=null, $defined=null) { $active_ctx, $value, $relative_to = [], $local_ctx = null, $defined = null)
{
// already expanded // already expanded
if ($value === null || self::_isKeyword($value)) { if ($value === null || self::_isKeyword($value)) {
return $value; return $value;
@ -5190,7 +5154,8 @@ class JsonLdProcessor {
* the @contexts from the urls map, false not to. * the @contexts from the urls map, false not to.
* @param string $base the base URL to resolve relative URLs with. * @param string $base the base URL to resolve relative URLs with.
*/ */
protected function _findContextUrls($input, $urls, $replace, $base) { protected function _findContextUrls($input, $urls, $replace, $base)
{
if (is_array($input)) { if (is_array($input)) {
foreach ($input as $e) { foreach ($input as $e) {
$this->_findContextUrls($e, $urls, $replace, $base); $this->_findContextUrls($e, $urls, $replace, $base);
@ -5253,12 +5218,11 @@ class JsonLdProcessor {
* @return mixed the result. * @return mixed the result.
*/ */
protected function _retrieveContextUrls( protected function _retrieveContextUrls(
&$input, $cycles, $load_document, $base='') { &$input, $cycles, $load_document, $base = '')
{
if (count(get_object_vars($cycles)) > self::MAX_CONTEXT_URLS) { if (count(get_object_vars($cycles)) > self::MAX_CONTEXT_URLS) {
throw new JsonLdException( throw new JsonLdException(
'Maximum number of @context URLs exceeded.', 'Maximum number of @context URLs exceeded.', 'jsonld.ContextUrlError', 'loading remote context failed', ['max' => self::MAX_CONTEXT_URLS]);
'jsonld.ContextUrlError', 'loading remote context failed',
array('max' => self::MAX_CONTEXT_URLS));
} }
// for tracking the URLs to retrieve // for tracking the URLs to retrieve
@ -5271,14 +5235,13 @@ class JsonLdProcessor {
$this->_findContextUrls($input, $urls, false, $base); $this->_findContextUrls($input, $urls, false, $base);
// queue all unretrieved URLs // queue all unretrieved URLs
$queue = array(); $queue = [];
foreach ($urls as $url => $ctx) { foreach ($urls as $url => $ctx) {
if ($ctx === false) { if ($ctx === false) {
// validate URL // validate URL
if (!preg_match($regex, $url)) { if (!preg_match($regex, $url)) {
throw new JsonLdException( throw new JsonLdException(
'Malformed or unsupported URL.', 'jsonld.InvalidUrl', 'Malformed or unsupported URL.', 'jsonld.InvalidUrl', 'loading remote context failed', ['url' => $url]);
'loading remote context failed', array('url' => $url));
} }
$queue[] = $url; $queue[] = $url;
} }
@ -5289,9 +5252,7 @@ class JsonLdProcessor {
// check for context URL cycle // check for context URL cycle
if (property_exists($cycles, $url)) { if (property_exists($cycles, $url)) {
throw new JsonLdException( throw new JsonLdException(
'Cyclical @context URLs detected.', 'Cyclical @context URLs detected.', 'jsonld.ContextUrlError', 'recursive context inclusion', ['url' => $url]);
'jsonld.ContextUrlError', 'recursive context inclusion',
array('url' => $url));
} }
$_cycles = self::copy($cycles); $_cycles = self::copy($cycles);
$_cycles->{$url} = true; $_cycles->{$url} = true;
@ -5306,24 +5267,21 @@ class JsonLdProcessor {
$ctx = self::_parse_json($ctx); $ctx = self::_parse_json($ctx);
} catch (Exception $e) { } catch (Exception $e) {
throw new JsonLdException( throw new JsonLdException(
'Could not parse JSON from URL.', 'Could not parse JSON from URL.', 'jsonld.ParseError', 'loading remote context failed', ['url' => $url], $e);
'jsonld.ParseError', 'loading remote context failed',
array('url' => $url), $e);
} }
} }
// ensure ctx is an object // ensure ctx is an object
if (!is_object($ctx)) { if (!is_object($ctx)) {
throw new JsonLdException( throw new JsonLdException(
'Derefencing a URL did not result in a valid JSON-LD object.', 'Derefencing a URL did not result in a valid JSON-LD object.', 'jsonld.InvalidUrl', 'invalid remote context', ['url' => $url]);
'jsonld.InvalidUrl', 'invalid remote context', array('url' => $url));
} }
// use empty context if no @context key is present // use empty context if no @context key is present
if (!property_exists($ctx, '@context')) { if (!property_exists($ctx, '@context')) {
$ctx = (object)array('@context' => new stdClass()); $ctx = (object) ['@context' => new stdClass()];
} else { } else {
$ctx = (object)array('@context' => $ctx->{'@context'}); $ctx = (object) ['@context' => $ctx->{'@context'}];
} }
// append context URL to context if given // append context URL to context if given
@ -5349,11 +5307,12 @@ class JsonLdProcessor {
* *
* @return stdClass the initial context. * @return stdClass the initial context.
*/ */
protected function _getInitialContext($options) { protected function _getInitialContext($options)
return (object)array( {
return (object) [
'@base' => jsonld_parse_url($options['base']), '@base' => jsonld_parse_url($options['base']),
'mappings' => new stdClass(), 'mappings' => new stdClass(),
'inverse' => null); 'inverse' => null];
} }
/** /**
@ -5364,7 +5323,8 @@ class JsonLdProcessor {
* *
* @return stdClass the inverse context. * @return stdClass the inverse context.
*/ */
protected function _getInverseContext($active_ctx) { protected function _getInverseContext($active_ctx)
{
// inverse context already generated // inverse context already generated
if ($active_ctx->inverse) { if ($active_ctx->inverse) {
return $active_ctx->inverse; return $active_ctx->inverse;
@ -5374,7 +5334,7 @@ class JsonLdProcessor {
// variables for building fast CURIE map // variables for building fast CURIE map
$fast_curie_map = $active_ctx->fast_curie_map = new ArrayObject(); $fast_curie_map = $active_ctx->fast_curie_map = new ArrayObject();
$iris_to_terms = array(); $iris_to_terms = [];
// handle default language // handle default language
$default_language = '@none'; $default_language = '@none';
@ -5386,7 +5346,7 @@ class JsonLdProcessor {
// shortest and then lexicographically least // shortest and then lexicographically least
$mappings = $active_ctx->mappings; $mappings = $active_ctx->mappings;
$terms = array_keys((array) $mappings); $terms = array_keys((array) $mappings);
usort($terms, array($this, '_compareShortestLeast')); usort($terms, [$this, '_compareShortestLeast']);
foreach ($terms as $term) { foreach ($terms as $term) {
$mapping = $mappings->{$term}; $mapping = $mappings->{$term};
if ($mapping === null) { if ($mapping === null) {
@ -5413,8 +5373,8 @@ class JsonLdProcessor {
// init IRI to term map and fast CURIE map // init IRI to term map and fast CURIE map
$iris_to_terms[$iri] = new ArrayObject(); $iris_to_terms[$iri] = new ArrayObject();
$iris_to_terms[$iri][] = $term; $iris_to_terms[$iri][] = $term;
$fast_curie_entry = (object)array( $fast_curie_entry = (object) [
'iri' => $iri, 'terms' => $iris_to_terms[$iri]); 'iri' => $iri, 'terms' => $iris_to_terms[$iri]];
if (!array_key_exists($iri[0], (array) $fast_curie_map)) { if (!array_key_exists($iri[0], (array) $fast_curie_map)) {
$fast_curie_map[$iri[0]] = new ArrayObject(); $fast_curie_map[$iri[0]] = new ArrayObject();
} }
@ -5428,9 +5388,9 @@ class JsonLdProcessor {
// add new entry // add new entry
if (!property_exists($container_map, $container)) { if (!property_exists($container_map, $container)) {
$container_map->{$container} = (object)array( $container_map->{$container} = (object) [
'@language' => new stdClass(), '@language' => new stdClass(),
'@type' => new stdClass()); '@type' => new stdClass()];
} }
$entry = $container_map->{$container}; $entry = $container_map->{$container};
@ -5482,7 +5442,8 @@ class JsonLdProcessor {
* @param string $key the current key in the map to work on. * @param string $key the current key in the map to work on.
* @param int $idx the index into the IRI to compare. * @param int $idx the index into the IRI to compare.
*/ */
function _buildIriMap($iri_map, $key, $idx) { function _buildIriMap($iri_map, $key, $idx)
{
$entries = $iri_map[$key]; $entries = $iri_map[$key];
$next = $iri_map[$key] = new ArrayObject(); $next = $iri_map[$key] = new ArrayObject();
@ -5516,7 +5477,8 @@ class JsonLdProcessor {
* add to. * add to.
* @param string $type_or_language_value the key in the entry to add to. * @param string $type_or_language_value the key in the entry to add to.
*/ */
function _addPreferredTerm($mapping, $term, $entry, $type_or_language_value) { function _addPreferredTerm($mapping, $term, $entry, $type_or_language_value)
{
if (!property_exists($entry, $type_or_language_value)) { if (!property_exists($entry, $type_or_language_value)) {
$entry->{$type_or_language_value} = $term; $entry->{$type_or_language_value} = $term;
} }
@ -5527,7 +5489,8 @@ class JsonLdProcessor {
* *
* @return stdClass a clone (child) of the active context. * @return stdClass a clone (child) of the active context.
*/ */
protected function _cloneActiveContext($active_ctx) { protected function _cloneActiveContext($active_ctx)
{
$child = new stdClass(); $child = new stdClass();
$child->{'@base'} = $active_ctx->{'@base'}; $child->{'@base'} = $active_ctx->{'@base'};
$child->mappings = self::copy($active_ctx->mappings); $child->mappings = self::copy($active_ctx->mappings);
@ -5548,7 +5511,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value is a keyword, false if not. * @return bool true if the value is a keyword, false if not.
*/ */
protected static function _isKeyword($v) { protected static function _isKeyword($v)
{
if (!is_string($v)) { if (!is_string($v)) {
return false; return false;
} }
@ -5584,7 +5548,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value is an empty Object, false if not. * @return bool true if the value is an empty Object, false if not.
*/ */
protected static function _isEmptyObject($v) { protected static function _isEmptyObject($v)
{
return is_object($v) && count(get_object_vars($v)) === 0; return is_object($v) && count(get_object_vars($v)) === 0;
} }
@ -5593,7 +5558,8 @@ class JsonLdProcessor {
* *
* @param mixed $v the value to check. * @param mixed $v the value to check.
*/ */
protected static function _validateTypeValue($v) { protected static function _validateTypeValue($v)
{
// must be a string or empty object // must be a string or empty object
if (is_string($v) || self::_isEmptyObject($v)) { if (is_string($v) || self::_isEmptyObject($v)) {
return; return;
@ -5615,8 +5581,7 @@ class JsonLdProcessor {
if (!$is_valid) { if (!$is_valid) {
throw new JsonLdException( throw new JsonLdException(
'Invalid JSON-LD syntax; "@type" value must a string, an array ' . 'Invalid JSON-LD syntax; "@type" value must a string, an array ' .
'of strings, or an empty object.', 'of strings, or an empty object.', 'jsonld.SyntaxError', 'invalid type value', ['value' => $v]);
'jsonld.SyntaxError', 'invalid type value', array('value' => $v));
} }
} }
@ -5627,7 +5592,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value is a subject with properties, false if not. * @return bool true if the value is a subject with properties, false if not.
*/ */
protected static function _isSubject($v) { protected static function _isSubject($v)
{
// Note: A value is a subject if all of these hold true: // Note: A value is a subject if all of these hold true:
// 1. It is an Object. // 1. It is an Object.
// 2. It is not a @value, @set, or @list. // 2. It is not a @value, @set, or @list.
@ -5650,7 +5616,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value is a subject reference, false if not. * @return bool true if the value is a subject reference, false if not.
*/ */
protected static function _isSubjectReference($v) { protected static function _isSubjectReference($v)
{
// Note: A value is a subject reference if all of these hold true: // Note: A value is a subject reference if all of these hold true:
// 1. It is an Object. // 1. It is an Object.
// 2. It has a single key: @id. // 2. It has a single key: @id.
@ -5665,7 +5632,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value is a @value, false if not. * @return bool true if the value is a @value, false if not.
*/ */
protected static function _isValue($v) { protected static function _isValue($v)
{
// Note: A value is a @value if all of these hold true: // Note: A value is a @value if all of these hold true:
// 1. It is an Object. // 1. It is an Object.
// 2. It has the @value property. // 2. It has the @value property.
@ -5679,7 +5647,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value is a @list, false if not. * @return bool true if the value is a @list, false if not.
*/ */
protected static function _isList($v) { protected static function _isList($v)
{
// Note: A value is a @list if all of these hold true: // Note: A value is a @list if all of these hold true:
// 1. It is an Object. // 1. It is an Object.
// 2. It has the @list property. // 2. It has the @list property.
@ -5693,7 +5662,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value is a blank node, false if not. * @return bool true if the value is a blank node, false if not.
*/ */
protected static function _isBlankNode($v) { protected static function _isBlankNode($v)
{
// Note: A value is a blank node if all of these hold true: // Note: A value is a blank node if all of these hold true:
// 1. It is an Object. // 1. It is an Object.
// 2. If it has an @id key its value begins with '_:'. // 2. If it has an @id key its value begins with '_:'.
@ -5719,7 +5689,8 @@ class JsonLdProcessor {
* *
* @return bool true if the value is an absolute IRI, false if not. * @return bool true if the value is an absolute IRI, false if not.
*/ */
protected static function _isAbsoluteIri($v) { protected static function _isAbsoluteIri($v)
{
return strpos($v, ':') !== false; return strpos($v, ':') !== false;
} }
@ -5733,7 +5704,8 @@ class JsonLdProcessor {
* *
* @return bool true if the target has the given key and its value matches. * @return bool true if the target has the given key and its value matches.
*/ */
protected static function _hasKeyValue($target, $key, $value) { protected static function _hasKeyValue($target, $key, $value)
{
return (property_exists($target, $key) && $target->{$key} === $value); return (property_exists($target, $key) && $target->{$key} === $value);
} }
@ -5748,7 +5720,8 @@ class JsonLdProcessor {
* @return bool true if both objects have the same value for the key or * @return bool true if both objects have the same value for the key or
* neither has the key. * neither has the key.
*/ */
protected static function _compareKeyValues($o1, $o2, $key) { protected static function _compareKeyValues($o1, $o2, $key)
{
if (property_exists($o1, $key)) { if (property_exists($o1, $key)) {
return property_exists($o2, $key) && $o1->{$key} === $o2->{$key}; return property_exists($o2, $key) && $o1->{$key} === $o2->{$key};
} }
@ -5762,7 +5735,8 @@ class JsonLdProcessor {
* *
* @return mixed the parsed JSON object or array. * @return mixed the parsed JSON object or array.
*/ */
protected static function _parse_json($json) { protected static function _parse_json($json)
{
$rval = json_decode($json); $rval = json_decode($json);
$error = json_last_error(); $error = json_last_error();
if ($error === JSON_ERROR_NONE && $rval === null) { if ($error === JSON_ERROR_NONE && $rval === null) {
@ -5773,47 +5747,48 @@ class JsonLdProcessor {
break; break;
case JSON_ERROR_DEPTH: case JSON_ERROR_DEPTH:
throw new JsonLdException( throw new JsonLdException(
'Could not parse JSON; the maximum stack depth has been exceeded.', 'Could not parse JSON; the maximum stack depth has been exceeded.', 'jsonld.ParseError');
'jsonld.ParseError');
case JSON_ERROR_STATE_MISMATCH: case JSON_ERROR_STATE_MISMATCH:
throw new JsonLdException( throw new JsonLdException(
'Could not parse JSON; invalid or malformed JSON.', 'Could not parse JSON; invalid or malformed JSON.', 'jsonld.ParseError');
'jsonld.ParseError');
case JSON_ERROR_CTRL_CHAR: case JSON_ERROR_CTRL_CHAR:
case JSON_ERROR_SYNTAX: case JSON_ERROR_SYNTAX:
throw new JsonLdException( throw new JsonLdException(
'Could not parse JSON; syntax error, malformed JSON.', 'Could not parse JSON; syntax error, malformed JSON.', 'jsonld.ParseError');
'jsonld.ParseError');
case JSON_ERROR_UTF8: case JSON_ERROR_UTF8:
throw new JsonLdException( throw new JsonLdException(
'Could not parse JSON from URL; malformed UTF-8 characters.', 'Could not parse JSON from URL; malformed UTF-8 characters.', 'jsonld.ParseError');
'jsonld.ParseError');
default: default:
throw new JsonLdException( throw new JsonLdException(
'Could not parse JSON from URL; unknown error.', 'Could not parse JSON from URL; unknown error.', 'jsonld.ParseError');
'jsonld.ParseError');
} }
return $rval; return $rval;
} }
} }
// register the N-Quads RDF parser // register the N-Quads RDF parser
jsonld_register_rdf_parser( jsonld_register_rdf_parser(
'application/nquads', array('JsonLdProcessor', 'parseNQuads')); 'application/nquads', ['JsonLdProcessor', 'parseNQuads']);
/** /**
* A JSON-LD Exception. * A JSON-LD Exception.
*/ */
class JsonLdException extends Exception { class JsonLdException extends Exception
{
public function __construct( public function __construct(
$msg, $type, $code='error', $details=null, $previous=null) { $msg, $type, $code = 'error', $details = null, $previous = null)
{
$this->type = $type; $this->type = $type;
$this->code = $code; $this->code = $code;
$this->details = $details; $this->details = $details;
$this->cause = $previous; $this->cause = $previous;
parent::__construct($msg, 0, $previous); parent::__construct($msg, 0, $previous);
} }
public function __toString() {
public function __toString()
{
$rval = __CLASS__ . ": [{$this->type}]: {$this->message}\n"; $rval = __CLASS__ . ": [{$this->type}]: {$this->message}\n";
if ($this->code) { if ($this->code) {
$rval .= 'Code: ' . $this->code . "\n"; $rval .= 'Code: ' . $this->code . "\n";
@ -5827,29 +5802,36 @@ class JsonLdException extends Exception {
$rval .= $this->getTraceAsString() . "\n"; $rval .= $this->getTraceAsString() . "\n";
return $rval; return $rval;
} }
};
}
;
/** /**
* A UniqueNamer issues unique names, keeping track of any previously issued * A UniqueNamer issues unique names, keeping track of any previously issued
* names. * names.
*/ */
class UniqueNamer { class UniqueNamer
{
/** /**
* Constructs a new UniqueNamer. * Constructs a new UniqueNamer.
* *
* @param prefix the prefix to use ('<prefix><counter>'). * @param prefix the prefix to use ('<prefix><counter>').
*/ */
public function __construct($prefix) { public function __construct($prefix)
{
$this->prefix = $prefix; $this->prefix = $prefix;
$this->counter = 0; $this->counter = 0;
$this->existing = new stdClass(); $this->existing = new stdClass();
$this->order = array(); $this->order = [];
} }
/** /**
* Clones this UniqueNamer. * Clones this UniqueNamer.
*/ */
public function __clone() { public function __clone()
{
$this->existing = clone $this->existing; $this->existing = clone $this->existing;
} }
@ -5861,7 +5843,8 @@ class UniqueNamer {
* *
* @return string the new name. * @return string the new name.
*/ */
public function getName($old_name=null) { public function getName($old_name = null)
{
// return existing old name // return existing old name
if ($old_name && property_exists($this->existing, $old_name)) { if ($old_name && property_exists($this->existing, $old_name)) {
return $this->existing->{$old_name}; return $this->existing->{$old_name};
@ -5887,22 +5870,27 @@ class UniqueNamer {
* *
* @return true if the old name has been assigned a new name, false if not. * @return true if the old name has been assigned a new name, false if not.
*/ */
public function isNamed($old_name) { public function isNamed($old_name)
{
return property_exists($this->existing, $old_name); return property_exists($this->existing, $old_name);
} }
} }
/** /**
* A Permutator iterates over all possible permutations of the given array * A Permutator iterates over all possible permutations of the given array
* of elements. * of elements.
*/ */
class Permutator { class Permutator
{
/** /**
* Constructs a new Permutator. * Constructs a new Permutator.
* *
* @param array $list the array of elements to iterate over. * @param array $list the array of elements to iterate over.
*/ */
public function __construct($list) { public function __construct($list)
{
// original array // original array
$this->list = $list; $this->list = $list;
sort($this->list); sort($this->list);
@ -5920,7 +5908,8 @@ class Permutator {
* *
* @return bool true if there is another permutation, false if not. * @return bool true if there is another permutation, false if not.
*/ */
public function hasNext() { public function hasNext()
{
return !$this->done; return !$this->done;
} }
@ -5930,7 +5919,8 @@ class Permutator {
* *
* @return array the next permutation. * @return array the next permutation.
*/ */
public function next() { public function next()
{
// copy current permutation // copy current permutation
$rval = $this->list; $rval = $this->list;
@ -5972,20 +5962,23 @@ class Permutator {
return $rval; return $rval;
} }
} }
/** /**
* An ActiveContextCache caches active contexts so they can be reused without * An ActiveContextCache caches active contexts so they can be reused without
* the overhead of recomputing them. * the overhead of recomputing them.
*/ */
class ActiveContextCache { class ActiveContextCache
{
/** /**
* Constructs a new ActiveContextCache. * Constructs a new ActiveContextCache.
* *
* @param int size the maximum size of the cache, defaults to 100. * @param int size the maximum size of the cache, defaults to 100.
*/ */
public function __construct($size=100) { public function __construct($size = 100)
$this->order = array(); {
$this->order = [];
$this->cache = new stdClass(); $this->cache = new stdClass();
$this->size = $size; $this->size = $size;
} }
@ -5999,7 +5992,8 @@ class ActiveContextCache {
* *
* @return mixed a shared copy of the cached active context or null. * @return mixed a shared copy of the cached active context or null.
*/ */
public function get($active_ctx, $local_ctx) { public function get($active_ctx, $local_ctx)
{
$key1 = serialize($active_ctx); $key1 = serialize($active_ctx);
$key2 = serialize($local_ctx); $key2 = serialize($local_ctx);
if (property_exists($this->cache, $key1)) { if (property_exists($this->cache, $key1)) {
@ -6008,6 +6002,7 @@ class ActiveContextCache {
return $level1->{$key2}; return $level1->{$key2};
} }
} }
return null; return null;
} }
@ -6019,18 +6014,21 @@ class ActiveContextCache {
* @param stdClass $local_ctx the just-processed local context. * @param stdClass $local_ctx the just-processed local context.
* @param stdClass $result the resulting active context. * @param stdClass $result the resulting active context.
*/ */
public function set($active_ctx, $local_ctx, $result) { public function set($active_ctx, $local_ctx, $result)
{
if (count($this->order) === $this->size) { if (count($this->order) === $this->size) {
$entry = array_shift($this->order); $entry = array_shift($this->order);
unset($this->cache->{$entry->activeCtx}->{$entry->localCtx}); unset($this->cache->{$entry->activeCtx}->{$entry->localCtx});
} }
$key1 = serialize($active_ctx); $key1 = serialize($active_ctx);
$key2 = serialize($local_ctx); $key2 = serialize($local_ctx);
$this->order[] = (object)array( $this->order[] = (object) [
'activeCtx' => $key1, 'localCtx' => $key2); 'activeCtx' => $key1, 'localCtx' => $key2];
if (!property_exists($this->cache, $key1)) { if (!property_exists($this->cache, $key1)) {
$this->cache->{$key1} = new stdClass(); $this->cache->{$key1} = new stdClass();
} }
$this->cache->{$key1}->{$key2} = JsonLdProcessor::copy($result); $this->cache->{$key1}->{$key2} = JsonLdProcessor::copy($result);
} }
} }

348
test.php
View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* PHP unit tests for JSON-LD. * PHP unit tests for JSON-LD.
* *
@ -8,14 +9,16 @@
*/ */
require_once('jsonld.php'); require_once('jsonld.php');
class JsonLdTestCase extends PHPUnit_Framework_TestCase { class JsonLdTestCase extends PHPUnit_Framework_TestCase
{
/** /**
* Runs this test case. Overridden to attach to EARL report w/o need for * Runs this test case. Overridden to attach to EARL report w/o need for
* an external XML configuration file. * an external XML configuration file.
* *
* @param PHPUnit_Framework_TestResult $result the test result. * @param PHPUnit_Framework_TestResult $result the test result.
*/ */
public function run(PHPUnit_Framework_TestResult $result = NULL) { public function run(PHPUnit_Framework_TestResult $result = NULL)
{
global $EARL; global $EARL;
$EARL->attach($result); $EARL->attach($result);
$this->result = $result; $this->result = $result;
@ -31,11 +34,12 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group json-ld.org * @group json-ld.org
* @dataProvider expandProvider * @dataProvider expandProvider
*/ */
public function testExpand($test) { public function testExpand($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readUrl('input'); $input = $test->readUrl('input');
$options = $test->createOptions(); $options = $test->createOptions();
$test->run('jsonld_expand', array($input, $options)); $test->run('jsonld_expand', [$input, $options]);
} }
/** /**
@ -47,12 +51,13 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group json-ld.org * @group json-ld.org
* @dataProvider compactProvider * @dataProvider compactProvider
*/ */
public function testCompact($test) { public function testCompact($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readUrl('input'); $input = $test->readUrl('input');
$context = $test->readProperty('context'); $context = $test->readProperty('context');
$options = $test->createOptions(); $options = $test->createOptions();
$test->run('jsonld_compact', array($input, $context, $options)); $test->run('jsonld_compact', [$input, $context, $options]);
} }
/** /**
@ -64,12 +69,13 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group json-ld.org * @group json-ld.org
* @dataProvider flattenProvider * @dataProvider flattenProvider
*/ */
public function testFlatten($test) { public function testFlatten($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readUrl('input'); $input = $test->readUrl('input');
$context = $test->readProperty('context'); $context = $test->readProperty('context');
$options = $test->createOptions(); $options = $test->createOptions();
$test->run('jsonld_flatten', array($input, $context, $options)); $test->run('jsonld_flatten', [$input, $context, $options]);
} }
/** /**
@ -81,11 +87,12 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group json-ld.org * @group json-ld.org
* @dataProvider toRdfProvider * @dataProvider toRdfProvider
*/ */
public function testToRdf($test) { public function testToRdf($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readUrl('input'); $input = $test->readUrl('input');
$options = $test->createOptions(array('format' => 'application/nquads')); $options = $test->createOptions(['format' => 'application/nquads']);
$test->run('jsonld_to_rdf', array($input, $options)); $test->run('jsonld_to_rdf', [$input, $options]);
} }
/** /**
@ -97,11 +104,12 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group json-ld.org * @group json-ld.org
* @dataProvider fromRdfProvider * @dataProvider fromRdfProvider
*/ */
public function testFromRdf($test) { public function testFromRdf($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readProperty('input'); $input = $test->readProperty('input');
$options = $test->createOptions(array('format' => 'application/nquads')); $options = $test->createOptions(['format' => 'application/nquads']);
$test->run('jsonld_from_rdf', array($input, $options)); $test->run('jsonld_from_rdf', [$input, $options]);
} }
/** /**
@ -113,12 +121,13 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group json-ld.org * @group json-ld.org
* @dataProvider frameProvider * @dataProvider frameProvider
*/ */
public function testFrame($test) { public function testFrame($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readUrl('input'); $input = $test->readUrl('input');
$frame = $test->readProperty('frame'); $frame = $test->readProperty('frame');
$options = $test->createOptions(); $options = $test->createOptions();
$test->run('jsonld_frame', array($input, $frame, $options)); $test->run('jsonld_frame', [$input, $frame, $options]);
} }
/** /**
@ -130,11 +139,12 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group json-ld.org * @group json-ld.org
* @dataProvider normalizeProvider * @dataProvider normalizeProvider
*/ */
public function testNormalize($test) { public function testNormalize($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readUrl('input'); $input = $test->readUrl('input');
$options = $test->createOptions(array('format' => 'application/nquads')); $options = $test->createOptions(['format' => 'application/nquads']);
$test->run('jsonld_normalize', array($input, $options)); $test->run('jsonld_normalize', [$input, $options]);
} }
/** /**
@ -146,14 +156,15 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group normalization * @group normalization
* @dataProvider urgna2012Provider * @dataProvider urgna2012Provider
*/ */
public function testUrgna2012($test) { public function testUrgna2012($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readProperty('action'); $input = $test->readProperty('action');
$options = $test->createOptions(array( $options = $test->createOptions([
'algorithm' => 'URGNA2012', 'algorithm' => 'URGNA2012',
'inputFormat' => 'application/nquads', 'inputFormat' => 'application/nquads',
'format' => 'application/nquads')); 'format' => 'application/nquads']);
$test->run('jsonld_normalize', array($input, $options)); $test->run('jsonld_normalize', [$input, $options]);
} }
/** /**
@ -165,64 +176,76 @@ class JsonLdTestCase extends PHPUnit_Framework_TestCase {
* @group normalization * @group normalization
* @dataProvider urdna2015Provider * @dataProvider urdna2015Provider
*/ */
public function testUrdna2015($test) { public function testUrdna2015($test)
{
$this->test = $test; $this->test = $test;
$input = $test->readProperty('action'); $input = $test->readProperty('action');
$options = $test->createOptions(array( $options = $test->createOptions([
'algorithm' => 'URDNA2015', 'algorithm' => 'URDNA2015',
'inputFormat' => 'application/nquads', 'inputFormat' => 'application/nquads',
'format' => 'application/nquads')); 'format' => 'application/nquads']);
$test->run('jsonld_normalize', array($input, $options)); $test->run('jsonld_normalize', [$input, $options]);
} }
public function expandProvider() { public function expandProvider()
{
return new JsonLdTestIterator('jld:ExpandTest'); return new JsonLdTestIterator('jld:ExpandTest');
} }
public function compactProvider() { public function compactProvider()
{
return new JsonLdTestIterator('jld:CompactTest'); return new JsonLdTestIterator('jld:CompactTest');
} }
public function flattenProvider() { public function flattenProvider()
{
return new JsonLdTestIterator('jld:FlattenTest'); return new JsonLdTestIterator('jld:FlattenTest');
} }
public function toRdfProvider() { public function toRdfProvider()
{
return new JsonLdTestIterator('jld:ToRDFTest'); return new JsonLdTestIterator('jld:ToRDFTest');
} }
public function fromRdfProvider() { public function fromRdfProvider()
{
return new JsonLdTestIterator('jld:FromRDFTest'); return new JsonLdTestIterator('jld:FromRDFTest');
} }
public function normalizeProvider() { public function normalizeProvider()
{
return new JsonLdTestIterator('jld:NormalizeTest'); return new JsonLdTestIterator('jld:NormalizeTest');
} }
public function frameProvider() { public function frameProvider()
{
return new JsonLdTestIterator('jld:FrameTest'); return new JsonLdTestIterator('jld:FrameTest');
} }
public function urgna2012Provider() { public function urgna2012Provider()
{
return new JsonLdTestIterator('rdfn:Urgna2012EvalTest'); return new JsonLdTestIterator('rdfn:Urgna2012EvalTest');
} }
public function urdna2015Provider() { public function urdna2015Provider()
{
return new JsonLdTestIterator('rdfn:Urdna2015EvalTest'); return new JsonLdTestIterator('rdfn:Urdna2015EvalTest');
} }
} }
class JsonLdManifest { class JsonLdManifest
public function __construct($data, $filename) { {
public function __construct($data, $filename)
{
$this->data = $data; $this->data = $data;
$this->filename = $filename; $this->filename = $filename;
$this->dirname = dirname($filename); $this->dirname = dirname($filename);
} }
public function load(&$tests) { public function load(&$tests)
{
$entries = array_merge( $entries = array_merge(
JsonLdProcessor::getValues($this->data, 'sequence'), JsonLdProcessor::getValues($this->data, 'sequence'), JsonLdProcessor::getValues($this->data, 'entries'));
JsonLdProcessor::getValues($this->data, 'entries'));
$includes = JsonLdProcessor::getValues($this->data, 'include'); $includes = JsonLdProcessor::getValues($this->data, 'include');
foreach ($includes as $include) { foreach ($includes as $include) {
array_push($entries, $include . '.jsonld'); array_push($entries, $include . '.jsonld');
@ -230,7 +253,7 @@ class JsonLdManifest {
foreach ($entries as $entry) { foreach ($entries as $entry) {
if (is_string($entry)) { if (is_string($entry)) {
$filename = join( $filename = join(
DIRECTORY_SEPARATOR, array($this->dirname, $entry)); DIRECTORY_SEPARATOR, [$this->dirname, $entry]);
$entry = Util::readJson($filename); $entry = Util::readJson($filename);
} else { } else {
$filename = $this->filename; $filename = $this->filename;
@ -245,11 +268,10 @@ class JsonLdManifest {
// assume entry is a test // assume entry is a test
$test = new JsonLdTest($this, $entry, $filename); $test = new JsonLdTest($this, $entry, $filename);
$types = array_merge( $types = array_merge(
JsonLdProcessor::getValues($test->data, '@type'), JsonLdProcessor::getValues($test->data, '@type'), JsonLdProcessor::getValues($test->data, 'type'));
JsonLdProcessor::getValues($test->data, 'type'));
foreach ($types as $type) { foreach ($types as $type) {
if (!isset($tests[$type])) { if (!isset($tests[$type])) {
$tests[$type] = array(); $tests[$type] = [];
} }
$tests[$type][] = $test; $tests[$type][] = $test;
} }
@ -258,19 +280,19 @@ class JsonLdManifest {
} }
} }
class JsonLdTest { class JsonLdTest
public function __construct($manifest, $data, $filename) { {
public function __construct($manifest, $data, $filename)
{
$this->manifest = $manifest; $this->manifest = $manifest;
$this->data = $data; $this->data = $data;
$this->filename = $filename; $this->filename = $filename;
$this->dirname = dirname($filename); $this->dirname = dirname($filename);
$this->isPositive = $this->isPositive = JsonLdProcessor::hasValue(
JsonLdProcessor::hasValue(
$data, '@type', 'jld:PositiveEvaluationTest') || $data, '@type', 'jld:PositiveEvaluationTest') ||
JsonLdProcessor::hasValue( JsonLdProcessor::hasValue(
$data, 'type', 'jld:PositiveEvaluationTest'); $data, 'type', 'jld:PositiveEvaluationTest');
$this->isNegative = $this->isNegative = JsonLdProcessor::hasValue(
JsonLdProcessor::hasValue(
$data, '@type', 'jld:NegativeEvaluationTest') || $data, '@type', 'jld:NegativeEvaluationTest') ||
JsonLdProcessor::hasValue( JsonLdProcessor::hasValue(
$data, 'type', 'jld:NegativeEvaluationTest'); $data, 'type', 'jld:NegativeEvaluationTest');
@ -306,7 +328,8 @@ class JsonLdTest {
} }
} }
private function _getResultProperty() { private function _getResultProperty()
{
if (isset($this->data->expect)) { if (isset($this->data->expect)) {
return 'expect'; return 'expect';
} else if (isset($this->data->result)) { } else if (isset($this->data->result)) {
@ -316,7 +339,8 @@ class JsonLdTest {
} }
} }
public function run($fn, $params) { public function run($fn, $params)
{
// read expected data // read expected data
if ($this->isNegative) { if ($this->isNegative) {
$this->expected = $this->data->expect; $this->expected = $this->data->expect;
@ -342,61 +366,69 @@ class JsonLdTest {
} }
} }
public function readUrl($property) { public function readUrl($property)
{
if (!property_exists($this->data, $property)) { if (!property_exists($this->data, $property)) {
return null; return null;
} }
return $this->manifest->data->baseIri . $this->data->{$property}; return $this->manifest->data->baseIri . $this->data->{$property};
} }
public function readProperty($property) { public function readProperty($property)
{
$data = $this->data; $data = $this->data;
if (!property_exists($data, $property)) { if (!property_exists($data, $property)) {
return null; return null;
} }
$filename = join( $filename = join(
DIRECTORY_SEPARATOR, array($this->dirname, $data->{$property})); DIRECTORY_SEPARATOR, [$this->dirname, $data->{$property}]);
$extension = pathinfo($filename, PATHINFO_EXTENSION); $extension = pathinfo($filename, PATHINFO_EXTENSION);
if ($extension === 'jsonld') { if ($extension === 'jsonld') {
return Util::readJson($filename); return Util::readJson($filename);
} }
return Util::readFile($filename); return Util::readFile($filename);
} }
public function createOptions($opts=array()) { public function createOptions($opts = [])
$http_options = array( {
'contentType', 'httpLink', 'httpStatus', 'redirectTo'); $http_options = [
'contentType', 'httpLink', 'httpStatus', 'redirectTo'];
$test_options = (property_exists($this->data, 'option') ? $test_options = (property_exists($this->data, 'option') ?
$this->data->option : array()); $this->data->option : []);
$options = array(); $options = [];
foreach ($test_options as $k => $v) { foreach ($test_options as $k => $v) {
if (!in_array($k, $http_options)) { if (!in_array($k, $http_options)) {
$options[$k] = $v; $options[$k] = $v;
} }
} }
$options['documentLoader'] = $this->createDocumentLoader(); $options['documentLoader'] = $this->createDocumentLoader();
$options = array_merge($options, $opts); $options = array_merge($options, $opts);
if (isset($options['expandContext'])) { if (isset($options['expandContext'])) {
$filename = join( $filename = join(
DIRECTORY_SEPARATOR, array($this->dirname, $options['expandContext'])); DIRECTORY_SEPARATOR, [$this->dirname, $options['expandContext']]);
$options['expandContext'] = Util::readJson($filename); $options['expandContext'] = Util::readJson($filename);
} }
return $options; return $options;
} }
public function createDocumentLoader() { public function createDocumentLoader()
{
$base = 'http://json-ld.org/test-suite'; $base = 'http://json-ld.org/test-suite';
$test = $this; $test = $this;
$load_locally = function($url) use ($test, $base) { $load_locally = function($url) use ($test, $base) {
$doc = (object)array( $doc = (object) [
'contextUrl' => null, 'documentUrl' => $url, 'document' => null); 'contextUrl' => null, 'documentUrl' => $url, 'document' => null];
$options = (property_exists($test->data, 'option') ? $options = (property_exists($test->data, 'option') ?
$test->data->option : null); $test->data->option : null);
if ($options and $url === $test->base) { if ($options and $url === $test->base) {
if (property_exists($options, 'redirectTo') && if (property_exists($options, 'redirectTo') &&
property_exists($options, 'httpStatus') && property_exists($options, 'httpStatus') &&
$options->httpStatus >= '300') { $options->httpStatus >= '300'
) {
$doc->documentUrl = ($test->manifest->data->baseIri . $doc->documentUrl = ($test->manifest->data->baseIri .
$options->redirectTo); $options->redirectTo);
} else if (property_exists($options, 'httpLink')) { } else if (property_exists($options, 'httpLink')) {
@ -406,16 +438,19 @@ class JsonLdTest {
if (!$content_type && $extension === 'jsonld') { if (!$content_type && $extension === 'jsonld') {
$content_type = 'application/ld+json'; $content_type = 'application/ld+json';
} }
$link_header = $options->httpLink; $link_header = $options->httpLink;
if (is_array($link_header)) { if (is_array($link_header)) {
$link_header = join(',', $link_header); $link_header = join(',', $link_header);
} }
$link_header = jsonld_parse_link_header($link_header); $link_header = jsonld_parse_link_header($link_header);
if (isset($link_header['http://www.w3.org/ns/json-ld#context'])) { if (isset($link_header['http://www.w3.org/ns/json-ld#context'])) {
$link_header = $link_header['http://www.w3.org/ns/json-ld#context']; $link_header = $link_header['http://www.w3.org/ns/json-ld#context'];
} else { } else {
$link_header = null; $link_header = null;
} }
if ($link_header && $content_type !== 'application/ld+json') { if ($link_header && $content_type !== 'application/ld+json') {
if (is_array($link_header)) { if (is_array($link_header)) {
throw new Exception('multiple context link headers'); throw new Exception('multiple context link headers');
@ -427,19 +462,21 @@ class JsonLdTest {
global $ROOT_MANIFEST_DIR; global $ROOT_MANIFEST_DIR;
if (strpos($doc->documentUrl, ':') === false) { if (strpos($doc->documentUrl, ':') === false) {
$filename = join( $filename = join(
DIRECTORY_SEPARATOR, array( DIRECTORY_SEPARATOR, [
$ROOT_MANIFEST_DIR, $doc->documentUrl)); $ROOT_MANIFEST_DIR, $doc->documentUrl]);
$doc->documentUrl = 'file://' . $filename; $doc->documentUrl = 'file://' . $filename;
} else { } else {
$filename = join( $filename = join(
DIRECTORY_SEPARATOR, array( DIRECTORY_SEPARATOR, [
$ROOT_MANIFEST_DIR, substr($doc->documentUrl, strlen($base)))); $ROOT_MANIFEST_DIR, substr($doc->documentUrl, strlen($base))]);
} }
try { try {
$doc->document = Util::readJson($filename); $doc->document = Util::readJson($filename);
} catch (Exception $e) { } catch (Exception $e) {
throw new Exception('loading document failed'); throw new Exception('loading document failed');
} }
return $doc; return $doc;
}; };
@ -457,20 +494,25 @@ class JsonLdTest {
return $local_loader; return $local_loader;
} }
public function getJsonLdErrorCode($err) { public function getJsonLdErrorCode($err)
{
if ($err instanceof JsonLdException) { if ($err instanceof JsonLdException) {
if ($err->getCode()) { if ($err->getCode()) {
return $err->getCode(); return $err->getCode();
} }
if ($err->cause) { if ($err->cause) {
return $this->getJsonLdErrorCode($err->cause); return $this->getJsonLdErrorCode($err->cause);
} }
} }
return $err->getMessage(); return $err->getMessage();
} }
} }
class JsonLdTestIterator implements Iterator { class JsonLdTestIterator implements Iterator
{
/** /**
* The current test index. * The current test index.
*/ */
@ -486,13 +528,15 @@ class JsonLdTestIterator implements Iterator {
* *
* @param string $type the type of tests to iterate over. * @param string $type the type of tests to iterate over.
*/ */
public function __construct($type) { public function __construct($type)
{
global $TESTS; global $TESTS;
if (isset($TESTS[$type])) { if (isset($TESTS[$type])) {
$this->tests = $TESTS[$type]; $this->tests = $TESTS[$type];
} else { } else {
$this->tests = array(); $this->tests = [];
} }
$this->count = count($this->tests); $this->count = count($this->tests);
} }
@ -501,8 +545,9 @@ class JsonLdTestIterator implements Iterator {
* *
* @return assoc the parameters for the next test. * @return assoc the parameters for the next test.
*/ */
public function current() { public function current()
return array('test' => $this->tests[$this->index]); {
return ['test' => $this->tests[$this->index]];
} }
/** /**
@ -510,21 +555,24 @@ class JsonLdTestIterator implements Iterator {
* *
* @return int the current test number. * @return int the current test number.
*/ */
public function key() { public function key()
{
return $this->index; return $this->index;
} }
/** /**
* Proceeds to the next test. * Proceeds to the next test.
*/ */
public function next() { public function next()
{
$this->index += 1; $this->index += 1;
} }
/** /**
* Rewinds to the first test. * Rewinds to the first test.
*/ */
public function rewind() { public function rewind()
{
$this->index = 0; $this->index = 0;
} }
@ -533,36 +581,38 @@ class JsonLdTestIterator implements Iterator {
* *
* @return bool true if there are more tests to be run. * @return bool true if there are more tests to be run.
*/ */
public function valid() { public function valid()
{
return $this->index < $this->count; return $this->index < $this->count;
} }
} }
class EarlReport extends PHPUnit_Util_Printer class EarlReport extends PHPUnit_Util_Printer implements PHPUnit_Framework_TestListener
implements PHPUnit_Framework_TestListener { {
public function __construct() { public function __construct()
{
$this->filename = null; $this->filename = null;
$this->attached = false; $this->attached = false;
$this->report = (object)array( $this->report = (object) [
'@context' => (object)array( '@context' => (object) [
'doap' => 'http://usefulinc.com/ns/doap#', 'doap' => 'http://usefulinc.com/ns/doap#',
'foaf' => 'http://xmlns.com/foaf/0.1/', 'foaf' => 'http://xmlns.com/foaf/0.1/',
'dc' => 'http://purl.org/dc/terms/', 'dc' => 'http://purl.org/dc/terms/',
'earl' => 'http://www.w3.org/ns/earl#', 'earl' => 'http://www.w3.org/ns/earl#',
'xsd' => 'http://www.w3.org/2001/XMLSchema#', 'xsd' => 'http://www.w3.org/2001/XMLSchema#',
'doap:homepage' => (object)array('@type' => '@id'), 'doap:homepage' => (object) ['@type' => '@id'],
'doap:license' => (object)array('@type' => '@id'), 'doap:license' => (object) ['@type' => '@id'],
'dc:creator' => (object)array('@type' => '@id'), 'dc:creator' => (object) ['@type' => '@id'],
'foaf:homepage' => (object)array('@type' => '@id'), 'foaf:homepage' => (object) ['@type' => '@id'],
'subjectOf' => (object)array('@reverse' => 'earl:subject'), 'subjectOf' => (object) ['@reverse' => 'earl:subject'],
'earl:assertedBy' => (object)array('@type' => '@id'), 'earl:assertedBy' => (object) ['@type' => '@id'],
'earl:mode' => (object)array('@type' => '@id'), 'earl:mode' => (object) ['@type' => '@id'],
'earl:test' => (object)array('@type' => '@id'), 'earl:test' => (object) ['@type' => '@id'],
'earl:outcome' => (object)array('@type' => '@id'), 'earl:outcome' => (object) ['@type' => '@id'],
'dc:date' => (object)array('@type' => 'xsd:date') 'dc:date' => (object) ['@type' => 'xsd:date']
), ],
'@id' => 'https://github.com/digitalbazaar/php-json-ld', '@id' => 'https://github.com/digitalbazaar/php-json-ld',
'@type' => array('doap:Project', 'earl:TestSubject', 'earl:Software'), '@type' => ['doap:Project', 'earl:TestSubject', 'earl:Software'],
'doap:name' => 'php-json-ld', 'doap:name' => 'php-json-ld',
'dc:title' => 'php-json-ld', 'dc:title' => 'php-json-ld',
'doap:homepage' => 'https://github.com/digitalbazaar/php-json-ld', 'doap:homepage' => 'https://github.com/digitalbazaar/php-json-ld',
@ -570,18 +620,18 @@ class EarlReport extends PHPUnit_Util_Printer
'doap:description' => 'A JSON-LD processor for PHP', 'doap:description' => 'A JSON-LD processor for PHP',
'doap:programming-language' => 'PHP', 'doap:programming-language' => 'PHP',
'dc:creator' => 'https://github.com/dlongley', 'dc:creator' => 'https://github.com/dlongley',
'doap:developer' => (object)array( 'doap:developer' => (object) [
'@id' => 'https://github.com/dlongley', '@id' => 'https://github.com/dlongley',
'@type' => array('foaf:Person', 'earl:Assertor'), '@type' => ['foaf:Person', 'earl:Assertor'],
'foaf:name' => 'Dave Longley', 'foaf:name' => 'Dave Longley',
'foaf:homepage' => 'https://github.com/dlongley' 'foaf:homepage' => 'https://github.com/dlongley'
), ],
'dc:date' => array( 'dc:date' => [
'@value' => gmdate('Y-m-d'), '@value' => gmdate('Y-m-d'),
'@type' => 'xsd:date' '@type' => 'xsd:date'
), ],
'subjectOf' => array() 'subjectOf' => []
); ];
} }
/** /**
@ -589,7 +639,8 @@ class EarlReport extends PHPUnit_Util_Printer
* *
* @param PHPUnit_Framework_Test $result the result to attach to. * @param PHPUnit_Framework_Test $result the result to attach to.
*/ */
public function attach(PHPUnit_Framework_TestResult $result) { public function attach(PHPUnit_Framework_TestResult $result)
{
if (!$this->attached && $this->filename) { if (!$this->attached && $this->filename) {
$this->attached = true; $this->attached = true;
$result->addListener($this); $result->addListener($this);
@ -602,25 +653,28 @@ class EarlReport extends PHPUnit_Util_Printer
* @param JsonLdTest $test the JsonLdTest for the assertion is for. * @param JsonLdTest $test the JsonLdTest for the assertion is for.
* @param bool $passed whether or not the test passed. * @param bool $passed whether or not the test passed.
*/ */
public function addAssertion($test, $passed) { public function addAssertion($test, $passed)
$this->report->{'subjectOf'}[] = (object)array( {
$this->report->{'subjectOf'}[] = (object) [
'@type' => 'earl:Assertion', '@type' => 'earl:Assertion',
'earl:assertedBy' => $this->report->{'doap:developer'}->{'@id'}, 'earl:assertedBy' => $this->report->{'doap:developer'}->{'@id'},
'earl:mode' => 'earl:automatic', 'earl:mode' => 'earl:automatic',
'earl:test' => $test->data->{'@id'}, 'earl:test' => $test->data->{'@id'},
'earl:result' => (object)array( 'earl:result' => (object) [
'@type' => 'earl:TestResult', '@type' => 'earl:TestResult',
'dc:date' => gmdate(DateTime::ISO8601), 'dc:date' => gmdate(DateTime::ISO8601),
'earl:outcome' => $passed ? 'earl:passed' : 'earl:failed' 'earl:outcome' => $passed ? 'earl:passed' : 'earl:failed'
) ]
); ];
return $this; return $this;
} }
/** /**
* Writes this EARL report to a file. * Writes this EARL report to a file.
*/ */
public function flush() { public function flush()
{
if ($this->filename) { if ($this->filename) {
printf("\nWriting EARL report to: %s\n", $this->filename); printf("\nWriting EARL report to: %s\n", $this->filename);
$fd = fopen($this->filename, 'w'); $fd = fopen($this->filename, 'w');
@ -629,18 +683,20 @@ class EarlReport extends PHPUnit_Util_Printer
} }
} }
public function endTest(PHPUnit_Framework_Test $test, $time) { public function endTest(PHPUnit_Framework_Test $test, $time)
{
$this->addAssertion($test->test, true); $this->addAssertion($test->test, true);
} }
public function addError( public function addError(
PHPUnit_Framework_Test $test, Exception $e, $time) { PHPUnit_Framework_Test $test, Exception $e, $time)
{
$this->addAssertion($test->test, false); $this->addAssertion($test->test, false);
} }
public function addFailure( public function addFailure(
PHPUnit_Framework_Test $test, PHPUnit_Framework_Test $test, PHPUnit_Framework_AssertionFailedError $e, $time)
PHPUnit_Framework_AssertionFailedError $e, $time) { {
$this->addAssertion($test->test, false); $this->addAssertion($test->test, false);
if ($test->result->shouldStop()) { if ($test->result->shouldStop()) {
if (isset($test->test->name)) { if (isset($test->test->name)) {
@ -659,41 +715,68 @@ class EarlReport extends PHPUnit_Util_Printer
} }
public function addIncompleteTest( public function addIncompleteTest(
PHPUnit_Framework_Test $test, Exception $e, $time) { PHPUnit_Framework_Test $test, Exception $e, $time)
{
$this->addAssertion($test->test, false); $this->addAssertion($test->test, false);
} }
public function addRiskyTest( public function addRiskyTest(
PHPUnit_Framework_Test $test, Exception $e, $time) {} PHPUnit_Framework_Test $test, Exception $e, $time)
public function addSkippedTest( {
PHPUnit_Framework_Test $test, Exception $e, $time) {}
public function startTest(PHPUnit_Framework_Test $test) {}
public function startTestSuite(PHPUnit_Framework_TestSuite $suite) {}
public function endTestSuite(PHPUnit_Framework_TestSuite $suite) {}
} }
class Util { public function addSkippedTest(
public static function readFile($filename) { PHPUnit_Framework_Test $test, Exception $e, $time)
{
}
public function startTest(PHPUnit_Framework_Test $test)
{
}
public function startTestSuite(PHPUnit_Framework_TestSuite $suite)
{
}
public function endTestSuite(PHPUnit_Framework_TestSuite $suite)
{
}
}
class Util
{
public static function readFile($filename)
{
$rval = @file_get_contents($filename); $rval = @file_get_contents($filename);
if ($rval === false) { if ($rval === false) {
throw new Exception('File read error: ' . $filename); throw new Exception('File read error: ' . $filename);
} }
return $rval; return $rval;
} }
public static function readJson($filename) { public static function readJson($filename)
{
$rval = json_decode(self::readFile($filename)); $rval = json_decode(self::readFile($filename));
if ($rval === null) { if ($rval === null) {
throw new Exception('JSON parse error'); throw new Exception('JSON parse error');
} }
return $rval; return $rval;
} }
public static function readNQuads($filename) { public static function readNQuads($filename)
{
return self::readFile($filename); return self::readFile($filename);
} }
public static function jsonldEncode($input) { public static function jsonldEncode($input)
{
// newer PHP has a flag to avoid escaped '/' // newer PHP has a flag to avoid escaped '/'
if (defined('JSON_UNESCAPED_SLASHES')) { if (defined('JSON_UNESCAPED_SLASHES')) {
$options = JSON_UNESCAPED_SLASHES; $options = JSON_UNESCAPED_SLASHES;
@ -705,21 +788,22 @@ class Util {
// use a simple string replacement of '\/' to '/'. // use a simple string replacement of '\/' to '/'.
$json = str_replace('\\/', '/', json_encode($input)); $json = str_replace('\\/', '/', json_encode($input));
} }
return $json; return $json;
} }
} }
// tests to skip // tests to skip
$SKIP_TESTS = array(); $SKIP_TESTS = [];
// root manifest directory // root manifest directory
$ROOT_MANIFEST_DIR; $ROOT_MANIFEST_DIR;
// parsed tests; keyed by type // parsed tests; keyed by type
$TESTS = array(); $TESTS = [];
// parsed command line options // parsed command line options
$OPTIONS = array(); $OPTIONS = [];
// parse command line options // parse command line options
global $argv; global $argv;
@ -740,11 +824,13 @@ for($i = 0; $i < $total; ++$i) {
$i += 1; $i += 1;
$OPTIONS[$arg] = $args[$i]; $OPTIONS[$arg] = $args[$i];
} }
if (!isset($OPTIONS['-d'])) { if (!isset($OPTIONS['-d'])) {
$dvar = 'path to json-ld.org/test-suite'; $dvar = 'path to json-ld.org/test-suite';
$evar = 'file to write EARL report to'; $evar = 'file to write EARL report to';
echo "php-json-ld Tests\n"; echo "php-json-ld Tests\n";
echo "Usage: phpunit test.php -d <$dvar> [-e <$evar>]\n\n"; echo "Usage: phpunit test.php -d <$dvar> [-e <$evar>]\n\n";
exit(0); exit(0);
} }
@ -757,7 +843,7 @@ if(isset($OPTIONS['-e'])) {
// load root manifest // load root manifest
$ROOT_MANIFEST_DIR = realpath($OPTIONS['-d']); $ROOT_MANIFEST_DIR = realpath($OPTIONS['-d']);
$filename = join( $filename = join(
DIRECTORY_SEPARATOR, array($ROOT_MANIFEST_DIR, 'manifest.jsonld')); DIRECTORY_SEPARATOR, [$ROOT_MANIFEST_DIR, 'manifest.jsonld']);
$root_manifest = Util::readJson($filename); $root_manifest = Util::readJson($filename);
$manifest = new JsonLdManifest($root_manifest, $filename); $manifest = new JsonLdManifest($root_manifest, $filename);
$manifest->load($TESTS); $manifest->load($TESTS);