From 46ac3cbbf9ee0f01e4a5287e90701c69956f5d45 Mon Sep 17 00:00:00 2001 From: Codeliner Date: Sun, 30 Mar 2014 21:39:49 +0200 Subject: [PATCH] Close #123 --- src/PhlyRestfully/Plugin/HalLinks.php | 35 +++++++++++++------ .../ChildResourcesIntegrationTest.php | 12 +++---- .../PhlyRestfullyTest/Plugin/HalLinksTest.php | 27 ++++++++++++++ 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/PhlyRestfully/Plugin/HalLinks.php b/src/PhlyRestfully/Plugin/HalLinks.php index 2b191f0a..0b061b9d 100644 --- a/src/PhlyRestfully/Plugin/HalLinks.php +++ b/src/PhlyRestfully/Plugin/HalLinks.php @@ -139,10 +139,11 @@ public function setEventManager(EventManagerInterface $events) $events->attach('getIdFromResource', function ($e) { $resource = $e->getParam('resource'); + $identifierName = $e->getParam('identifier_name', 'id'); // Found id in array - if (is_array($resource) && array_key_exists('id', $resource)) { - return $resource['id']; + if (is_array($resource) && array_key_exists($identifierName, $resource)) { + return $resource[$identifierName]; } // No id in array, or not an object; return false @@ -151,13 +152,15 @@ public function setEventManager(EventManagerInterface $events) } // Found public id property on object - if (isset($resource->id)) { - return $resource->id; + if (isset($resource->{$identifierName})) { + return $resource->{$identifierName}; } + $publicGetter = 'get' . ucfirst($identifierName); + // Found public id getter on object - if (method_exists($resource, 'getid')) { - return $resource->getId(); + if (method_exists($resource, $publicGetter)) { + return $resource->{$publicGetter}(); } // not found @@ -578,7 +581,7 @@ public function createResource($resource, $route, $identifierName) } if (!$resource instanceof HalResource) { - $id = $this->getIdFromResource($resource); + $id = $this->getIdFromResource($resource, $identifierName); if (!$id) { return new ApiProblem( 422, @@ -820,7 +823,7 @@ protected function extractCollection(HalCollection $halCollection) } } - $id = $this->getIdFromResource($resource); + $id = $this->getIdFromResource($resource, $identifierName); if (!$id) { // Cannot handle resources without an identifier // Return as-is @@ -828,10 +831,13 @@ protected function extractCollection(HalCollection $halCollection) continue; } + + if ($eventParams['resource'] instanceof LinkCollectionAwareInterface) { $links = $eventParams['resource']->getLinks(); } else { $links = new LinkCollection(); + var_dump($eventParams['route']); } $selfLink = new Link('self'); @@ -853,21 +859,28 @@ protected function extractCollection(HalCollection $halCollection) /** * Retrieve the identifier from a resource * - * Expects an "id" member to exist; if not, a boolean false is returned. + * Expects an "id" or $identifierName member to exist; if not, a boolean false is returned. * * Triggers the "getIdFromResource" event with the resource; listeners can * return a non-false, non-null value in order to specify the identifier * to use for URL assembly. * * @param array|object $resource + * @param null|string $identifierName * @return mixed|false */ - protected function getIdFromResource($resource) + protected function getIdFromResource($resource, $identifierName = null) { + $params = array('resource' => $resource); + + if ($identifierName) { + $params['identifier_name'] = $identifierName; + } + $results = $this->getEventManager()->trigger( __FUNCTION__, $this, - array('resource' => $resource), + $params, function ($r) { return (null !== $r && false !== $r); } diff --git a/test/PhlyRestfullyTest/ChildResourcesIntegrationTest.php b/test/PhlyRestfullyTest/ChildResourcesIntegrationTest.php index 0ec02436..0bfabf7a 100644 --- a/test/PhlyRestfullyTest/ChildResourcesIntegrationTest.php +++ b/test/PhlyRestfullyTest/ChildResourcesIntegrationTest.php @@ -349,8 +349,8 @@ public function testChildResourceObjectIdentiferMappingViaControllerReturn() $resource = new Resource(); $resource->getEventManager()->attach('fetch', function ($e) { return (object) array( - 'id' => 'luke', - 'name' => 'Luke Skywalker', + 'child_id' => 'luke', + 'name' => 'Luke Skywalker', ); }); $controller = new ResourceController(); @@ -393,12 +393,12 @@ public function testChildResourceObjectIdentiferMappingInCollectionsViaControlle $resource->getEventManager()->attach('fetchAll', function ($e) { return array( (object) array( - 'id' => 'luke', - 'name' => 'Luke Skywalker', + 'child_id' => 'luke', + 'name' => 'Luke Skywalker', ), (object) array( - 'id' => 'leia', - 'name' => 'Leia Organa', + 'child_id' => 'leia', + 'name' => 'Leia Organa', ), ); }); diff --git a/test/PhlyRestfullyTest/Plugin/HalLinksTest.php b/test/PhlyRestfullyTest/Plugin/HalLinksTest.php index 66afce33..28ea8e34 100644 --- a/test/PhlyRestfullyTest/Plugin/HalLinksTest.php +++ b/test/PhlyRestfullyTest/Plugin/HalLinksTest.php @@ -435,6 +435,33 @@ public function testRenderingCollectionRendersAllLinksInEmbeddedResources() $this->assertRelationalLinkContains('/users/foo', 'self', $user); $this->assertRelationalLinkContains('/users/foo/phones', 'phones', $user); } + + public function testRenderingCollectionRendersAllLinksInEmbeddedArrayResourcesWithCustomIdentifier() + { + $embedded = array('custom_id' => 'foo', 'name' => 'foo'); + + $collection = new HalCollection(array($embedded)); + $collection->setCollectionName('embedded_custom'); + $collection->setCollectionRoute('hostname/embedded_custom'); + $collection->setResourceRoute('hostname/embedded_custom'); + $collection->setIdentifierName('custom_id'); + $self = new Link('self'); + $self->setRoute('hostname/embedded_custom'); + $collection->getLinks()->add($self); + + $rendered = $this->plugin->renderCollection($collection); + + $this->assertRelationalLinkContains('/embedded_custom', 'self', $rendered); + $this->assertArrayHasKey('_embedded', $rendered); + $this->assertInternalType('array', $rendered['_embedded']); + $this->assertArrayHasKey('embedded_custom', $rendered['_embedded']); + + $embeddedCustoms = $rendered['_embedded']['embedded_custom']; + $this->assertInternalType('array', $embeddedCustoms); + $embeddedCustom = array_shift($embeddedCustoms); + + $this->assertRelationalLinkContains('/embedded_custom/foo', 'self', $embeddedCustom); + } public function testResourcesFromCollectionCanUseHydratorSetInMetadataMap() {