nodeA means * that nodeA["as:inReplyTo"] == this node). * @var array */ private $backreferences; /** * JsonLdNode constructor. * @param stdClass $jsonLd The JSON-LD input. * @param string|array|stdClass $context The JSON-LD context. * @param JsonLdNodeFactory $factory The factory used to construct this instance. * @param DereferencerInterface $dereferencer * @param LoggerInterface $logger * @param JsonLdGraph $graph The JSON-LD graph this node is a part of. * @param array $backreferences */ public function __construct( $jsonLd, $context, JsonLdNodeFactory $factory, DereferencerInterface $dereferencer, LoggerInterface $logger, JsonLdGraph $graph, $backreferences = [], ) { $this->factory = $factory; $this->dereferencer = $dereferencer; $this->logger = $logger; if ( $jsonLd == new stdClass() ) { $this->expanded = new stdClass(); } else { $this->expanded = JsonLD::expand( $jsonLd )[0]; } if ( property_exists( $this->expanded, '@id' ) ) { $idProp = '@id'; $this->id = $this->expanded->$idProp; } $this->context = $context; $this->graph = $graph; $this->graph->addNode( $this ); $this->backreferences = $backreferences; } /** * Gets this node's id. Could be a temporary id if this is a blank node. * @return string */ public function getId() { return $this->id; } /** * Sets this node's ID to $id. * @param string $id * @throws BadMethodCallException If this node already has an ID set. */ public function setId($id) { if ( ! is_null( $this->getId() ) ) { throw new BadMethodCallException( 'Node already has an ID' ); } $this->id = $id; } /** * Cardinality-one get. Gets the single value for the property named $name. * If there are multiple values defined for the property, only the first value is returned. * @param string $name The property name to get. * @return mixed A single property value. * @throws PropertyNotDefinedException If no property named $name exists. * @throws NodeNotFoundException If lazy-loading a linked node fails. */ public function get($name) { $expandedName = $this->expandName( $name ); if ( property_exists( $this->expanded, $expandedName ) ) { $resolved = $this->resolveProperty( $expandedName, $this->expanded->$expandedName[0] ); if ( is_array( $resolved ) ) { $resolved = $resolved[0]; } return $resolved; } throw new PropertyNotDefinedException( $name ); } /** * Cardinality-many get. Gets all the values for the property named $name. * If there is only one value defined for the property, it is returned as a length-1 array. * @param string $name The property name to get. * @return mixed A single property value. * @throws PropertyNotDefinedException If no property named $name exists. * @throws NodeNotFoundException If lazy-loading a linked node fails. */ public function getMany($name) { $expandedName = $this->expandName( $name ); if ( property_exists( $this->expanded, $expandedName ) ) { $resolved = $this->resolveProperty( $expandedName, $this->expanded->$expandedName ); if ( ! is_array( $resolved ) ) { $resolved = array( $resolved ); } return $resolved; } throw new PropertyNotDefinedException( $name ); } /** * A convenience wrapper around $this->get( $name ). Cardinality-one. * @param string $name * @return mixed * @throws PropertyNotDefinedException */ public function __get($name) { return $this->get( $name ); } /** * Takes a raw value from $this->expanded and turns it into something useful. * If its a node, lazy-load the node and wrap it in a JsonLdNode. If it's a value object, * return the value. If it's an array, recursively resolve the values in the array. * @param string $expandedName The name of the property we are resolving. * @param mixed $property The property value. * @return JsonLdNode|array|mixed * @throws NodeNotFoundException If lazy-loading the node fails because the node does not exist. */ private function resolveProperty($expandedName, &$property) { if ( is_array( $property ) ) { $properties = []; foreach ( $property as $subProperty ) { $properties[] = $this->resolveProperty( $expandedName, $subProperty ); } return $properties; } else if ( $property instanceof stdClass && property_exists( $property, '@id') ) { // Lazy-load if we only have the @id property $idProp = '@id'; if ( count( get_object_vars( $property ) ) <= 1 ) { $iri = $property->$idProp; $dereferenced = $this->dereferencer->dereference( $iri ); $expanded = JsonLD::expand( $dereferenced )[0]; $property = $expanded; } $referencedNode = $this->graph->getNode( $property->$idProp ); if ( is_null( $referencedNode) ) { $backrefs = array( $expandedName => array( $this ) ); $referencedNode = $this->factory->newNode( $property, $this->graph, $backrefs ); } return $referencedNode; } else if ( $property instanceof stdClass && property_exists( $property, '@value' ) ) { // TODO check for an @type and return an appropriate object type if present, e.g. Datetime for dates or // number for nonNegativeInteger etc. $value = '@value'; return $property->$value; } else if ( $property instanceof stdClass ) { $referencedNode = $this->factory->newNode( $property, $this->graph ); return $referencedNode; } else { return $property; } } /** * Sets the value for a new or existing property on the node. * If the property already exists, the new value overwrites the old value(s). * @param string $name * @param string|stdClass|array $value */ public function set($name, $value) { $expandedName = $this->expandName( $name ); if ( $expandedName === '@id' && ! $this->isBlankNode() ) { throw new InvalidArgumentException( 'This node already has an id.' ); } $expandedValue = $this->expandValue( $expandedName, $value ); $this->addNewValueToGraph( $expandedName, $expandedValue ); $this->expanded->$expandedName = $expandedValue; if ( $expandedName === '@id' ) { $this->graph->nameBlankNode( $this->getId(), $expandedValue ); $this->id = $expandedValue; } } public function add($name, $value) { $expandedName = $this->expandName( $name ); if ( $expandedName === '@id' ) { throw new InvalidArgumentException( 'Cannot add to the @id property.' ); } $expandedValue = $this->expandValue( $expandedName, $value ); $this->addNewValueToGraph( $expandedName, $expandedValue ); if ( property_exists( $this->expanded, $expandedName ) ) { $this->expanded->$expandedName = array_merge( $this->expanded->$expandedName, $expandedValue ); } else { $this->expanded->$expandedName = $expandedValue; } } private function addNewValueToGraph($expandedName, $expandedValue) { if ( is_array( $expandedValue ) ) { for ( $i = 0; $i < count( $expandedValue ); $i += 1 ) { $names[] = $expandedName; } array_map( array( $this, 'addNewValueToGraph' ), $names, $expandedValue ); } else if ( $expandedValue instanceof stdClass && property_exists( $expandedValue, '@id' ) ) { $idProp = '@id'; $id = $expandedValue->$idProp; $referencedNode = $this->graph->getNode( $id ); if ( is_null( $referencedNode ) ) { $backrefs = array( $expandedName => array( $this ) ); $this->factory->newNode( $expandedValue, $this->graph, $backrefs ); } else { $referencedNode->addBackReference( $expandedName, $this ); } } } /** * Convenience wrapper around $this->set(). * If the property already exists, the new value overwrites the old value(s). * @param string $name * @param string|stdClass|array $value */ public function __set($name, $value) { return $this->set( $name, $value ); } public function has($name) { $expandedName = $this->expandName( $name ); return property_exists( $this->expanded, $expandedName ); } /** * Given an already-expanded name and the current context, expands value so that it can be stored in $expanded. * @param string $expandedName * @param string|stdClass|array $value * @return array|stdClass */ private function expandValue($expandedName, $value) { $nameToValue = (object) array( '@context' => $this->context, $expandedName => $value ); $expanded = JsonLD::expand( $nameToValue )[0]; $expandedValue = $expanded->$expandedName; return $expandedValue; } /** * Clears the property named $name. * @param string $name */ public function clear($name) { $expandedName = $this->expandName( $name ); unset( $this->expanded->expandedName ); } /** * Returns the node as an object. * @return stdClass */ public function asObject() { return JsonLD::compact( $this->expanded, $this->context ); } /** * Returns true if this node is a blank node (even if it has a temporary id). * @return bool */ public function isBlankNode() { return ! property_exists( $this->expanded, '@id' ); } /** * Returns the list of nodes which reference this node as the field $name. * @param string $name * @return array */ public function getBackReferences($name) { $expandedName = $this->expandName( $name ); if ( array_key_exists( $expandedName, $this->backreferences ) ) { return $this->backreferences[$expandedName]; } else { return array(); } } /** * Adds a new backreference to this node. * @param string $expandedName * @param JsonLdNode $referencingNode */ public function addBackReference($expandedName, JsonLdNode $referencingNode) { $this->backreferences[$expandedName][] = $referencingNode; } /** * Returns the node expressed as an array of RdfTriples. * @return TypedRdfTriple[] */ public function toRdfTriples() { $idProp = '@id'; $valueProp = '@value'; $typeProp = '@type'; $triples = array(); foreach ( get_object_vars( $this->expanded ) as $attribute => $values ) { if ( ! is_array( $values ) ) { // If $values is not an array, this is the @id property $triples[] = TypedRdfTriple::create( $this->getId(), $attribute, $values ); continue; } foreach ( $values as $value ) { if ( ! is_object( $value ) ) { // If $value is not an object, this is the @type property $triples[] = TypedRdfTriple::create( $this->getId(), $attribute, $value ); } if ( property_exists( $value, '@id' ) ) { $triples[] = TypedRdfTriple::create( $this->getId(), $attribute, $value->$idProp, '@id' ); } else if ( property_exists( $value, '@value' ) ) { $jsonLdValue = Value::fromJsonLd( $value ); $triple = TypedRdfTriple::create( $this->getId(), $attribute, $jsonLdValue->getValue() ); if ( $jsonLdValue instanceof TypedValue ) { $triple->setObjectType( $jsonLdValue->getType() ); } $triples[] = $triple; } } // Check if we should serialize any child nodes foreach ( $this->getMany( $attribute ) as $childNode ) { if ( $childNode instanceof JsonLdNode ) { // Serialize the child node if it is local, i.e. has a local URI or is anonymous if ( $childNode->isBlankNode() || Util::isLocalUri( $childNode->getId() ) ) { $triples = array_merge( $triples, $childNode->toRdfTriples() ); } } } } return $triples; } /** * Whether a offset exists * @link https://php.net/manual/en/arrayaccess.offsetexists.php * @param mixed $offset
* An offset to check for. *
* @return boolean true on success or false on failure. * ** The return value will be casted to boolean if non-boolean was returned. * @since 5.0.0 */ public function offsetExists($offset) { return property_exists( $this->expanded, (string) $offset ); } /** * A convenience wrapper around $this->get(). Cardinality-one. * Offset to retrieve * @link https://php.net/manual/en/arrayaccess.offsetget.php * @param mixed $offset
* The offset to retrieve. *
* @return mixed Can return all value types. * @since 5.0.0 * @throws PropertyNotDefinedException */ public function offsetGet($offset) { return $this->get( (string) $offset ); } /** * Offset to set * @link https://php.net/manual/en/arrayaccess.offsetset.php * @param mixed $offset* The offset to assign the value to. *
* @param mixed $value* The value to set. *
* @return void * @since 5.0.0 */ public function offsetSet($offset, $value) { $this->set( (string) $offset, $value ); } /** * Offset to unset * @link https://php.net/manual/en/arrayaccess.offsetunset.php * @param mixed $offset* The offset to unset. *
* @return void * @since 5.0.0 */ public function offsetUnset($offset) { $this->clear( (string) $offset ); } /** * Resolves $name to a full IRI given the JSON-LD context of this node. * @param string $name The name of the property to resolve. * @return string The expanded name. */ private function expandName($name) { // TODO memoize this function $dummyObj = (object) array( '@context' => $this->context, '_dummyKey' => '_dummyValue', // Set a dummy key to ensure that @id gets properly expanded $name => '_dummyValue', ); $expanded = (array) JsonLD::expand( $dummyObj )[0]; unset( $expanded['_:_dummyKey'] ); return array_keys( $expanded )[0]; } }__halt_compiler();----SIGNATURE:----hgDf6SJd0ZycKHHHAm8TYlv/A6rNJ91s5Qe47ipClyyd6eAQOpHtiMyOatCooW6tTAkuPd07eEwlBMBhwsPCcB89SzcK/7hHdaXARkglX+RIk5tzN0sFEJ9t9FuTW7z0la6d6qKg/pN/EufhQ0k/FNBCihxZ+vNOMOZ7wCb3qSfGLQ+tsIjeNEiqYWbLXQtQsZEQ8kc/gYfn4EV38JCarvKqb+ZlHIlDmthliFtsxTRhfUZVrSAC5QJb2oLzAyXw+Bf5vtqIqmAXZYw7beHG6bTH13iTr2yMbmQYRgTOiWyvxJk8KKxnKOxM78dE/eT9f284QmSbfza3RXi6HgtC42gNQhYnVileJgmm319+CQ1Kanjp/RYtPudjyN7p/hT1E7P5CMp7rPCXdxXDYQKg/z2JS23TMNqA5uEo4agztT516+Z/JRYohq6wQLcrMihgPQ2JYY2un1xu1y0WDE7bg9LcWyt/6RuGR3iOUcySyYuPkxwCGYVP8CmoQr4Hqn+A+l+zWgW9r3gGjFAXHQwG9j90NaUdHhmxWGktWmHt39xsoVOyYZKyFWjKlv07GRUBFfDAXtkNCIav7k/kpnMeWpZIMa2UHUBE61cfVIdl1kgkKb0eo6o1ym7OUPm7eE37tCOpTV3gFu7iDQSwkP5G6xWB5kfQic3hYJ0zvp7jIOY=----ATTACHMENT:----ODg5NzcxMDcyODU2NDc2OCA0MDIxMTE1MDM2NjQ3ODYwIDM2MzgyNDE4NzI5NzQ3Nzc=