forked from friendica/php-json-ld
Support more error conditions in expand.
This commit is contained in:
parent
12a9ccc9e8
commit
60c335a6e9
1 changed files with 79 additions and 60 deletions
129
jsonld.php
129
jsonld.php
|
@ -2079,6 +2079,9 @@ class JsonLdProcessor {
|
||||||
// recursively expand array
|
// recursively expand array
|
||||||
if(is_array($element)) {
|
if(is_array($element)) {
|
||||||
$rval = array();
|
$rval = array();
|
||||||
|
$container = self::getContextValue(
|
||||||
|
$active_ctx, $active_property, '@container');
|
||||||
|
$inside_list = $inside_list || $container === '@list';
|
||||||
foreach($element as $e) {
|
foreach($element as $e) {
|
||||||
// expand element
|
// expand element
|
||||||
$e = $this->_expand(
|
$e = $this->_expand(
|
||||||
|
@ -2087,10 +2090,10 @@ class JsonLdProcessor {
|
||||||
// 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');
|
'jsonld.SyntaxError', 'list of lists');
|
||||||
}
|
}
|
||||||
// drop null values
|
// drop null values
|
||||||
else if($e !== null) {
|
if($e !== null) {
|
||||||
if(is_array($e)) {
|
if(is_array($e)) {
|
||||||
$rval = array_merge($rval, $e);
|
$rval = array_merge($rval, $e);
|
||||||
}
|
}
|
||||||
|
@ -2103,7 +2106,7 @@ class JsonLdProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!is_object($element)) {
|
if(!is_object($element)) {
|
||||||
// drop top-level 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,
|
||||||
|
@ -2137,14 +2140,6 @@ class JsonLdProcessor {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get term definition for key
|
|
||||||
if(property_exists($active_ctx->mappings, $key)) {
|
|
||||||
$mapping = $active_ctx->mappings->{$key};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$mapping = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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, array('vocab' => true));
|
||||||
|
@ -2156,19 +2151,35 @@ class JsonLdProcessor {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(self::_isKeyword($expanded_property) &&
|
if(self::_isKeyword($expanded_property)) {
|
||||||
$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.',
|
'property.', 'jsonld.SyntaxError', 'invalid reverse property map',
|
||||||
'jsonld.SyntaxError', array('value' => $value));
|
array('value' => $value));
|
||||||
|
}
|
||||||
|
if(property_exists($rval, $expanded_property)) {
|
||||||
|
throw new JsonLdException(
|
||||||
|
'Invalid JSON-LD syntax; colliding keywords detected.',
|
||||||
|
'jsonld.SyntaxError', 'colliding keywords',
|
||||||
|
array('keyword' => $expanded_property));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// syntax error if @id is not a string
|
// syntax error if @id is not a string
|
||||||
if($expanded_property === '@id' && !is_string($value)) {
|
if($expanded_property === '@id' && !is_string($value)) {
|
||||||
|
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', array('value' => $value));
|
'jsonld.SyntaxError', 'invalid @id value',
|
||||||
|
array('value' => $value));
|
||||||
|
}
|
||||||
|
if(!is_object($value)) {
|
||||||
|
throw new JsonLdException(
|
||||||
|
'Invalid JSON-LD syntax; "@id" value must a string or an object.',
|
||||||
|
'jsonld.SyntaxError', 'invalid @id value',
|
||||||
|
array('value' => $value));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate @type value
|
// validate @type value
|
||||||
|
@ -2180,9 +2191,9 @@ class JsonLdProcessor {
|
||||||
if($expanded_property === '@graph' &&
|
if($expanded_property === '@graph' &&
|
||||||
!(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; "@graph" value must not be an ' .
|
||||||
'object or an array.',
|
'object or an array.', 'jsonld.SyntaxError',
|
||||||
'jsonld.SyntaxError', array('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
|
||||||
|
@ -2190,15 +2201,18 @@ 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.',
|
'object or an array.', 'jsonld.SyntaxError',
|
||||||
'jsonld.SyntaxError', array('value' => $value));
|
'invalid value object value', array('value' => $value));
|
||||||
}
|
}
|
||||||
|
|
||||||
// @language must be a string
|
// @language must be a string
|
||||||
if($expanded_property === '@language' && !is_string($value)) {
|
if($expanded_property === '@language') {
|
||||||
|
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', array('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);
|
||||||
}
|
}
|
||||||
|
@ -2208,7 +2222,8 @@ class JsonLdProcessor {
|
||||||
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', array('value' => $value));
|
'jsonld.SyntaxError', 'invalid @index value',
|
||||||
|
array('value' => $value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2217,7 +2232,8 @@ class JsonLdProcessor {
|
||||||
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', 'invalid @reverse value',
|
||||||
|
array('value' => $value));
|
||||||
}
|
}
|
||||||
|
|
||||||
$expanded_value = $this->_expand(
|
$expanded_value = $this->_expand(
|
||||||
|
@ -2253,8 +2269,8 @@ 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.',
|
'@value or an @list.', 'jsonld.SyntaxError',
|
||||||
'jsonld.SyntaxError',
|
'invalid reverse property value',
|
||||||
array('value' => $expanded_value));
|
array('value' => $expanded_value));
|
||||||
}
|
}
|
||||||
self::addValue(
|
self::addValue(
|
||||||
|
@ -2290,7 +2306,7 @@ class JsonLdProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// recurse into @list or @set keeping the active property
|
// recurse into @list or @set
|
||||||
$is_list = ($expanded_property === '@list');
|
$is_list = ($expanded_property === '@list');
|
||||||
if($is_list || $expanded_property === '@set') {
|
if($is_list || $expanded_property === '@set') {
|
||||||
$next_active_property = $active_property;
|
$next_active_property = $active_property;
|
||||||
|
@ -2302,7 +2318,7 @@ class JsonLdProcessor {
|
||||||
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');
|
'jsonld.SyntaxError', 'list of lists');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2336,8 +2352,9 @@ 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.',
|
'@value or an @list.', 'jsonld.SyntaxError',
|
||||||
'jsonld.SyntaxError', array('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,
|
||||||
|
@ -2368,7 +2385,8 @@ class JsonLdProcessor {
|
||||||
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', array('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')) {
|
||||||
|
@ -2385,16 +2403,29 @@ class JsonLdProcessor {
|
||||||
'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', array('element' => $rval));
|
'jsonld.SyntaxError', 'invalid value object',
|
||||||
|
array('element' => $rval));
|
||||||
}
|
}
|
||||||
// drop null @values
|
// drop null @values
|
||||||
if($rval->{'@value'} === null) {
|
if($rval->{'@value'} === null) {
|
||||||
$rval = null;
|
$rval = null;
|
||||||
}
|
}
|
||||||
// drop @language if @value isn't a string
|
// if @language is present, @value must be a string
|
||||||
else if(property_exists($rval, '@language') &&
|
else if(property_exists($rval, '@language') &&
|
||||||
!is_string($rval->{'@value'})) {
|
!is_string($rval->{'@value'})) {
|
||||||
unset($rval->{'@language'});
|
throw new JsonLdException(
|
||||||
|
'Invalid JSON-LD syntax; only strings may be language-tagged.',
|
||||||
|
'jsonld.SyntaxError', 'invalid language-tagged value',
|
||||||
|
array('element' => $rval));
|
||||||
|
}
|
||||||
|
else if(property_exists($rval, '@type') &&
|
||||||
|
!self::_isAbsoluteIri($rval->{'@type'}) ||
|
||||||
|
strpos($rval->{'@type'}, '_:') === 0) {
|
||||||
|
throw new JsonLdException(
|
||||||
|
'Invalid JSON-LD syntax; an element containing "@value" ' .
|
||||||
|
'and "@type" must have an absolute IRI for the value ' .
|
||||||
|
'of "@type".', 'jsonld.SyntaxError', 'invalid typed value',
|
||||||
|
array('element' => $rval));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// convert @type to an array
|
// convert @type to an array
|
||||||
|
@ -2408,8 +2439,8 @@ 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".',
|
'"@index".', 'jsonld.SyntaxError', 'invalid set or list object',
|
||||||
'jsonld.SyntaxError', array('element' => $rval));
|
array('element' => $rval));
|
||||||
}
|
}
|
||||||
// optimize away @set
|
// optimize away @set
|
||||||
if(property_exists($rval, '@set')) {
|
if(property_exists($rval, '@set')) {
|
||||||
|
@ -2427,24 +2458,12 @@ class JsonLdProcessor {
|
||||||
if(is_object($rval) &&
|
if(is_object($rval) &&
|
||||||
!$options['keepFreeFloatingNodes'] && !$inside_list &&
|
!$options['keepFreeFloatingNodes'] && !$inside_list &&
|
||||||
($active_property === null || $expanded_active_property === '@graph')) {
|
($active_property === null || $expanded_active_property === '@graph')) {
|
||||||
// drop empty object or top-level @value
|
// drop empty object or top-level @value/@list, or object with only @id
|
||||||
if($count === 0 || property_exists($rval, '@value')) {
|
if($count === 0 || property_exists($rval, '@value') ||
|
||||||
|
property_exists($rval, '@list') ||
|
||||||
|
($count === 1 && property_exists($rval, '@id'))) {
|
||||||
$rval = null;
|
$rval = null;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// drop subjects that generate no triples
|
|
||||||
$has_triples = false;
|
|
||||||
$ignore = array('@graph', '@type');
|
|
||||||
foreach($keys as $key) {
|
|
||||||
if(!self::_isKeyword($key) || in_array($key, $ignore)) {
|
|
||||||
$has_triples = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!$has_triples) {
|
|
||||||
$rval = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return $rval;
|
return $rval;
|
||||||
|
@ -5430,9 +5449,9 @@ jsonld_register_rdf_parser(
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
|
|
Loading…
Reference in a new issue