コード例 #1
0
 public function testInjectCollectionSelfLinkShouldAddSelfLinkToLinkCollection()
 {
     $linkCollection = new LinkCollection();
     $resource = new Collection([]);
     $resource->setLinks($linkCollection);
     $injector = new SelfLinkInjector();
     $injector->injectSelfLink($resource, 'foo');
     $this->assertTrue($linkCollection->has('self'));
 }
コード例 #2
0
 public function halObjects()
 {
     $entity = new Entity(['foo' => 'bar'], 'identifier', 'route');
     $link = new Link('self');
     $link->setRoute('resource/route')->setRouteParams(['id' => 'identifier']);
     $entity->getLinks()->add($link);
     $collection = new Collection([$entity]);
     $collection->setCollectionRoute('collection/route');
     $collection->setEntityRoute('resource/route');
     return ['entity' => [$entity], 'collection' => [$collection]];
 }
コード例 #3
0
 /**
  * @param  int $pages
  * @param  int $currentPage
  * @return Collection
  */
 private function getHalCollection($pages, $currentPage)
 {
     $items = [];
     for ($i = 0; $i < $pages; $i++) {
         $items[] = [];
     }
     $adapter = new ArrayAdapter($items);
     $collection = new Paginator($adapter);
     $halCollection = new Collection($collection);
     $halCollection->setCollectionRoute('foo');
     $halCollection->setPage($currentPage);
     $halCollection->setPageSize(1);
     return $halCollection;
 }
コード例 #4
0
    public function halObjects()
    {
        $entity = new Entity(array(
            'foo' => 'bar',
        ), 'identifier', 'route');
        $link = new Link('self');
        $link->setRoute('resource/route')->setRouteParams(array('id' => 'identifier'));
        $entity->getLinks()->add($link);

        $collection = new Collection(array($entity));
        $collection->setCollectionRoute('collection/route');
        $collection->setEntityRoute('resource/route');

        return array(
            'entity'     => array($entity),
            'collection' => array($collection),
        );
    }
コード例 #5
0
 public function settingsDashboardAction()
 {
     $authentication = $this->authentication->fetch();
     if ($authentication) {
         $authenticationEntity = $authentication;
         $authentication = new Entity($authentication, null);
         $authentication->getLinks()->add(Link::factory(array('rel' => 'self', 'route' => $this->getRouteForEntity($authenticationEntity))));
     }
     $dbAdapters = new Collection($this->dbAdapters->fetchAll());
     $dbAdapters->setCollectionRoute('zf-apigility/api/db-adapter');
     $contentNegotiation = new Collection($this->contentNegotiation->fetchAll());
     $contentNegotiation->setCollectionRoute('zf-apigility/api/content-negotiation');
     $dashboard = array('authentication' => $authentication, 'content_negotiation' => $contentNegotiation, 'db_adapter' => $dbAdapters);
     $entity = new Entity($dashboard, 'settings-dashboard');
     $links = $entity->getLinks();
     $links->add(Link::factory(array('rel' => 'self', 'route' => array('name' => 'zf-apigility/api/settings-dashboard'))));
     return new ViewModel(array('payload' => $entity));
 }
コード例 #6
0
 /**
  * @param HalCollection $halCollection
  * @return array
  */
 protected function getCollectionPayload(HalCollection $halCollection)
 {
     $collection = $halCollection->getCollection();
     $collectionName = $halCollection->getCollectionName();
     $attributes = $halCollection->getAttributes();
     $normalizationGroups = $this->getNormalizationGroups($halCollection);
     if ($collection instanceof Paginator) {
         $pageSize = (int) (isset($attributes['page_size']) ? $attributes['page_size'] : $halCollection->getPageSize());
         $collection->setItemCountPerPage($pageSize);
         $items = (array) $collection->getCurrentItems();
         /** @todo Force snake case as collection name? */
         $payload = array($collectionName => $this->getNormalizer()->normalize($items, $normalizationGroups), 'page_count' => (int) (isset($attributes['page_count']) ? $attributes['page_count'] : $collection->count()), 'page_size' => $pageSize, 'total_items' => (int) (isset($attributes['total_items']) ? $attributes['total_items'] : $collection->getTotalItemCount()));
     } else {
         $payload = array($collectionName => $this->getNormalizer()->normalize($collection, $normalizationGroups));
         if (is_array($collection) || $collection instanceof Countable) {
             $payload['total_items'] = isset($attributes['total_items']) ? $attributes['total_items'] : count($collection);
         }
     }
     $payload = array_merge($attributes, $payload);
     return $payload;
 }
コード例 #7
0
ファイル: ResourceFactory.php プロジェクト: nobesnickr/zf-hal
 /**
  * @param  object $object
  * @param  Metadata $metadata
  * @return Collection
  */
 public function createCollectionFromMetadata($object, Metadata $metadata)
 {
     $halCollection = new Collection($object);
     $halCollection->setCollectionName($metadata->getCollectionName());
     $halCollection->setCollectionRoute($metadata->getRoute());
     $halCollection->setEntityRoute($metadata->getEntityRoute());
     $halCollection->setRouteIdentifierName($metadata->getRouteIdentifierName());
     $halCollection->setEntityIdentifierName($metadata->getEntityIdentifierName());
     $links = $halCollection->getLinks();
     $this->marshalMetadataLinks($metadata, $links);
     $forceSelfLink = $metadata->getForceSelfLink();
     if ($forceSelfLink && !$links->has('self') && ($metadata->hasUrl() || $metadata->hasRoute())) {
         $link = $this->marshalLinkFromMetadata($metadata, $object);
         $links->add($link);
     }
     return $halCollection;
 }
コード例 #8
0
ファイル: HalTest.php プロジェクト: zfcampus/zf-hal
 public function testAllowsSpecifyingAlternateCallbackForReturningEntityId()
 {
     $this->plugin->getEventManager()->attach('getIdFromEntity', function ($e) {
         $entity = $e->getParam('entity');
         if (!is_array($entity)) {
             return false;
         }
         if (array_key_exists('name', $entity)) {
             return $entity['name'];
         }
         return false;
     }, 10);
     $prototype = ['foo' => 'bar'];
     $items = [];
     foreach (range(1, 100) as $id) {
         $item = $prototype;
         $item['name'] = $id;
         $items[] = $item;
     }
     $collection = new Collection($items);
     $collection->setCollectionRoute('resource');
     $collection->setEntityRoute('resource');
     $links = $collection->getLinks();
     $self = new Link('self');
     $self->setRoute('resource');
     $links->add($self);
     $result = $this->plugin->renderCollection($collection);
     $this->assertInternalType('array', $result, var_export($result, 1));
     $this->assertRelationalLinkEquals('http://localhost.localdomain/resource', 'self', $result);
     $this->assertArrayHasKey('_embedded', $result);
     $this->assertInternalType('array', $result['_embedded']);
     $this->assertArrayHasKey('items', $result['_embedded']);
     $this->assertInternalType('array', $result['_embedded']['items']);
     $this->assertEquals(100, count($result['_embedded']['items']));
     foreach ($result['_embedded']['items'] as $key => $item) {
         $id = $key + 1;
         $this->assertRelationalLinkEquals('http://localhost.localdomain/resource/' . $id, 'self', $item);
         $this->assertArrayHasKey('name', $item, var_export($item, 1));
         $this->assertEquals($id, $item['name']);
         $this->assertArrayHasKey('foo', $item);
         $this->assertEquals('bar', $item['foo']);
     }
 }
コード例 #9
0
 /**
  * Inject the input filters collection, if any, as an embedded collection
  *
  * @param RestServiceEntity $service
  */
 protected function injectInputFilters(RestServiceEntity $service)
 {
     $inputFilters = $this->inputFilterModel->fetch($this->moduleName, $service->controllerServiceName);
     if (!$inputFilters instanceof InputFilterCollection || !count($inputFilters)) {
         return;
     }
     $collection = [];
     $parentName = str_replace('\\', '-', $service->controllerServiceName);
     foreach ($inputFilters as $inputFilter) {
         $inputFilter['input_filter_name'] = str_replace('\\', '-', $inputFilter['input_filter_name']);
         $entity = new HalEntity($inputFilter, $inputFilter['input_filter_name']);
         $links = $entity->getLinks();
         $links->add(Link::factory(['rel' => 'self', 'route' => ['name' => 'zf-apigility/api/module/rest-service/input-filter', 'params' => ['name' => $this->moduleName, 'controller_service_name' => $parentName, 'input_filter_name' => $inputFilter['input_filter_name']]]]));
         $collection[] = $entity;
     }
     $collection = new HalCollection($collection);
     $collection->setCollectionName('input_filter');
     $collection->setCollectionRoute('zf-apigility/module/rest-service/input-filter');
     $collection->setCollectionRouteParams(['name' => $service->module, 'controller_service_name' => $service->controllerServiceName]);
     $service->exchangeArray(['input_filters' => $collection]);
 }
コード例 #10
0
 public function testAllowsSpecifyingAlternateCallbackForReturningEntityId()
 {
     $this->setUpHelpers();
     $this->helpers->get('Hal')->getEventManager()->attach('getIdFromEntity', function ($e) {
         $entity = $e->getParam('entity');
         if (!is_array($entity)) {
             return false;
         }
         if (array_key_exists('name', $entity)) {
             return $entity['name'];
         }
         return false;
     }, 10);
     $prototype = array('foo' => 'bar');
     $items = array();
     foreach (range(1, 100) as $id) {
         $item = $prototype;
         $item['name'] = $id;
         $items[] = $item;
     }
     $collection = new Collection($items);
     $collection->setCollectionRoute('resource');
     $collection->setEntityRoute('resource');
     $links = $collection->getLinks();
     $self = new Link('self');
     $self->setRoute('resource');
     $links->add($self);
     $model = new HalJsonModel(array('payload' => $collection));
     $test = $this->renderer->render($model);
     $test = json_decode($test);
     $this->assertInstanceof('stdClass', $test, var_export($test, 1));
     $this->assertRelationalLinkEquals('http://localhost.localdomain/resource', 'self', $test);
     $this->assertObjectHasAttribute('_embedded', $test);
     $this->assertInstanceof('stdClass', $test->_embedded);
     $this->assertObjectHasAttribute('items', $test->_embedded);
     $this->assertInternalType('array', $test->_embedded->items);
     $this->assertEquals(100, count($test->_embedded->items));
     foreach ($test->_embedded->items as $key => $item) {
         $id = $key + 1;
         $this->assertRelationalLinkEquals('http://localhost.localdomain/resource/' . $id, 'self', $item);
         $this->assertObjectHasAttribute('name', $item, var_export($item, 1));
         $this->assertEquals($id, $item->name);
         $this->assertObjectHasAttribute('foo', $item);
         $this->assertEquals('bar', $item->foo);
     }
 }
コード例 #11
0
ファイル: HalTest.php プロジェクト: jbarentsen/drb
    /**
     * @group 14
     */
    public function testRenderingNonPaginatorCollectionRendersCountOfTotalItems()
    {
        $embedded = new Entity((object) array('id' => 'foo', 'name' => 'foo'), 'foo');
        $links = $embedded->getLinks();
        $self = new Link('self');
        $self->setRoute('hostname/users', array('id' => 'foo'));
        $links->add($self);

        $collection = new Collection(array($embedded));
        $collection->setCollectionName('users');
        $self = new Link('self');
        $self->setRoute('hostname/users');
        $collection->getLinks()->add($self);

        $rendered = $this->plugin->renderCollection($collection);

        $expectedKeys = array('_links', '_embedded', 'total_items');
        $this->assertEquals($expectedKeys, array_keys($rendered));
    }
コード例 #12
0
 private function createPaginationLink($relation, Collection $halCollection, $page = null)
 {
     $options = ArrayUtils::merge($halCollection->getCollectionRouteOptions(), ['query' => ['page' => $page]]);
     return Link::factory(['rel' => $relation, 'route' => ['name' => $halCollection->getCollectionRoute(), 'params' => $halCollection->getCollectionRouteParams(), 'options' => $options]]);
 }
コード例 #13
0
ファイル: Hal.php プロジェクト: jbarentsen/drb
    /**
     * Extract a collection as an array
     *
     * @todo   Remove 'resource' from event parameters for 1.0.0
     * @todo   Remove trigger of 'renderCollection.resource' for 1.0.0
     * @param  Collection $halCollection
     * @param  int $depth                   depth of the current rendering recursion
     * @param  int $maxDepth                maximum rendering depth for the current metadata
     * @return array
     */
    protected function extractCollection(Collection $halCollection, $depth = 0, $maxDepth = null)
    {
        $collection           = array();
        $events               = $this->getEventManager();
        $routeIdentifierName  = $halCollection->getRouteIdentifierName();
        $entityRoute          = $halCollection->getEntityRoute();
        $entityRouteParams    = $halCollection->getEntityRouteParams();
        $entityRouteOptions   = $halCollection->getEntityRouteOptions();
        $metadataMap          = $this->getMetadataMap();

        foreach ($halCollection->getCollection() as $entity) {
            $eventParams = new ArrayObject(array(
                'collection'   => $halCollection,
                'entity'       => $entity,
                'resource'     => $entity,
                'route'        => $entityRoute,
                'routeParams'  => $entityRouteParams,
                'routeOptions' => $entityRouteOptions,
            ));
            $events->trigger('renderCollection.resource', $this, $eventParams);
            $events->trigger('renderCollection.entity', $this, $eventParams);

            $entity = $eventParams['entity'];

            if (is_object($entity) && $metadataMap->has($entity)) {
                $entity = $this->createEntityFromMetadata($entity, $metadataMap->get($entity));
            }

            if ($entity instanceof Entity) {
                // Depth does not increment at this level
                $collection[] = $this->renderEntity($entity, $this->getRenderCollections(), $depth, $maxDepth);
                continue;
            }

            if (!is_array($entity)) {
                $entity = $this->convertEntityToArray($entity);
            }

            foreach ($entity as $key => $value) {
                if (is_object($value) && $metadataMap->has($value)) {
                    $value = $this->createEntityFromMetadata($value, $metadataMap->get($value));
                }

                if ($value instanceof Entity) {
                    $this->extractEmbeddedEntity($entity, $key, $value, $depth + 1, $maxDepth);
                }

                if ($value instanceof Collection) {
                    $this->extractEmbeddedCollection($entity, $key, $value, $depth + 1, $maxDepth);
                }
            }

            $id = $this->getIdFromEntity($entity);

            if ($id === false) {
                // Cannot handle entities without an identifier
                // Return as-is
                $collection[] = $entity;
                continue;
            }

            if ($eventParams['entity'] instanceof LinkCollectionAwareInterface) {
                $links = $eventParams['entity']->getLinks();
            } else {
                $links = new LinkCollection();
            }

            if (isset($entity['links']) && $entity['links'] instanceof LinkCollection) {
                $links = $entity['links'];
            }

            $selfLink = new Link('self');
            $selfLink->setRoute(
                $eventParams['route'],
                array_merge($eventParams['routeParams'], array($routeIdentifierName => $id)),
                $eventParams['routeOptions']
            );
            $links->add($selfLink);

            $entity['_links'] = $this->fromLinkCollection($links);

            $collection[] = $entity;
        }

        return $collection;
    }
コード例 #14
0
 public function indexAction()
 {
     $event = $this->getEvent();
     $routeMatch = $event->getRouteMatch();
     $route = $this->deriveRouteName($routeMatch->getMatchedRouteName());
     $request = $this->getRequest();
     $module = $this->params()->fromRoute('name', false);
     $controller = $this->params()->fromRoute('controller_service_name', false);
     $inputFilterName = $this->params()->fromRoute('input_filter_name', false);
     if (!$module || !$this->model->moduleExists($module)) {
         return new ApiProblemResponse(new ApiProblem(404, 'The module specified does not exist'));
     }
     if (!$controller || !$this->model->controllerExists($module, $controller)) {
         return new ApiProblemResponse(new ApiProblem(404, 'The controller specified does not exist'));
     }
     switch ($request->getMethod()) {
         case $request::METHOD_GET:
             $result = $this->model->fetch($module, $controller, $inputFilterName);
             if (false === $result) {
                 return new ApiProblemResponse(new ApiProblem(404, 'The input filter specified does not exist'));
             }
             if ($result instanceof InputFilterCollection) {
                 $result = new HalCollection($result);
                 $result->setCollectionName('input_filter');
                 $result->getLinks()->add(Link::factory(array('rel' => 'self', 'route' => array('name' => $route, 'params' => array('name' => $module, 'controller_service_name' => str_replace('\\', '-', $controller))))));
                 $result->setEntityRoute($route);
                 break;
             }
             $name = $result['input_filter_name'];
             $result = new HalEntity($result, $name);
             $this->injectEntitySelfLink($result->getLinks(), $route, $module, $controller, $name);
             break;
         case $request::METHOD_POST:
             if ($inputFilterName) {
                 return new ApiProblemResponse(new ApiProblem(400, 'POST requests are not allowed to individual input filters'));
             }
             // Intentionally not breaking, as remainder of logic remains the same as PUT
         // Intentionally not breaking, as remainder of logic remains the same as PUT
         case $request::METHOD_PUT:
             $inputFilter = $this->bodyParams();
             $result = $this->model->update($module, $controller, $inputFilter);
             if (!$result) {
                 return new ApiProblemResponse(new ApiProblem(500, 'There was an unexpected error updating the input filter; please verify the module and controller specified are valid'));
             }
             $name = $result['input_filter_name'];
             $result = new HalEntity($result, $name);
             $this->injectEntitySelfLink($result->getLinks(), $route, $module, $controller, $name);
             break;
         case $request::METHOD_DELETE:
             if (empty($inputFilterName)) {
                 return new ApiProblemResponse(new ApiProblem(400, 'The input filter name has not been specified'));
             }
             $result = $this->model->remove($module, $controller, $inputFilterName);
             if (!$result) {
                 return new ApiProblemResponse(new ApiProblem(404, 'The input filter specified does not exist'));
             }
             return $this->getResponse()->setStatusCode(204);
     }
     $e = $this->getEvent();
     $e->setParam('ZFContentNegotiationFallback', 'HalJson');
     return new ViewModel(array('payload' => $result));
 }
コード例 #15
0
ファイル: RestController.php プロジェクト: antarus/mystra-pve
 /**
  * Prepare a HAL collection with the metadata for the current instance.
  *
  * @param HalCollection $collection
  * @return HalCollection|ApiProblem
  */
 protected function prepareHalCollection(HalCollection $collection)
 {
     if (!$collection->getLinks()->has('self')) {
         $plugin = $this->plugin('Hal');
         $plugin->injectSelfLink($collection, $this->route);
     }
     $collection->setCollectionRoute($this->route);
     $collection->setRouteIdentifierName($this->getRouteIdentifierName());
     $collection->setEntityRoute($this->route);
     $collection->setCollectionName($this->collectionName);
     $collection->setPageSize($this->getPageSize());
     try {
         $collection->setPage($this->getRequest()->getQuery('page', 1));
     } catch (HalInvalidArgumentException $e) {
         return new ApiProblem(400, $e->getMessage());
     }
     return $collection;
 }
コード例 #16
0
 public function setUpChildCollection()
 {
     $children = array(array('luke', 'Luke Skywalker'), array('leia', 'Leia Organa'));
     $this->collection = array();
     foreach ($children as $info) {
         $collection[] = call_user_func_array(array($this, 'setUpChildResource'), $info);
     }
     $collection = new HalCollection($this->collection);
     $collection->setCollectionRoute('parent/child');
     $collection->setEntityRoute('parent/child');
     $collection->setPage(1);
     $collection->setPageSize(10);
     $collection->setCollectionName('child');
     $link = new Link('self');
     $link->setRoute('parent/child');
     $collection->getLinks()->add($link);
     return $collection;
 }
コード例 #17
0
ファイル: CollectionTest.php プロジェクト: jbarentsen/drb
 public function testAllowsSettingAdditionalEntityLinks()
 {
     $links = new LinkCollection();
     $links->add(new Link('describedby'));
     $links->add(new Link('orders'));
     $hal   = new Collection(array(), 'item/route');
     $hal->setEntityLinks($links);
     $this->assertSame($links, $hal->getEntityLinks());
 }
コード例 #18
0
ファイル: Hal.php プロジェクト: antarus/mystra-pve
 /**
  * Extract a collection as an array
  *
  * @todo   Remove 'resource' from event parameters for 1.0.0
  * @todo   Remove trigger of 'renderCollection.resource' for 1.0.0
  * @param  Collection $halCollection
  * @param  int $depth                   depth of the current rendering recursion
  * @param  int $maxDepth                maximum rendering depth for the current metadata
  * @return array
  */
 protected function extractCollection(Collection $halCollection, $depth = 0, $maxDepth = null)
 {
     $collection = [];
     $events = $this->getEventManager();
     $routeIdentifierName = $halCollection->getRouteIdentifierName();
     $entityRoute = $halCollection->getEntityRoute();
     $entityRouteParams = $halCollection->getEntityRouteParams();
     $entityRouteOptions = $halCollection->getEntityRouteOptions();
     $metadataMap = $this->getMetadataMap();
     foreach ($halCollection->getCollection() as $entity) {
         $eventParams = new ArrayObject(['collection' => $halCollection, 'entity' => $entity, 'resource' => $entity, 'route' => $entityRoute, 'routeParams' => $entityRouteParams, 'routeOptions' => $entityRouteOptions]);
         $events->trigger('renderCollection.resource', $this, $eventParams);
         $events->trigger('renderCollection.entity', $this, $eventParams);
         $entity = $eventParams['entity'];
         if (is_object($entity) && $metadataMap->has($entity)) {
             $entity = $this->getResourceFactory()->createEntityFromMetadata($entity, $metadataMap->get($entity));
         }
         if ($entity instanceof Entity) {
             // Depth does not increment at this level
             $collection[] = $this->renderEntity($entity, $this->getRenderCollections(), $depth, $maxDepth);
             continue;
         }
         if (!is_array($entity)) {
             $entity = $this->getEntityExtractor()->extract($entity);
         }
         foreach ($entity as $key => $value) {
             if (is_object($value) && $metadataMap->has($value)) {
                 $value = $this->getResourceFactory()->createEntityFromMetadata($value, $metadataMap->get($value));
             }
             if ($value instanceof Entity) {
                 $this->extractEmbeddedEntity($entity, $key, $value, $depth + 1, $maxDepth);
             }
             if ($value instanceof Collection) {
                 $this->extractEmbeddedCollection($entity, $key, $value, $depth + 1, $maxDepth);
             }
         }
         $id = $this->getIdFromEntity($entity);
         if ($id === false) {
             // Cannot handle entities without an identifier
             // Return as-is
             $collection[] = $entity;
             continue;
         }
         if ($eventParams['entity'] instanceof LinkCollectionAwareInterface) {
             $links = $eventParams['entity']->getLinks();
         } else {
             $links = new LinkCollection();
         }
         if (isset($entity['links']) && $entity['links'] instanceof LinkCollection) {
             $links = $entity['links'];
         }
         /* $entity is always an array here. We don't have metadata config for arrays so the self link is forced
            by default (at the moment) and should be removed manually if not required. But at some point it should
            be discussed if it makes sense to force self links in this particular use-case.  */
         $selfLink = new Link('self');
         $selfLink->setRoute($eventParams['route'], array_merge($eventParams['routeParams'], [$routeIdentifierName => $id]), $eventParams['routeOptions']);
         $links->add($selfLink);
         $entity['_links'] = $this->fromLinkCollection($links);
         $collection[] = $entity;
     }
     return $collection;
 }
 /**
  * Inject the input filters collection, if any, as an embedded collection
  *
  * @param DoctrineRpcServiceEntity $service
  */
 protected function injectInputFilters(DoctrineRpcServiceEntity $service)
 {
     $inputFilters = $this->inputFilterModel->fetch($this->moduleName, $service->controllerServiceName);
     if (!$inputFilters instanceof InputFilterCollection || !count($inputFilters)) {
         return;
     }
     // @codeCoverageIgnoreStart
     $collection = array();
     foreach ($inputFilters as $inputFilter) {
         $resource = new HalResource($inputFilter, $inputFilter['input_filter_name']);
         $links = $resource->getLinks();
         $links->add(Link::factory(array('rel' => 'self', 'route' => array('name' => 'zf-apigility-admin/api/module/rpc-service/rpc_input_filter', 'params' => array('name' => $this->moduleName, 'controller_service_name' => $service->controllerServiceName, 'input_filter_name' => $inputFilter['input_filter_name'])))));
         $collection[] = $resource;
     }
     $collection = new HalCollection($collection);
     $collection->setCollectionName('input_filter');
     $collection->setCollectionRoute('zf-apigility-admin/module/rpc-service/inputfilter');
     $collection->setCollectionRouteParams(array('name' => $this->moduleName, 'controller_service_name' => $service->controllerServiceName));
     $service->exchangeArray(array('input_filters' => $collection));
 }