diff --git a/src/JsonLd/JsonLdNode.php b/src/JsonLd/JsonLdNode.php index f8054f9..ca2b5c8 100644 --- a/src/JsonLd/JsonLdNode.php +++ b/src/JsonLd/JsonLdNode.php @@ -173,16 +173,14 @@ class JsonLdNode implements ArrayAccess } return array_map( array( $this, 'resolveProperty'), $names, $property ); } else if ( $property instanceof stdClass && property_exists( $property, '@id') ) { - // Only dereference if @id is the only property present - if ( count( get_object_vars( $property ) ) > 1 ) { - return $property; - } - // Otherwise lazy-load the referenced node + // Lazy-load if we only have the @id property $idProp = '@id'; - $iri = $property->$idProp; - $dereferenced = $this->dereferencer->dereference( $iri ); - $expanded = JsonLD::expand( $dereferenced )[0]; - $property = $expanded; + 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 ) ); @@ -315,6 +313,26 @@ class JsonLdNode implements ArrayAccess 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; diff --git a/test/JsonLd/JsonLdNodeTest.php b/test/JsonLd/JsonLdNodeTest.php index f2ed4e8..d872904 100644 --- a/test/JsonLd/JsonLdNodeTest.php +++ b/test/JsonLd/JsonLdNodeTest.php @@ -400,10 +400,61 @@ class JsonLdNodeTest extends APTestCase $this->assertEquals( $expectedValue, $actualValue ); } - public function testBackreferences() + public function provideForBackreferencesOnGet() { - // TODO implement me - $this->assertTrue( false ); + return array( + array( + (object) array( + '@context' => array( 'https://www.w3.org/ns/activitystreams' ), + 'id' => 'https://example.org/objects/1', + 'type' => 'Note', + 'inReplyTo' => (object) array( + 'id' => 'https://example.org/articles/1', + 'type' => 'Article', + ), + ), + $this->asContext, + 'inReplyTo', + ), + ); + } + + /** + * @dataProvider provideForBackreferencesOnGet + */ + public function testBackreferencesOnGet( $inputObj, $context, $childNodeField, $nodeGraph = array() ) + { + $parentNode = $this->makeJsonLdNode( $inputObj, $context, $nodeGraph ); + $childNode = $parentNode->$childNodeField; + $this->assertInstanceOf( JsonLdNode::class, $childNode ); + $this->assertEquals( $childNode->getBackReferences( $childNodeField ), array( $parentNode ) ); + } + + public function provideForBackreferencesOnSet() + { + return array( + array( + new stdClass(), + $this->asContext, + 'inReplyTo', + (object) array( + 'id' => 'https://example.org/articles/1', + 'type' => 'Article', + ) + ) + ); + } + + /** + * @dataProvider provideForBackreferencesOnSet + */ + public function testBackreferencesOnSet( $inputObj, $context, $newPropertyName, $newNodeValue ) + { + $parentNode = $this->makeJsonLdNode( $inputObj, $context ); + $parentNode->set( $newPropertyName, $newNodeValue ); + $childNode = $parentNode->get( $newPropertyName ); + $this->assertInstanceOf( JsonLdNode::class, $childNode ); + $this->assertEquals( $childNode->getBackReferences( $newPropertyName ), array( $parentNode ) ); } private function makeJsonLdNode( $inputObj, $context, $nodeGraph = array() )