forked from friendica/php-json-ld
Remove blank node relabeling from expansion.
This commit is contained in:
parent
d5c0460356
commit
0778e0f7c3
546
jsonld.php
546
jsonld.php
|
@ -1,7 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* PHP implementation of the JSON-LD API.
|
* PHP implementation of the JSON-LD API.
|
||||||
* Version: 0.0.17
|
* Version: 0.0.18
|
||||||
*
|
*
|
||||||
* @author Dave Longley
|
* @author Dave Longley
|
||||||
*
|
*
|
||||||
|
@ -352,26 +352,26 @@ function jsonld_parse_url($url) {
|
||||||
// parse authority for unparsed relative network-path reference
|
// parse authority for unparsed relative network-path reference
|
||||||
if(strpos($rval['href'], ':') === false &&
|
if(strpos($rval['href'], ':') === false &&
|
||||||
strpos($rval['href'], '//') === 0 && $rval['host'] === '') {
|
strpos($rval['href'], '//') === 0 && $rval['host'] === '') {
|
||||||
// must parse authority from pathname
|
// must parse authority from pathname
|
||||||
$rval['path'] = substr($rval['path'], 2);
|
$rval['path'] = substr($rval['path'], 2);
|
||||||
$idx = strpos($rval['path'], '/');
|
$idx = strpos($rval['path'], '/');
|
||||||
if($idx === false) {
|
if($idx === false) {
|
||||||
$rval['authority'] = $rval['path'];
|
$rval['authority'] = $rval['path'];
|
||||||
$rval['path'] = '';
|
$rval['path'] = '';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$rval['authority'] = substr($rval['path'], 0, $idx);
|
$rval['authority'] = substr($rval['path'], 0, $idx);
|
||||||
$rval['path'] = substr($rval['path'], $idx);
|
$rval['path'] = substr($rval['path'], $idx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$rval['authority'] = $rval['host'];
|
$rval['authority'] = $rval['host'];
|
||||||
if(isset($rval['port'])) {
|
if(isset($rval['port'])) {
|
||||||
$rval['authority'] .= ":{$rval['port']}";
|
$rval['authority'] .= ":{$rval['port']}";
|
||||||
}
|
}
|
||||||
if(isset($rval['auth'])) {
|
if(isset($rval['auth'])) {
|
||||||
$rval['authority'] = "{$rval['auth']}@{$rval['authority']}";
|
$rval['authority'] = "{$rval['auth']}@{$rval['authority']}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$rval['normalizedPath'] = jsonld_remove_dot_segments(
|
$rval['normalizedPath'] = jsonld_remove_dot_segments(
|
||||||
$rval['path'], $rval['authority'] !== '');
|
$rval['path'], $rval['authority'] !== '');
|
||||||
|
@ -379,44 +379,44 @@ function jsonld_parse_url($url) {
|
||||||
return $rval;
|
return $rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes dot segments from a URL path.
|
* Removes dot segments from a URL path.
|
||||||
*
|
*
|
||||||
* @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) {
|
||||||
$rval = '/';
|
$rval = '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
// RFC 3986 5.2.4 (reworked)
|
// RFC 3986 5.2.4 (reworked)
|
||||||
$input = explode('/', $path);
|
$input = explode('/', $path);
|
||||||
$output = array();
|
$output = array();
|
||||||
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);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if($input[0] === '..') {
|
if($input[0] === '..') {
|
||||||
array_shift($input);
|
array_shift($input);
|
||||||
if($has_authority ||
|
if($has_authority ||
|
||||||
(count($output) > 0 && $output[count($output) - 1] !== '..')) {
|
(count($output) > 0 && $output[count($output) - 1] !== '..')) {
|
||||||
array_pop($output);
|
array_pop($output);
|
||||||
}
|
}
|
||||||
// leading relative URL '..'
|
// leading relative URL '..'
|
||||||
else {
|
else {
|
||||||
$output[] = '..';
|
$output[] = '..';
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$output[] = array_shift($input);
|
$output[] = array_shift($input);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $rval . implode('/', $output);
|
return $rval . implode('/', $output);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepends a base IRI to the given relative IRI.
|
* Prepends a base IRI to the given relative IRI.
|
||||||
|
@ -548,13 +548,13 @@ function jsonld_remove_base($base, $iri) {
|
||||||
// prepend remaining segments
|
// prepend remaining segments
|
||||||
$rval .= implode('/', $iri_segments);
|
$rval .= implode('/', $iri_segments);
|
||||||
|
|
||||||
// add query and hash
|
// add query and hash
|
||||||
if(isset($rel['query'])) {
|
if(isset($rel['query'])) {
|
||||||
$rval .= "?{$rel['query']}";
|
$rval .= "?{$rel['query']}";
|
||||||
}
|
}
|
||||||
if(isset($rel['fragment'])) {
|
if(isset($rel['fragment'])) {
|
||||||
$rval .= "#{$rel['fragment']}";
|
$rval .= "#{$rel['fragment']}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if($rval === '') {
|
if($rval === '') {
|
||||||
$rval = './';
|
$rval = './';
|
||||||
|
@ -620,8 +620,6 @@ class JsonLdProcessor {
|
||||||
// set default options
|
// set default options
|
||||||
isset($options['base']) or $options['base'] = '';
|
isset($options['base']) or $options['base'] = '';
|
||||||
isset($options['strict']) or $options['strict'] = true;
|
isset($options['strict']) or $options['strict'] = true;
|
||||||
isset($options['renameBlankNodes']) or $options['renameBlankNodes'] =
|
|
||||||
true;
|
|
||||||
isset($options['compactArrays']) or $options['compactArrays'] = true;
|
isset($options['compactArrays']) or $options['compactArrays'] = true;
|
||||||
isset($options['graph']) or $options['graph'] = false;
|
isset($options['graph']) or $options['graph'] = false;
|
||||||
isset($options['skipExpansion']) or $options['skipExpansion'] = false;
|
isset($options['skipExpansion']) or $options['skipExpansion'] = false;
|
||||||
|
@ -735,8 +733,6 @@ class JsonLdProcessor {
|
||||||
* @param mixed $input the JSON-LD object to expand.
|
* @param mixed $input the JSON-LD object to expand.
|
||||||
* @param assoc $options the options to use:
|
* @param assoc $options the options to use:
|
||||||
* [base] the base IRI to use.
|
* [base] the base IRI to use.
|
||||||
* [renameBlankNodes] true to rename blank nodes, false not to,
|
|
||||||
* defaults to true.
|
|
||||||
* [keepFreeFloatingNodes] true to keep free-floating nodes,
|
* [keepFreeFloatingNodes] true to keep free-floating nodes,
|
||||||
* false not to, defaults to false.
|
* false not to, defaults to false.
|
||||||
* [loadContext(url)] the context loader.
|
* [loadContext(url)] the context loader.
|
||||||
|
@ -746,8 +742,6 @@ class JsonLdProcessor {
|
||||||
public function expand($input, $options) {
|
public function expand($input, $options) {
|
||||||
// set default options
|
// set default options
|
||||||
isset($options['base']) or $options['base'] = '';
|
isset($options['base']) or $options['base'] = '';
|
||||||
isset($options['renameBlankNodes']) or $options['renameBlankNodes'] =
|
|
||||||
true;
|
|
||||||
isset($options['keepFreeFloatingNodes']) or
|
isset($options['keepFreeFloatingNodes']) or
|
||||||
$options['keepFreeFloatingNodes'] = false;
|
$options['keepFreeFloatingNodes'] = false;
|
||||||
isset($options['loadContext']) or $options['loadContext'] =
|
isset($options['loadContext']) or $options['loadContext'] =
|
||||||
|
@ -1062,8 +1056,6 @@ class JsonLdProcessor {
|
||||||
* @param stdClass $active_ctx the current active context.
|
* @param stdClass $active_ctx the current active context.
|
||||||
* @param mixed $local_ctx the local context to process.
|
* @param mixed $local_ctx the local context to process.
|
||||||
* @param assoc $options the options to use:
|
* @param assoc $options the options to use:
|
||||||
* [renameBlankNodes] true to rename blank nodes, false not to,
|
|
||||||
* defaults to true.
|
|
||||||
* [loadContext(url)] the context loader.
|
* [loadContext(url)] the context loader.
|
||||||
*
|
*
|
||||||
* @return stdClass the new active context.
|
* @return stdClass the new active context.
|
||||||
|
@ -1071,8 +1063,6 @@ class JsonLdProcessor {
|
||||||
public function processContext($active_ctx, $local_ctx, $options) {
|
public function processContext($active_ctx, $local_ctx, $options) {
|
||||||
// set default options
|
// set default options
|
||||||
isset($options['base']) or $options['base'] = '';
|
isset($options['base']) or $options['base'] = '';
|
||||||
isset($options['renameBlankNodes']) or $options['renameBlankNodes'] =
|
|
||||||
true;
|
|
||||||
isset($options['loadContext']) or $options['loadContext'] =
|
isset($options['loadContext']) or $options['loadContext'] =
|
||||||
'jsonld_get_url';
|
'jsonld_get_url';
|
||||||
|
|
||||||
|
@ -1698,7 +1688,7 @@ class JsonLdProcessor {
|
||||||
return $this->_compactValue($active_ctx, $active_property, $element);
|
return $this->_compactValue($active_ctx, $active_property, $element);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: avoid misuse of active property as an expanded property?
|
// FIXME: avoid misuse of active property as an expanded property?
|
||||||
$inside_reverse = ($active_property === '@reverse');
|
$inside_reverse = ($active_property === '@reverse');
|
||||||
|
|
||||||
// process element keys in order
|
// process element keys in order
|
||||||
|
@ -1735,33 +1725,33 @@ class JsonLdProcessor {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle @reverse
|
// handle @reverse
|
||||||
if($expanded_property === '@reverse') {
|
if($expanded_property === '@reverse') {
|
||||||
// recursively compact expanded value
|
// recursively compact expanded value
|
||||||
$compacted_value = $this->_compact(
|
$compacted_value = $this->_compact(
|
||||||
$active_ctx, '@reverse', $expanded_value, $options);
|
$active_ctx, '@reverse', $expanded_value, $options);
|
||||||
|
|
||||||
// handle double-reversed properties
|
// handle double-reversed properties
|
||||||
foreach($compacted_value as $compacted_property => $value) {
|
foreach($compacted_value as $compacted_property => $value) {
|
||||||
if(property_exists($active_ctx->mappings, $compacted_property) &&
|
if(property_exists($active_ctx->mappings, $compacted_property) &&
|
||||||
$active_ctx->mappings->{$compacted_property} &&
|
$active_ctx->mappings->{$compacted_property} &&
|
||||||
$active_ctx->mappings->{$compacted_property}->reverse) {
|
$active_ctx->mappings->{$compacted_property}->reverse) {
|
||||||
if(!property_exists($rval, $compacted_property) &&
|
if(!property_exists($rval, $compacted_property) &&
|
||||||
!$options['compactArrays']) {
|
!$options['compactArrays']) {
|
||||||
$rval->{$compacted_property} = array();
|
$rval->{$compacted_property} = array();
|
||||||
}
|
}
|
||||||
self::addValue($rval, $compacted_property, $value);
|
self::addValue($rval, $compacted_property, $value);
|
||||||
unset($compacted_value->{$compacted_property});
|
unset($compacted_value->{$compacted_property});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(count(array_keys((array)$compacted_value)) > 0) {
|
if(count(array_keys((array)$compacted_value)) > 0) {
|
||||||
// use keyword alias and add value
|
// use keyword alias and add value
|
||||||
$alias = $this->_compactIri($active_ctx, $expanded_property);
|
$alias = $this->_compactIri($active_ctx, $expanded_property);
|
||||||
self::addValue($rval, $alias, $compacted_value);
|
self::addValue($rval, $alias, $compacted_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle @index property
|
// handle @index property
|
||||||
|
@ -1971,11 +1961,11 @@ class JsonLdProcessor {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self::_isKeyword($expanded_property) &&
|
if(self::_isKeyword($expanded_property) &&
|
||||||
$expanded_active_property === '@reverse') {
|
$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.',
|
'property.',
|
||||||
'jsonld.SyntaxError', array('value' => $value));
|
'jsonld.SyntaxError', array('value' => $value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2027,58 +2017,58 @@ class JsonLdProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @reverse must be an object
|
// @reverse must be an object
|
||||||
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', array('value' => $value));
|
'jsonld.SyntaxError', array('value' => $value));
|
||||||
}
|
}
|
||||||
|
|
||||||
$expanded_value = $this->_expand(
|
$expanded_value = $this->_expand(
|
||||||
$active_ctx, '@reverse', $value, $options, $inside_list);
|
$active_ctx, '@reverse', $value, $options, $inside_list);
|
||||||
|
|
||||||
// properties double-reversed
|
// properties double-reversed
|
||||||
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, array('propertyIsArray' => true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: can this be merged with code below to simplify?
|
// FIXME: can this be merged with code below to simplify?
|
||||||
// merge in all reversed properties
|
// merge in all reversed properties
|
||||||
if(property_exists($rval, '@reverse')) {
|
if(property_exists($rval, '@reverse')) {
|
||||||
$reverse_map = $rval->{'@reverse'};
|
$reverse_map = $rval->{'@reverse'};
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$reverse_map = null;
|
$reverse_map = null;
|
||||||
}
|
}
|
||||||
foreach($expanded_value as $property => $items) {
|
foreach($expanded_value as $property => $items) {
|
||||||
if($property === '@reverse') {
|
if($property === '@reverse') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if($reverse_map === null) {
|
if($reverse_map === null) {
|
||||||
$reverse_map = $rval->{'@reverse'} = new stdClass();
|
$reverse_map = $rval->{'@reverse'} = new stdClass();
|
||||||
}
|
}
|
||||||
self::addValue(
|
self::addValue(
|
||||||
$reverse_map, $property, array(),
|
$reverse_map, $property, array(),
|
||||||
array('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.',
|
'@value or an @list.',
|
||||||
'jsonld.SyntaxError',
|
'jsonld.SyntaxError',
|
||||||
array('value' => $expanded_value));
|
array('value' => $expanded_value));
|
||||||
}
|
}
|
||||||
self::addValue(
|
self::addValue(
|
||||||
$reverse_map, $property, $item,
|
$reverse_map, $property, $item,
|
||||||
array('propertyIsArray' => true));
|
array('propertyIsArray' => true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$container = self::getContextValue($active_ctx, $key, '@container');
|
$container = self::getContextValue($active_ctx, $key, '@container');
|
||||||
|
@ -2146,25 +2136,25 @@ class JsonLdProcessor {
|
||||||
'@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?
|
||||||
// merge in reverse properties
|
// merge in reverse properties
|
||||||
if(property_exists($active_ctx->mappings, $key) &&
|
if(property_exists($active_ctx->mappings, $key) &&
|
||||||
$active_ctx->mappings->{$key} &&
|
$active_ctx->mappings->{$key} &&
|
||||||
$active_ctx->mappings->{$key}->reverse) {
|
$active_ctx->mappings->{$key}->reverse) {
|
||||||
$reverse_map = $rval->{'@reverse'} = new stdClass();
|
$reverse_map = $rval->{'@reverse'} = new stdClass();
|
||||||
$expanded_value = self::arrayify($expanded_value);
|
$expanded_value = self::arrayify($expanded_value);
|
||||||
foreach($expanded_value as $item) {
|
foreach($expanded_value 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.',
|
'@value or an @list.',
|
||||||
'jsonld.SyntaxError', array('value' => $expanded_value));
|
'jsonld.SyntaxError', array('value' => $expanded_value));
|
||||||
}
|
}
|
||||||
self::addValue(
|
self::addValue(
|
||||||
$reverse_map, $expanded_property, $item,
|
$reverse_map, $expanded_property, $item,
|
||||||
array('propertyIsArray' => true));
|
array('propertyIsArray' => true));
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add value for property
|
// add value for property
|
||||||
|
@ -2695,7 +2685,6 @@ class JsonLdProcessor {
|
||||||
if(property_exists($jsonld_cache, 'activeCtx')) {
|
if(property_exists($jsonld_cache, 'activeCtx')) {
|
||||||
$rval = $jsonld_cache->activeCtx->get($active_ctx, $local_ctx);
|
$rval = $jsonld_cache->activeCtx->get($active_ctx, $local_ctx);
|
||||||
if($rval) {
|
if($rval) {
|
||||||
$rval->namer = $active_ctx->namer;
|
|
||||||
return $rval;
|
return $rval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2715,7 +2704,6 @@ class JsonLdProcessor {
|
||||||
// reset to initial context
|
// reset to initial context
|
||||||
if($ctx === null) {
|
if($ctx === null) {
|
||||||
$rval = $this->_getInitialContext($options);
|
$rval = $this->_getInitialContext($options);
|
||||||
$rval->namer = $active_ctx->namer;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2734,26 +2722,26 @@ class JsonLdProcessor {
|
||||||
// define context mappings for keys in local context
|
// define context mappings for keys in local context
|
||||||
$defined = new stdClass();
|
$defined = new stdClass();
|
||||||
|
|
||||||
// handle @base
|
// handle @base
|
||||||
if(property_exists($ctx, '@base')) {
|
if(property_exists($ctx, '@base')) {
|
||||||
$base = $ctx->{'@base'};
|
$base = $ctx->{'@base'};
|
||||||
if($base === null) {
|
if($base === null) {
|
||||||
$base = $options['base'];
|
$base = $options['base'];
|
||||||
}
|
}
|
||||||
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', array('context' => $ctx));
|
'jsonld.SyntaxError', 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', array('context' => $ctx));
|
'jsonld.SyntaxError', array('context' => $ctx));
|
||||||
}
|
}
|
||||||
$rval->{'@base'} = jsonld_parse_url($base);
|
$rval->{'@base'} = jsonld_parse_url($base);
|
||||||
$defined->{'@base'} = true;
|
$defined->{'@base'} = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle @vocab
|
// handle @vocab
|
||||||
|
@ -2933,10 +2921,6 @@ class JsonLdProcessor {
|
||||||
|
|
||||||
// other type
|
// other type
|
||||||
if($type !== null) {
|
if($type !== null) {
|
||||||
// rename blank node if requested
|
|
||||||
if($active_ctx->namer !== null && strpos($type, '_:') === 0) {
|
|
||||||
$type = $active_ctx->namer->getName($type);
|
|
||||||
}
|
|
||||||
$rval->{'@type'} = $type;
|
$rval->{'@type'} = $type;
|
||||||
}
|
}
|
||||||
// check for language tagging for strings
|
// check for language tagging for strings
|
||||||
|
@ -3253,20 +3237,20 @@ class JsonLdProcessor {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle reverse properties
|
// handle reverse properties
|
||||||
if($property === '@reverse') {
|
if($property === '@reverse') {
|
||||||
$referenced_node = (object)array('@id' => $name);
|
$referenced_node = (object)array('@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) {
|
||||||
self::addValue(
|
self::addValue(
|
||||||
$item, $reverse_property, $referenced_node,
|
$item, $reverse_property, $referenced_node,
|
||||||
array('propertyIsArray' => true, 'allowDuplicate' => false));
|
array('propertyIsArray' => true, 'allowDuplicate' => false));
|
||||||
$this->_createNodeMap($item, $graphs, $graph, $namer);
|
$this->_createNodeMap($item, $graphs, $graph, $namer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// recurse into graph
|
// recurse into graph
|
||||||
if($property === '@graph') {
|
if($property === '@graph') {
|
||||||
|
@ -3282,11 +3266,11 @@ class JsonLdProcessor {
|
||||||
|
|
||||||
// copy non-@type keywords
|
// copy non-@type keywords
|
||||||
if($property !== '@type' && self::_isKeyword($property)) {
|
if($property !== '@type' && self::_isKeyword($property)) {
|
||||||
if($property === '@index' && property_exists($subject, '@index')) {
|
if($property === '@index' && property_exists($subject, '@index')) {
|
||||||
throw new JsonLdException(
|
throw new JsonLdException(
|
||||||
'Invalid JSON-LD syntax; conflicting @index property detected.',
|
'Invalid JSON-LD syntax; conflicting @index property detected.',
|
||||||
'jsonld.SyntaxError', array('subject' => $subject));
|
'jsonld.SyntaxError', array('subject' => $subject));
|
||||||
}
|
}
|
||||||
$subject->{$property} = $input->{$property};
|
$subject->{$property} = $input->{$property};
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -4120,10 +4104,10 @@ class JsonLdProcessor {
|
||||||
$type_or_language = '@language';
|
$type_or_language = '@language';
|
||||||
$type_or_language_value = '@null';
|
$type_or_language_value = '@null';
|
||||||
|
|
||||||
if($reverse) {
|
if($reverse) {
|
||||||
$type_or_language = '@type';
|
$type_or_language = '@type';
|
||||||
$type_or_language_value = '@reverse';
|
$type_or_language_value = '@reverse';
|
||||||
$containers[] = '@set';
|
$containers[] = '@set';
|
||||||
}
|
}
|
||||||
// choose the most specific term that works for all elements in @list
|
// choose the most specific term that works for all elements in @list
|
||||||
else if(self::_isList($value)) {
|
else if(self::_isList($value)) {
|
||||||
|
@ -4205,7 +4189,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);
|
||||||
|
@ -4451,28 +4435,28 @@ class JsonLdProcessor {
|
||||||
$mapping = new stdClass();
|
$mapping = new stdClass();
|
||||||
$mapping->reverse = false;
|
$mapping->reverse = false;
|
||||||
|
|
||||||
if(property_exists($value, '@reverse')) {
|
if(property_exists($value, '@reverse')) {
|
||||||
if(property_exists($value, '@id') ||
|
if(property_exists($value, '@id') ||
|
||||||
property_exists($value, '@type') ||
|
property_exists($value, '@type') ||
|
||||||
property_exists($value, '@language')) {
|
property_exists($value, '@language')) {
|
||||||
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, @type, or @language.',
|
'contain @id, @type, or @language.',
|
||||||
'jsonld.SyntaxError', array('context' => $local_ctx));
|
'jsonld.SyntaxError', 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', array('context' => $local_ctx));
|
'jsonld.SyntaxError', array('context' => $local_ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
// expand and add @id mapping, set @type to @id
|
// expand and add @id mapping, set @type to @id
|
||||||
$mapping->{'@id'} = $this->_expandIri(
|
$mapping->{'@id'} = $this->_expandIri(
|
||||||
$active_ctx, $reverse, array('vocab' => true, 'base' => true),
|
$active_ctx, $reverse, array('vocab' => true, 'base' => true),
|
||||||
$local_ctx, $defined);
|
$local_ctx, $defined);
|
||||||
$mapping->{'@type'} = '@id';
|
$mapping->{'@type'} = '@id';
|
||||||
$mapping->reverse = true;
|
$mapping->reverse = true;
|
||||||
}
|
}
|
||||||
else if(property_exists($value, '@id')) {
|
else if(property_exists($value, '@id')) {
|
||||||
$id = $value->{'@id'};
|
$id = $value->{'@id'};
|
||||||
|
@ -4551,11 +4535,11 @@ class JsonLdProcessor {
|
||||||
'one of the following: @list, @set, @index, or @language.',
|
'one of the following: @list, @set, @index, or @language.',
|
||||||
'jsonld.SyntaxError', array('context' => $local_ctx));
|
'jsonld.SyntaxError', array('context' => $local_ctx));
|
||||||
}
|
}
|
||||||
if($mapping->reverse && $container !== '@index') {
|
if($mapping->reverse && $container !== '@index') {
|
||||||
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.',
|
'type definition must be @index.',
|
||||||
'jsonld.SyntaxError', array('context' => $local_ctx));
|
'jsonld.SyntaxError', array('context' => $local_ctx));
|
||||||
}
|
}
|
||||||
|
|
||||||
// add @container to mapping
|
// add @container to mapping
|
||||||
|
@ -4614,8 +4598,6 @@ class JsonLdProcessor {
|
||||||
$this->_createTermDefinition($active_ctx, $local_ctx, $value, $defined);
|
$this->_createTermDefinition($active_ctx, $local_ctx, $value, $defined);
|
||||||
}
|
}
|
||||||
|
|
||||||
$rval = null;
|
|
||||||
|
|
||||||
if(isset($relative_to['vocab']) && $relative_to['vocab']) {
|
if(isset($relative_to['vocab']) && $relative_to['vocab']) {
|
||||||
if(property_exists($active_ctx->mappings, $value)) {
|
if(property_exists($active_ctx->mappings, $value)) {
|
||||||
$mapping = $active_ctx->mappings->{$value};
|
$mapping = $active_ctx->mappings->{$value};
|
||||||
|
@ -4626,55 +4608,44 @@ class JsonLdProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// value is a term
|
// value is a term
|
||||||
$rval = $mapping->{'@id'};
|
return $mapping->{'@id'};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($rval === null) {
|
// split value into prefix:suffix
|
||||||
// split value into prefix:suffix
|
$colon = strpos($value, ':');
|
||||||
$colon = strpos($value, ':');
|
if($colon !== false) {
|
||||||
if($colon !== false) {
|
$prefix = substr($value, 0, $colon);
|
||||||
$prefix = substr($value, 0, $colon);
|
$suffix = substr($value, $colon + 1);
|
||||||
$suffix = substr($value, $colon + 1);
|
|
||||||
|
|
||||||
// do not expand blank nodes (prefix of '_') or already-absolute
|
// do not expand blank nodes (prefix of '_') or already-absolute
|
||||||
// IRIs (suffix of '//')
|
// IRIs (suffix of '//')
|
||||||
if($prefix !== '_' && strpos($suffix, '//') !== 0) {
|
if($prefix !== '_' && strpos($suffix, '//') !== 0) {
|
||||||
// prefix dependency not defined, define it
|
// prefix dependency not defined, define it
|
||||||
if($local_ctx !== null && property_exists($local_ctx, $prefix)) {
|
if($local_ctx !== null && property_exists($local_ctx, $prefix)) {
|
||||||
$this->_createTermDefinition(
|
$this->_createTermDefinition(
|
||||||
$active_ctx, $local_ctx, $prefix, $defined);
|
$active_ctx, $local_ctx, $prefix, $defined);
|
||||||
}
|
}
|
||||||
|
|
||||||
// use mapping if prefix is defined
|
// use mapping if prefix is defined
|
||||||
if(property_exists($active_ctx->mappings, $prefix)) {
|
if(property_exists($active_ctx->mappings, $prefix)) {
|
||||||
$mapping = $active_ctx->mappings->{$prefix};
|
$mapping = $active_ctx->mappings->{$prefix};
|
||||||
if($mapping) {
|
if($mapping) {
|
||||||
$rval = $mapping->{'@id'} . $suffix;
|
return $mapping->{'@id'} . $suffix;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if($rval === null) {
|
// already absolute IRI
|
||||||
$rval = $value;
|
if(self::_isAbsoluteIri($value)) {
|
||||||
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// keywords need no expanding (aliasing already handled by now)
|
$rval = $value;
|
||||||
if(self::_isKeyword($rval)) {
|
|
||||||
return $rval;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(self::_isAbsoluteIri($rval)) {
|
|
||||||
// rename blank node if requested
|
|
||||||
if(!$local_ctx && strpos($rval, '_:') === 0 &&
|
|
||||||
$active_ctx->namer !== null) {
|
|
||||||
$rval = $active_ctx->namer->getName($rval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// prepend vocab
|
// prepend vocab
|
||||||
else if(isset($relative_to['vocab']) && $relative_to['vocab'] &&
|
if(isset($relative_to['vocab']) && $relative_to['vocab'] &&
|
||||||
property_exists($active_ctx, '@vocab')) {
|
property_exists($active_ctx, '@vocab')) {
|
||||||
$rval = $active_ctx->{'@vocab'} . $rval;
|
$rval = $active_ctx->{'@vocab'} . $rval;
|
||||||
}
|
}
|
||||||
|
@ -4869,14 +4840,9 @@ class JsonLdProcessor {
|
||||||
* @return stdClass the initial context.
|
* @return stdClass the initial context.
|
||||||
*/
|
*/
|
||||||
protected function _getInitialContext($options) {
|
protected function _getInitialContext($options) {
|
||||||
$namer = null;
|
|
||||||
if(isset($options['renameBlankNodes']) && $options['renameBlankNodes']) {
|
|
||||||
$namer = new UniqueNamer('_:b');
|
|
||||||
}
|
|
||||||
return (object)array(
|
return (object)array(
|
||||||
'@base' => jsonld_parse_url($options['base']),
|
'@base' => jsonld_parse_url($options['base']),
|
||||||
'mappings' => new stdClass(),
|
'mappings' => new stdClass(),
|
||||||
'namer' => $namer,
|
|
||||||
'inverse' => null);
|
'inverse' => null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4934,37 +4900,37 @@ class JsonLdProcessor {
|
||||||
}
|
}
|
||||||
$entry = $container_map->{$container};
|
$entry = $container_map->{$container};
|
||||||
|
|
||||||
// term is preferred for values using @reverse
|
// term is preferred for values using @reverse
|
||||||
if($mapping->reverse) {
|
if($mapping->reverse) {
|
||||||
$this->_addPreferredTerm(
|
$this->_addPreferredTerm(
|
||||||
$mapping, $term, $entry->{'@type'}, '@reverse');
|
$mapping, $term, $entry->{'@type'}, '@reverse');
|
||||||
}
|
}
|
||||||
// term is preferred for values using specific type
|
// term is preferred for values using specific type
|
||||||
else if(property_exists($mapping, '@type')) {
|
else if(property_exists($mapping, '@type')) {
|
||||||
$this->_addPreferredTerm(
|
$this->_addPreferredTerm(
|
||||||
$mapping, $term, $entry->{'@type'}, $mapping->{'@type'});
|
$mapping, $term, $entry->{'@type'}, $mapping->{'@type'});
|
||||||
}
|
}
|
||||||
// term is preferred for values using specific language
|
// term is preferred for values using specific language
|
||||||
else if(property_exists($mapping, '@language')) {
|
else if(property_exists($mapping, '@language')) {
|
||||||
$language = $mapping->{'@language'};
|
$language = $mapping->{'@language'};
|
||||||
if($language === null) {
|
if($language === null) {
|
||||||
$language = '@null';
|
$language = '@null';
|
||||||
}
|
}
|
||||||
$this->_addPreferredTerm(
|
$this->_addPreferredTerm(
|
||||||
$mapping, $term, $entry->{'@language'}, $language);
|
$mapping, $term, $entry->{'@language'}, $language);
|
||||||
}
|
}
|
||||||
// term is preferred for values w/default language or no type and
|
// term is preferred for values w/default language or no type and
|
||||||
// no language
|
// no language
|
||||||
else {
|
else {
|
||||||
// add an entry for the default language
|
// add an entry for the default language
|
||||||
$this->_addPreferredTerm(
|
$this->_addPreferredTerm(
|
||||||
$mapping, $term, $entry->{'@language'}, $default_language);
|
$mapping, $term, $entry->{'@language'}, $default_language);
|
||||||
|
|
||||||
// add entries for no type and no language
|
// add entries for no type and no language
|
||||||
$this->_addPreferredTerm(
|
$this->_addPreferredTerm(
|
||||||
$mapping, $term, $entry->{'@type'}, '@none');
|
$mapping, $term, $entry->{'@type'}, '@none');
|
||||||
$this->_addPreferredTerm(
|
$this->_addPreferredTerm(
|
||||||
$mapping, $term, $entry->{'@language'}, '@none');
|
$mapping, $term, $entry->{'@language'}, '@none');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4996,7 +4962,6 @@ class JsonLdProcessor {
|
||||||
$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);
|
||||||
$child->namer = $active_ctx->namer;
|
|
||||||
$child->inverse = null;
|
$child->inverse = null;
|
||||||
if(property_exists($active_ctx, '@language')) {
|
if(property_exists($active_ctx, '@language')) {
|
||||||
$child->{'@language'} = $active_ctx->{'@language'};
|
$child->{'@language'} = $active_ctx->{'@language'};
|
||||||
|
@ -5020,9 +4985,6 @@ class JsonLdProcessor {
|
||||||
$rval = new stdClass();
|
$rval = new stdClass();
|
||||||
$rval->{'@base'} = $active_ctx->{'@base'};
|
$rval->{'@base'} = $active_ctx->{'@base'};
|
||||||
$rval->mappings = $active_ctx->mappings;
|
$rval->mappings = $active_ctx->mappings;
|
||||||
if($active_ctx->namer !== null) {
|
|
||||||
$rval->namer = new UniqueNamer('_:b');
|
|
||||||
}
|
|
||||||
$rval->inverse = $active_ctx->inverse;
|
$rval->inverse = $active_ctx->inverse;
|
||||||
if(property_exists($active_ctx, '@language')) {
|
if(property_exists($active_ctx, '@language')) {
|
||||||
$rval->{'@language'} = $active_ctx->{'@language'};
|
$rval->{'@language'} = $active_ctx->{'@language'};
|
||||||
|
|
Loading…
Reference in a new issue