diff --git a/CloudObjects/SDK/CloudObject.php b/CloudObjects/SDK/CloudObject.php new file mode 100644 index 0000000..bf5b1e4 --- /dev/null +++ b/CloudObjects/SDK/CloudObject.php @@ -0,0 +1,108 @@ +getId(), "COID and Node ID must match."); + + $this->coid = $coid; + $this->node = $node; + } + + /** + * Specify a custom NodeReader to use for this CloudObject. + * If not set, a default NodeReader will be used. + */ + public function setReader(NodeReader $reader) { + $this->reader = $reader; + } + + private function getReader() { + if (!$this->reader) { + $this->reader = new NodeReader; + } + return $this->reader; + } + + /** + * Get the COID of this object. + */ + public function getCOID() : IRI { + return $this->coid; + } + + /** + * Get the raw object node. + */ + public function getObjectNode() : Node { + return $this->node; + } + + /** + * Get the value of a property as a string. + * If the property has multiple values, only the first is returned. + */ + public function getString($property, string $default = null) : ?string { + return $this->getReader()->getFirstValueString($this->node, $property, $default); + } + + /** + * Get the value of a property as an integer. + * If the property has multiple values, only the first is returned. + */ + public function getInt($property, int $default = null) : ?int { + return $this->getReader()->getFirstValueInt($this->node, $property, $default); + } + + /** + * Get the value of a property as a float. + * If the property has multiple values, only the first is returned. + */ + public function getFloat($property, float $default = null) : ?float { + return $this->getReader()->getFirstValueFloat($this->node, $property, $default); + } + + /** + * Get the value of a property as a boolean. + * If the property has multiple values, only the first is returned. + */ + public function getBool($property, bool $default = null) : ?bool { + return $this->getReader()->getFirstValueBool($this->node, $property, $default); + } + + /** + * Get the value of a property as an IRI. + * If the property has multiple values, only the first is returned. + */ + public function getIRI($property, IRI $default = null) : ?IRI { + return $this->getReader()->getFirstValueIRI($this->node, $property, $default); + } + + /** + * Get the value of a property as a Node. + * If the property has multiple values, only the first is returned. + */ + public function getNode($property, Node $default = null) : ?Node { + return $this->getReader()->getFirstValueNode($this->node, $property, $default); + } + +} diff --git a/CloudObjects/SDK/ObjectRetriever.php b/CloudObjects/SDK/ObjectRetriever.php index 6b4cfd5..42ec61b 100644 --- a/CloudObjects/SDK/ObjectRetriever.php +++ b/CloudObjects/SDK/ObjectRetriever.php @@ -170,15 +170,34 @@ class ObjectRetriever implements CustomCacheAndLogInterface { } /** - * Get an object description from CloudObjects. Attempts to get object - * from in-memory cache first, stored static configurations next, - * configured external cache third, and finally calls the Object API - * on CloudObjects Core. Returns null if the object was not found. + * Get an object description and return a CloudObject. + */ + public function getCloudObject(IRI $coid) { + $node = $this->getObjectNode($coid); + if (!$node) { + // Object not found + return null; + } + + return new CloudObject($coid, $node); + } + + /** + * Get an object description and return a node. + * + * @deprecated Use getObjectNode() instead + */ + public function getObject(IRI $coid) { + return $this->getObjectNode($coid); + } + + /** + * Get an object description from CloudObjects and return a node. * * @param IRI $coid COID of the object * @return Node|null */ - public function getObject(IRI $coid) { + public function getObjectNode(IRI $coid) { if (!COIDParser::isValidCOID($coid)) throw new Exception("Not a valid COID."); @@ -394,10 +413,11 @@ class ObjectRetriever implements CustomCacheAndLogInterface { /** * Get an object description from CloudObjects. Shorthand method for - * "getObject" which allows passing the COID as string instead of IRI. + * "getObjectNode" which allows passing the COID as string instead of IRI. * * @param any $coid * @return Node|null + * @deprecated Interface may change */ public function get($coid) { if (is_string($coid)) @@ -425,7 +445,7 @@ class ObjectRetriever implements CustomCacheAndLogInterface { $ts = microtime(true); $cacheId = $object->getId().'#'.$filename; - $fileData = $this->getFromCache($cacheId); + $fileData = $this->getFromCache($cacheId); // Parse cached data into revision and content if (isset($fileData)) { diff --git a/tests/OfflineTests/ObjectRetrieverMockTest.php b/tests/OfflineTests/ObjectRetrieverMockTest.php index a48caa3..ce0f12b 100644 --- a/tests/OfflineTests/ObjectRetrieverMockTest.php +++ b/tests/OfflineTests/ObjectRetrieverMockTest.php @@ -8,33 +8,46 @@ namespace CloudObjects\SDK; use ML\IRI\IRI; use GuzzleHttp\Client, GuzzleHttp\Handler\MockHandler, - GuzzleHttp\HandlerStack, GuzzleHttp\Psr7\Response; + GuzzleHttp\HandlerStack, GuzzleHttp\Psr7\Response; class ObjectRetrieverMockTest extends \PHPUnit\Framework\TestCase { - private $retriever; + private $retriever; - private function setMockResponse(Response $response) { - $mock = new MockHandler([$response]); - $handler = HandlerStack::create($mock); - $this->retriever->setClient(new Client(['handler' => $handler])); - } + private function setMockResponse(Response $response) { + $mock = new MockHandler([$response]); + $handler = HandlerStack::create($mock); + $this->retriever->setClient(new Client(['handler' => $handler])); + } - protected function setUp(): void { - $this->retriever = new ObjectRetriever; - } + protected function setUp(): void { + $this->retriever = new ObjectRetriever; + } - public function testGetRootResource() { - $this->setMockResponse(new Response(200, - ['Content-Type' => 'application/ld+json'], - '{"@context":{"cloudobjects":"coid:\/\/cloudobjects.io\/","rdf":"http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#","rdfs":"http:\/\/www.w3.org\/2000\/01\/rdf-schema#"},"@id":"coid:\/\/cloudobjects.io","@type":"cloudobjects:Namespace","cloudobjects:hasPublicListing":"true","cloudobjects:revision":"1-325baa62b76105f56dc09386f5a2ec91","rdfs:comment":"The CloudObjects namespace defines the essential objects.","rdfs:label":"CloudObjects"}')); + public function testGetRootResource() { + $this->setMockResponse(new Response(200, + ['Content-Type' => 'application/ld+json'], + '{"@context":{"cloudobjects":"coid:\/\/cloudobjects.io\/","rdf":"http:\/\/www.w3.org\/1999\/02\/22-rdf-syntax-ns#","rdfs":"http:\/\/www.w3.org\/2000\/01\/rdf-schema#"},"@id":"coid:\/\/cloudobjects.io","@type":"cloudobjects:Namespace","cloudobjects:hasPublicListing":"true","cloudobjects:revision":"1-325baa62b76105f56dc09386f5a2ec91","rdfs:comment":"The CloudObjects namespace defines the essential objects.","rdfs:label":"CloudObjects"}' + )); - $coid = new IRI('coid://cloudobjects.io'); - $object = $this->retriever->getObject($coid); - $this->assertNotNull($object); - $this->assertEquals((string)$coid, $object->getID()); - $this->assertNotNull($object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')); - $this->assertEquals('CloudObjects', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue()); - } + $coid = new IRI('coid://cloudobjects.io'); + + // Test node interface first + $object = $this->retriever->getObjectNode($coid); + $this->assertNotNull($object); + $this->assertEquals((string)$coid, $object->getId()); + $this->assertNotNull($object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')); + $this->assertEquals('CloudObjects', $object->getProperty('http://www.w3.org/2000/01/rdf-schema#label')->getValue()); + $this->assertNull($object->getProperty('urn:example:nonexistingvalue')); + + // Test CloudObject interface + $object = $this->retriever->getCloudObject($coid); + $this->assertNotNull($object); + $this->assertEquals((string)$coid, $object->getObjectNode()->getID()); + $this->assertEquals($coid, $object->getCOID()); + $this->assertNotNull($object->getString('http://www.w3.org/2000/01/rdf-schema#label')); + $this->assertEquals('CloudObjects', $object->getString('http://www.w3.org/2000/01/rdf-schema#label')); + $this->assertNull($object->getString('urn:example:nonexistingvalue')); + } }