forked from friendica/php-json-ld
Added support for framing defaults and fixed property checks.
This commit is contained in:
parent
4d7d0fa0ae
commit
5d03e650ec
212
jsonld.php
212
jsonld.php
|
@ -182,11 +182,15 @@ function jsonld_merge_contexts($ctx1, $ctx2)
|
|||
}
|
||||
|
||||
// @coerce must be specially-merged, remove from contexts
|
||||
$coerceExists = isset($merged->{'@coerce'}) or isset($copy->{'@coerce'});
|
||||
$coerceExists =
|
||||
property_exists($merged, '@coerce') or
|
||||
property_exists($copy, '@coerce');
|
||||
if($coerceExists)
|
||||
{
|
||||
$c1 = isset($merged->{'@coerce'}) ? $merged->{'@coerce'} : new stdClass();
|
||||
$c2 = isset($copy->{'@coerce'}) ? $copy->{'@coerce'} : new stdClass();
|
||||
$c1 = property_exists($merged, '@coerce') ?
|
||||
$merged->{'@coerce'} : new stdClass();
|
||||
$c2 = property_exists($copy, '@coerce') ?
|
||||
$copy->{'@coerce'} : new stdClass();
|
||||
unset($merged->{'@coerce'});
|
||||
unset($copy->{'@coerce'});
|
||||
}
|
||||
|
@ -203,7 +207,7 @@ function jsonld_merge_contexts($ctx1, $ctx2)
|
|||
foreach($c1 as $type => $p1)
|
||||
{
|
||||
// append existing-type properties that don't already exist
|
||||
if(isset($c2->$type))
|
||||
if(property_exists($c2, $type))
|
||||
{
|
||||
$p2 = $c2->$type;
|
||||
|
||||
|
@ -237,7 +241,7 @@ function jsonld_merge_contexts($ctx1, $ctx2)
|
|||
// add new types from new @coerce
|
||||
foreach($c2 as $type => $value)
|
||||
{
|
||||
if(!isset($c1->$type))
|
||||
if(!property_exists($c1, $type))
|
||||
{
|
||||
$c1->$type = $value;
|
||||
}
|
||||
|
@ -254,7 +258,7 @@ function jsonld_merge_contexts($ctx1, $ctx2)
|
|||
}
|
||||
foreach($p as $v)
|
||||
{
|
||||
if(!isset($unique->$v))
|
||||
if(!property_exists($unique, $v))
|
||||
{
|
||||
$unique->$v = true;
|
||||
}
|
||||
|
@ -327,7 +331,7 @@ function jsonld_frame($input, $frame, $options=null)
|
|||
|
||||
// save frame context
|
||||
$ctx = null;
|
||||
if(isset($frame->{'@context'}))
|
||||
if(property_exists($frame, '@context'))
|
||||
{
|
||||
$ctx = jsonld_merge_contexts(
|
||||
jsonld_create_default_context(), $frame->{'@context'});
|
||||
|
@ -342,6 +346,7 @@ function jsonld_frame($input, $frame, $options=null)
|
|||
$options->defaults = new stdClass();
|
||||
$options->defaults->embedOn = true;
|
||||
$options->defaults->explicitOn = false;
|
||||
$options->defaults->omitDefaultOn = false;
|
||||
|
||||
// build map of all subjects
|
||||
$subjects = new stdClass();
|
||||
|
@ -461,7 +466,7 @@ function _expandTerm($ctx, $term, $usedCtx)
|
|||
$prefix = substr($term, 0, $idx);
|
||||
|
||||
// 1.1. See if the prefix is in the context:
|
||||
if(isset($ctx->$prefix))
|
||||
if(property_exists($ctx, $prefix))
|
||||
{
|
||||
// prefix found, expand property to absolute IRI
|
||||
$rval = $ctx->$prefix . substr($term, $idx + 1);
|
||||
|
@ -477,7 +482,7 @@ function _expandTerm($ctx, $term, $usedCtx)
|
|||
}
|
||||
}
|
||||
// 2. If the property is in the context, then it's a term.
|
||||
else if(isset($ctx->$term))
|
||||
else if(property_exists($ctx, $term))
|
||||
{
|
||||
$rval = $ctx->$term;
|
||||
if($usedCtx !== null)
|
||||
|
@ -518,7 +523,7 @@ function _expandTerm($ctx, $term, $usedCtx)
|
|||
*/
|
||||
function _setProperty($s, $p, $o)
|
||||
{
|
||||
if(isset($s->$p))
|
||||
if(property_exists($s, $p))
|
||||
{
|
||||
if(is_array($s->$p))
|
||||
{
|
||||
|
@ -640,12 +645,12 @@ function _getCoerceType($ctx, $property, $usedCtx)
|
|||
$rval = _expandTerm($ctx, $type, $usedCtx);
|
||||
if($usedCtx !== null)
|
||||
{
|
||||
if(!isset($usedCtx->{'@coerce'}))
|
||||
if(!property_exists($usedCtx, '@coerce'))
|
||||
{
|
||||
$usedCtx->{'@coerce'} = new stdClass();
|
||||
}
|
||||
|
||||
if(!isset($usedCtx->{'@coerce'}->$type))
|
||||
if(!property_exists($usedCtx->{'@coerce'}, $type))
|
||||
{
|
||||
$usedCtx->{'@coerce'}->$type = $p;
|
||||
}
|
||||
|
@ -699,7 +704,7 @@ function _compact($ctx, $property, $value, $usedCtx)
|
|||
// graph literal/disjoint graph
|
||||
else if(
|
||||
is_object($value) and
|
||||
isset($value->{__S}) and is_array($value->{__S}))
|
||||
property_exists($value, __S) and is_array($value->{__S}))
|
||||
{
|
||||
$rval = new stdClass();
|
||||
$rval->{__S} = _compact($ctx, $property, $value->{__S}, $usedCtx);
|
||||
|
@ -707,7 +712,8 @@ function _compact($ctx, $property, $value, $usedCtx)
|
|||
// value has sub-properties if it doesn't define a literal or IRI value
|
||||
else if(
|
||||
is_object($value) and
|
||||
!isset($value->{'@literal'}) and !isset($value->{'@iri'}))
|
||||
!property_exists($value, '@literal') and
|
||||
!property_exists($value, '@iri'))
|
||||
{
|
||||
// recursively handle sub-properties that aren't a sub-context
|
||||
$rval = new stdClass();
|
||||
|
@ -732,15 +738,15 @@ function _compact($ctx, $property, $value, $usedCtx)
|
|||
if(is_object($value))
|
||||
{
|
||||
// type coercion can only occur if language is not specified
|
||||
if(!isset($value->{'@language'}))
|
||||
if(!property_exists($value, '@language'))
|
||||
{
|
||||
// datatype must match coerce type if specified
|
||||
if(isset($value->{'@datatype'}))
|
||||
if(property_exists($value, '@datatype'))
|
||||
{
|
||||
$type = $value->{'@datatype'};
|
||||
}
|
||||
// datatype is IRI
|
||||
else if(isset($value->{'@iri'}))
|
||||
else if(property_exists($value, '@iri'))
|
||||
{
|
||||
$type = JSONLD_XSD_ANY_URI;
|
||||
}
|
||||
|
@ -787,11 +793,11 @@ function _compact($ctx, $property, $value, $usedCtx)
|
|||
{
|
||||
if(is_object($value))
|
||||
{
|
||||
if(isset($value->{'@iri'}))
|
||||
if(property_exists($value, '@iri'))
|
||||
{
|
||||
$rval = $value->{'@iri'};
|
||||
}
|
||||
else if(isset($value->{'@literal'}))
|
||||
else if(property_exists($value, '@literal'))
|
||||
{
|
||||
$rval = $value->{'@literal'};
|
||||
}
|
||||
|
@ -879,10 +885,11 @@ function _expand($ctx, $property, $value, $expandSubjects)
|
|||
else if(is_object($value))
|
||||
{
|
||||
// value has sub-properties if it doesn't define a literal or IRI value
|
||||
if(!(isset($value->{'@literal'}) or isset($value->{'@iri'})))
|
||||
if(!(property_exists($value, '@literal') or
|
||||
property_exists($value, '@iri')))
|
||||
{
|
||||
// if value has a context, use it
|
||||
if(isset($value->{'@context'}))
|
||||
if(property_exists($value, '@context'))
|
||||
{
|
||||
$ctx = jsonld_merge_contexts($ctx, $value->{'@context'});
|
||||
}
|
||||
|
@ -892,7 +899,8 @@ function _expand($ctx, $property, $value, $expandSubjects)
|
|||
foreach($value as $key => $v)
|
||||
{
|
||||
// preserve frame keywords
|
||||
if($key === '@embed' or $key === '@explicit')
|
||||
if($key === '@embed' or $key === '@explicit' or
|
||||
$key === '@default' or $key === '@omitDefault')
|
||||
{
|
||||
_setProperty($rval, $key, _clone($v));
|
||||
}
|
||||
|
@ -981,8 +989,9 @@ function _isNamedBlankNode($v)
|
|||
{
|
||||
// look for "_:" at the beginning of the subject
|
||||
return (
|
||||
is_object($v) and isset($v->{__S}) and
|
||||
isset($v->{__S}->{'@iri'}) and _isBlankNodeIri($v->{__S}->{'@iri'}));
|
||||
is_object($v) and property_exists($v, __S) and
|
||||
property_exists($v->{__S}, '@iri') and
|
||||
_isBlankNodeIri($v->{__S}->{'@iri'}));
|
||||
}
|
||||
|
||||
function _isBlankNode($v)
|
||||
|
@ -990,8 +999,8 @@ function _isBlankNode($v)
|
|||
// look for no subject or named blank node
|
||||
return (
|
||||
is_object($v) and
|
||||
!(isset($v->{'@iri'}) or isset($v->{'@literal'})) and
|
||||
(!isset($v->{__S}) or _isNamedBlankNode($v)));
|
||||
!(property_exists($v, '@iri') or property_exists($v, '@literal')) and
|
||||
(!property_exists($v, __S) or _isNamedBlankNode($v)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1036,9 +1045,9 @@ function _compare($v1, $v2)
|
|||
function _compareObjectKeys($o1, $o2, $key)
|
||||
{
|
||||
$rval = 0;
|
||||
if(isset($o1->$key))
|
||||
if(property_exists($o1, $key))
|
||||
{
|
||||
if(isset($o2->$key))
|
||||
if(property_exists($o2, $key))
|
||||
{
|
||||
$rval = _compare($o1->$key, $o2->$key);
|
||||
}
|
||||
|
@ -1047,7 +1056,7 @@ function _compareObjectKeys($o1, $o2, $key)
|
|||
$rval = -1;
|
||||
}
|
||||
}
|
||||
else if(isset($o2->$key))
|
||||
else if(property_exists($o2, $key))
|
||||
{
|
||||
$rval = 1;
|
||||
}
|
||||
|
@ -1086,7 +1095,7 @@ function _compareObjects($o1, $o2)
|
|||
$rval = _compareObjectKeys($o1, $o2, '@literal');
|
||||
if($rval === 0)
|
||||
{
|
||||
if(isset($o1->{'@literal'}))
|
||||
if(property_exists($o1, '@literal'))
|
||||
{
|
||||
$rval = _compareObjectKeys($o1, $o2, '@datatype');
|
||||
if($rval === 0)
|
||||
|
@ -1115,7 +1124,7 @@ function _compareObjects($o1, $o2)
|
|||
function _filterBlankNodes($e)
|
||||
{
|
||||
return (is_string($e) or
|
||||
!(isset($e->{'@iri'}) and _isBlankNodeIri($e->{'@iri'})));
|
||||
!(property_exists($e, '@iri') and _isBlankNodeIri($e->{'@iri'})));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1242,7 +1251,7 @@ function _collectSubjects($input, $subjects, $bnodes)
|
|||
}
|
||||
else if(is_object($input))
|
||||
{
|
||||
if(isset($input->{__S}))
|
||||
if(property_exists($input, __S))
|
||||
{
|
||||
// graph literal
|
||||
if(is_array($input->{__S}))
|
||||
|
@ -1281,7 +1290,7 @@ class DuplicateIriFilter
|
|||
|
||||
public function filter($e)
|
||||
{
|
||||
return (is_object($e) and isset($e->{'@iri'}) and
|
||||
return (is_object($e) and property_exists($e, '@iri') and
|
||||
$e->{'@iri'} === $this->iri);
|
||||
}
|
||||
}
|
||||
|
@ -1311,7 +1320,7 @@ function _flatten($parent, $parentProperty, $value, $subjects)
|
|||
else if(is_object($value))
|
||||
{
|
||||
// graph literal/disjoint graph
|
||||
if(isset($value->{__S}) and is_array($value->{__S}))
|
||||
if(property_exists($value, __S) and is_array($value->{__S}))
|
||||
{
|
||||
// cannot flatten embedded graph literals
|
||||
if($parent !== null)
|
||||
|
@ -1326,7 +1335,9 @@ function _flatten($parent, $parentProperty, $value, $subjects)
|
|||
}
|
||||
}
|
||||
// already-expanded value
|
||||
else if(isset($value->{'@literal'}) or isset($value->{'@iri'}))
|
||||
else if(
|
||||
property_exists($value, '@literal') or
|
||||
property_exists($value, '@iri'))
|
||||
{
|
||||
$flattened = _clone($value);
|
||||
}
|
||||
|
@ -1334,7 +1345,7 @@ function _flatten($parent, $parentProperty, $value, $subjects)
|
|||
else
|
||||
{
|
||||
// create or fetch existing subject
|
||||
if(isset($subjects->{$value->{__S}->{'@iri'}}))
|
||||
if(property_exists($subjects, $value->{__S}->{'@iri'}))
|
||||
{
|
||||
// FIXME: __S might be a graph literal (as {})
|
||||
$subject = $subjects->{$value->{__S}->{'@iri'}};
|
||||
|
@ -1342,7 +1353,7 @@ function _flatten($parent, $parentProperty, $value, $subjects)
|
|||
else
|
||||
{
|
||||
$subject = new stdClass();
|
||||
if(isset($value->{__S}))
|
||||
if(property_exists($value, __S))
|
||||
{
|
||||
// FIXME: __S might be a graph literal (as {})
|
||||
$subjects->{$value->{__S}->{'@iri'}} = $subject;
|
||||
|
@ -1389,7 +1400,7 @@ function _flatten($parent, $parentProperty, $value, $subjects)
|
|||
// 'http://mypredicate': {'@subject': {'@iri': 'http://mysubject'}}
|
||||
// becomes
|
||||
// 'http://mypredicate': {'@iri': 'http://mysubject'}
|
||||
if(is_object($flattened) and isset($flattened->{__S}))
|
||||
if(is_object($flattened) and property_exists($flattened, __S))
|
||||
{
|
||||
$flattened = $flattened->{__S};
|
||||
}
|
||||
|
@ -1398,7 +1409,7 @@ function _flatten($parent, $parentProperty, $value, $subjects)
|
|||
{
|
||||
// do not add duplicate IRIs for the same property
|
||||
$duplicate = false;
|
||||
if(is_object($flattened) and isset($flattened->{'@iri'}))
|
||||
if(is_object($flattened) and property_exists($flattened, '@iri'))
|
||||
{
|
||||
$duplicate = count(array_filter(
|
||||
(array)$parent, array(
|
||||
|
@ -1460,7 +1471,7 @@ class MappingBuilder
|
|||
*/
|
||||
public function mapNode($iri)
|
||||
{
|
||||
if(!isset($this->mapping->$iri))
|
||||
if(!property_exists($this->mapping, $iri))
|
||||
{
|
||||
if(strpos($iri, '_:c14n') === 0)
|
||||
{
|
||||
|
@ -1640,10 +1651,10 @@ class JsonLdProcessor
|
|||
// uniquely name all unnamed bnodes
|
||||
foreach($bnodes as $i => $bnode)
|
||||
{
|
||||
if(!isset($bnode->{__S}))
|
||||
if(!property_exists($bnode, __S))
|
||||
{
|
||||
// generate names until one is unique
|
||||
while(isset($subjects->{$ng->next()}));
|
||||
while(property_exists($subjects, $ng->next()));
|
||||
$bnode->{__S} = new stdClass();
|
||||
$bnode->{__S}->{'@iri'} = $ng->current();
|
||||
$subjects->{$ng->current()} = $bnode;
|
||||
|
@ -1701,7 +1712,8 @@ class JsonLdProcessor
|
|||
for($n = 0; $n < $length; ++$n)
|
||||
{
|
||||
if(is_object($tmp[$n]) and
|
||||
isset($tmp[$n]->{'@iri'}) and $tmp[$n]->{'@iri'} === $old)
|
||||
property_exists($tmp[$n], '@iri') and
|
||||
$tmp[$n]->{'@iri'} === $old)
|
||||
{
|
||||
$tmp[$n]->{'@iri'} = $id;
|
||||
}
|
||||
|
@ -1775,7 +1787,7 @@ class JsonLdProcessor
|
|||
if($c14n->inNamespace($iri))
|
||||
{
|
||||
// generate names until one is unique
|
||||
while(isset($subjects->{$ngTmp->next()}));
|
||||
while(property_exists($subjects, $ngTmp->next()));
|
||||
$this->renameBlankNode($bnode, $ngTmp->current());
|
||||
$iri = $bnode->{__S}->{'@iri'};
|
||||
}
|
||||
|
@ -1814,7 +1826,8 @@ class JsonLdProcessor
|
|||
$renamed = array();
|
||||
foreach($keys as $i => $iriK)
|
||||
{
|
||||
if(!$c14n->inNamespace($iri) and isset($subjects->$iriK))
|
||||
if(!$c14n->inNamespace($iri) and
|
||||
property_exists($subjects, $iriK))
|
||||
{
|
||||
$this->renameBlankNode($subjects->$iriK, $c14n->next());
|
||||
$renamed[] = $iriK;
|
||||
|
@ -1868,7 +1881,7 @@ class JsonLdProcessor
|
|||
public function markSerializationDirty($iri, $changed, $dir)
|
||||
{
|
||||
$s = $this->serializations->$iri;
|
||||
if($s->$dir !== null and isset($s->$dir->m->$changed))
|
||||
if($s->$dir !== null and property_exists($s->$dir->m, $changed))
|
||||
{
|
||||
$s->$dir = null;
|
||||
}
|
||||
|
@ -1902,7 +1915,7 @@ class JsonLdProcessor
|
|||
{
|
||||
$rval .= '|';
|
||||
}
|
||||
if(is_object($obj) and isset($obj->{'@iri'}) and
|
||||
if(is_object($obj) and property_exists($obj, '@iri') and
|
||||
_isBlankNodeIri($obj->{'@iri'}))
|
||||
{
|
||||
$rval .= '_:';
|
||||
|
@ -1932,12 +1945,12 @@ class JsonLdProcessor
|
|||
$rval = '';
|
||||
foreach($keys as $k)
|
||||
{
|
||||
if(!isset($output->$k))
|
||||
if(!property_exists($output, $k))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(isset($done->$k))
|
||||
if(property_exists($done, $k))
|
||||
{
|
||||
// mark cycle
|
||||
$rval .= '_' . $k;
|
||||
|
@ -1950,7 +1963,7 @@ class JsonLdProcessor
|
|||
{
|
||||
$rval .= $s;
|
||||
$iri = $tmp->m->$s;
|
||||
if(isset($this->subjects->$iri))
|
||||
if(property_exists($this->subjects, $iri))
|
||||
{
|
||||
$b = $this->subjects->$iri;
|
||||
|
||||
|
@ -2084,7 +2097,7 @@ class JsonLdProcessor
|
|||
public function serializeBlankNode($s, $iri, $mb, $dir)
|
||||
{
|
||||
// only do mapping if iri not already mapped
|
||||
if(!isset($mb->mapped->$iri))
|
||||
if(!property_exists($mb->mapped, $iri))
|
||||
{
|
||||
// iri now mapped
|
||||
$mb->mapped->$iri = true;
|
||||
|
@ -2099,7 +2112,7 @@ class JsonLdProcessor
|
|||
$notMapped = array();
|
||||
foreach($adjs as $adj)
|
||||
{
|
||||
if(isset($mb->mapping->{$adj->s}))
|
||||
if(property_exists($mb->mapping, $adj->s))
|
||||
{
|
||||
$mapped->{$mb->mapping->{$adj->s}} = $adj->s;
|
||||
}
|
||||
|
@ -2112,7 +2125,7 @@ class JsonLdProcessor
|
|||
// TODO: ensure this optimization does not alter canonical order
|
||||
|
||||
// if the current bnode already has a serialization, reuse it
|
||||
/*$hint = isset($this->serializations->$iri) ?
|
||||
/*$hint = property_exists($this->serializations, $iri) ?
|
||||
$this->serializations->$iri->$dir : null;
|
||||
if($hint !== null)
|
||||
{
|
||||
|
@ -2350,8 +2363,8 @@ class JsonLdProcessor
|
|||
$tmp = !is_array($object) ? array($object) : $object;
|
||||
foreach($tmp as $o)
|
||||
{
|
||||
if(is_object($o) and isset($o->{'@iri'}) and
|
||||
isset($this->subjects->{$o->{'@iri'}}))
|
||||
if(is_object($o) and property_exists($o, '@iri') and
|
||||
property_exists($this->subjects, $o->{'@iri'}))
|
||||
{
|
||||
$objIri = $o->{'@iri'};
|
||||
|
||||
|
@ -2401,9 +2414,9 @@ function _isType($input, $frame)
|
|||
|
||||
// check if type(s) are specified in frame and input
|
||||
$type = JSONLD_RDF_TYPE;
|
||||
if(isset($frame->{JSONLD_RDF_TYPE}) and
|
||||
is_object($input) and isset($input->{__S}) and
|
||||
isset($input->{JSONLD_RDF_TYPE}))
|
||||
if(property_exists($frame, JSONLD_RDF_TYPE) and
|
||||
is_object($input) and property_exists($input, __S) and
|
||||
property_exists($input, JSONLD_RDF_TYPE))
|
||||
{
|
||||
$tmp = is_array($input->{JSONLD_RDF_TYPE}) ?
|
||||
$input->{JSONLD_RDF_TYPE} : array($input->{JSONLD_RDF_TYPE});
|
||||
|
@ -2452,7 +2465,7 @@ function _isDuckType($input, $frame)
|
|||
$rval = false;
|
||||
|
||||
// frame must not have a specific type
|
||||
if(!isset($frame->{JSONLD_RDF_TYPE}))
|
||||
if(!property_exists($frame, JSONLD_RDF_TYPE))
|
||||
{
|
||||
// get frame properties that must exist on input
|
||||
$props = array_filter(array_keys((array)$frame), '_filterNonKeywords');
|
||||
|
@ -2462,12 +2475,12 @@ function _isDuckType($input, $frame)
|
|||
$rval = true;
|
||||
}
|
||||
// input must be a subject with all the given properties
|
||||
else if(is_object($input) and isset($input->{__S}))
|
||||
else if(is_object($input) and property_exists($input, __S))
|
||||
{
|
||||
$rval = true;
|
||||
foreach($props as $prop)
|
||||
{
|
||||
if(!isset($input->$prop))
|
||||
if(!property_exists($input, $prop))
|
||||
{
|
||||
$rval = false;
|
||||
break;
|
||||
|
@ -2531,8 +2544,8 @@ function _frame($subjects, $input, $frame, $embeds, $options)
|
|||
{
|
||||
// dereference input if it refers to a subject
|
||||
$next = $input[$n];
|
||||
if(is_object($next) and isset($next->{'@iri'}) and
|
||||
isset($subjects->{$next->{'@iri'}}))
|
||||
if(is_object($next) and property_exists($next, '@iri') and
|
||||
property_exists($subjects, $next->{'@iri'}))
|
||||
{
|
||||
$next = $subjects->{$next->{'@iri'}};
|
||||
}
|
||||
|
@ -2556,19 +2569,19 @@ function _frame($subjects, $input, $frame, $embeds, $options)
|
|||
$frame = $frames[$i1];
|
||||
|
||||
// determine if value should be embedded or referenced
|
||||
$embedOn = isset($frame->{'@embed'}) ?
|
||||
$embedOn = property_exists($frame, '@embed') ?
|
||||
$frame->{'@embed'} : $options->defaults->embedOn;
|
||||
if(!$embedOn)
|
||||
{
|
||||
// if value is a subject, only use subject IRI as reference
|
||||
if(is_object($value) and isset($value->{__S}))
|
||||
if(is_object($value) and property_exists($value, __S))
|
||||
{
|
||||
$value = $value->{__S};
|
||||
}
|
||||
}
|
||||
else if(
|
||||
is_object($value) and isset($value->{__S}) and
|
||||
isset($embeds->{$value->{__S}->{'@iri'}}))
|
||||
is_object($value) and property_exists($value, __S) and
|
||||
property_exists($embeds, $value->{__S}->{'@iri'}))
|
||||
{
|
||||
// TODO: possibly support multiple embeds in the future ... and
|
||||
// instead only prevent cycles?
|
||||
|
@ -2577,19 +2590,19 @@ function _frame($subjects, $input, $frame, $embeds, $options)
|
|||
'subject=' . $value->{__S}->{'@iri'});
|
||||
}
|
||||
// if value is a subject, do embedding and subframing
|
||||
else if(is_object($value) and isset($value->{__S}))
|
||||
else if(is_object($value) and property_exists($value, __S))
|
||||
{
|
||||
$embeds->{$value->{__S}->{'@iri'}} = true;
|
||||
|
||||
// if explicit is on, remove keys from value that aren't in frame
|
||||
$explicitOn = isset($frame->{'@explicit'}) ?
|
||||
$explicitOn = property_exists($frame, '@explicit') ?
|
||||
$frame->{'@explicit'} : $options->defaults->explicitOn;
|
||||
if($explicitOn)
|
||||
{
|
||||
foreach($value as $key => $v)
|
||||
{
|
||||
// always include subject
|
||||
if($key !== __S and !isset($frame->$key))
|
||||
// do not remove subject or any key in the frame
|
||||
if($key !== __S and !property_exists($frame, $key))
|
||||
{
|
||||
unset($value->$key);
|
||||
}
|
||||
|
@ -2597,12 +2610,12 @@ function _frame($subjects, $input, $frame, $embeds, $options)
|
|||
}
|
||||
|
||||
// iterate over frame keys to do subframing
|
||||
foreach($frame as $key => $v)
|
||||
foreach($frame as $key => $f)
|
||||
{
|
||||
// skip keywords and type query
|
||||
if(strpos($key, '@') !== 0 and $key !== JSONLD_RDF_TYPE)
|
||||
{
|
||||
if(isset($value->$key))
|
||||
if(property_exists($value, $key))
|
||||
{
|
||||
// build input and do recursion
|
||||
$input = is_array($value->$key) ?
|
||||
|
@ -2612,20 +2625,67 @@ function _frame($subjects, $input, $frame, $embeds, $options)
|
|||
{
|
||||
// replace reference to subject w/subject
|
||||
if(is_object($input[$n]) and
|
||||
isset($input[$n]->{'@iri'}) and
|
||||
isset($subjects->{$input[$n]->{'@iri'}}))
|
||||
property_exists($input[$n], '@iri') and
|
||||
property_exists($subjects, $input[$n]->{'@iri'}))
|
||||
{
|
||||
$input[$n] = $subjects->{$input[$n]->{'@iri'}};
|
||||
}
|
||||
}
|
||||
$value->$key = _frame(
|
||||
$subjects, $input, $frame->$key, $embeds, $options);
|
||||
$subjects, $input, $f, $embeds, $options);
|
||||
}
|
||||
else
|
||||
{
|
||||
// add null property to value
|
||||
$value->$key = null;
|
||||
}
|
||||
|
||||
// handle setting default value(s)
|
||||
if(property_exists($value, $key))
|
||||
{
|
||||
// use first subframe if frame is an array
|
||||
if(is_array($f))
|
||||
{
|
||||
$f = (count($f) > 0) ? $f[0] : new stdClass();
|
||||
}
|
||||
|
||||
// determine if omit default is on
|
||||
$omitOn = property_exists($f, '@omitDefault') ?
|
||||
$f->{'@omitDefault'} :
|
||||
$options->defaults->omitDefaultOn;
|
||||
|
||||
if($value->$key === null)
|
||||
{
|
||||
if($omitOn)
|
||||
{
|
||||
unset($value->$key);
|
||||
}
|
||||
else if(property_exists($f, '@default'))
|
||||
{
|
||||
$value->$key = $f->{'@default'};
|
||||
}
|
||||
}
|
||||
else if(is_array($value->$key))
|
||||
{
|
||||
$tmp = array();
|
||||
foreach($value->$key as $v)
|
||||
{
|
||||
if($v === null)
|
||||
{
|
||||
if(!$omitOn)
|
||||
{
|
||||
$tmp[] = property_exists($f, '$default') ?
|
||||
$f->{'$default'} : null;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$tmp[] = $v;
|
||||
}
|
||||
}
|
||||
$value->$key = $tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue