/** * test adding an item * * @return void */ public function testAddItem() { $header = new LinkHeader(array()); $item = new LinkHeaderItem('urn:uri'); $header->add($item); $links = $header->all(); $this->assertSame($item, $links[0]); }
/** * add a rel=self Link header to the response * * @param FilterResponseEvent $event response listener event * * @return void */ public function onKernelResponse(FilterResponseEvent $event) { if (!$event->isMasterRequest()) { // don't do anything if it's not the master request return; } $response = $event->getResponse(); $request = $event->getRequest(); $linkHeader = LinkHeader::fromResponse($response); // extract various info from route $routeName = $request->get('_route'); $routeParts = explode('.', $routeName); $routeType = end($routeParts); if ($routeType == 'post') { $routeName = substr($routeName, 0, -4) . 'get'; } /** if the request failed in the RestController, $request will not have an record id in case of a POST and $router->generate() will fail. that's why we catch it and fail silently by not including our header in the response. i hope that's a good compromise. **/ /** Nope, it's not a good compromise...catch and handle it where it happens. * I will refactory this in another branch*/ $addHeader = true; $url = ''; try { $url = $this->router->generate($routeName, $this->generateParameters($routeType, $request), true); } catch (\Exception $e) { $addHeader = false; } if ($addHeader) { // append rel=self link to link headers $linkHeader->add(new LinkHeaderItem($url, array('rel' => 'self'))); // overwrite link headers with new headers $response->headers->set('Link', (string) $linkHeader); } }
/** * generate link header passed on params and type * * @param string $routeName use with router to generate urls * @param integer $page page to link to * @param integer $perPage number of items per page * @param string $type rel type of link to generate * @param array $additionalParams Optional array of additional params to include * * @return string */ private function generateLink($routeName, $page, $perPage, $type, $additionalParams = array()) { $parameters = array_merge($additionalParams, array('page' => $page)); if ($perPage) { $parameters['perPage'] = $perPage; } $url = $this->router->generate($routeName, $parameters, true); $this->linkHeader->add(new LinkHeaderItem($url, array('rel' => $type))); }
/** * add a rel=self Link header to the response * * @param FilterResponseEvent $event response listener event * * @return void */ public function onKernelResponse(FilterResponseEvent $event) { $request = $event->getRequest(); if ($request->attributes->get('schemaRequest', false)) { $response = $event->getResponse(); $linkHeader = LinkHeader::fromResponse($response); $routeName = SchemaUtils::getSchemaRouteName($request->get('_route')); $url = $this->router->generate($routeName, array(), true); // append rel=canonical link to link headers $linkHeader->add(new LinkHeaderItem($url, array('rel' => 'canonical'))); // overwrite link headers with new headers $response->headers->set('Link', (string) $linkHeader); $event->setResponse($response); } }
/** * generate link header passed on params and type * * @param string $routeName use with router to generate urls * @param integer $page page to link to * @param integer $perPage number of items per page * @param string $type rel type of link to generate * @param Request $request request to get rawRql from * @param string $rql rql query string * * @return string */ private function generateLink($routeName, $page, $perPage, $type, Request $request, $rql) { $limit = ''; if ($perPage) { $page = ($page - 1) * $perPage; $limit = sprintf('limit(%s,%s)', $perPage, $page); } if (strpos($rql, 'limit') !== false) { $rql = preg_replace('/limit\\(.*\\)/', $limit, $rql); } else { $rql = $limit; } $url = $this->getRqlUrl($request, $this->router->generate($routeName, [], true) . '?' . strtr($rql, [',' => '%2C'])); $this->linkHeader->add(new LinkHeaderItem($url, array('rel' => $type))); }
/** * add a rel=self Link header to the response * * @param FilterResponseEvent $event response listener event * @param string $eventName event name * @param EventDispatcherInterface $dispatcher dispatcher * * @return void */ public function onKernelResponse(FilterResponseEvent $event, $eventName, EventDispatcherInterface $dispatcher) { if (!$event->isMasterRequest()) { // don't do anything if it's not the master request return; } $response = $event->getResponse(); $request = $event->getRequest(); $linkHeader = LinkHeader::fromResponse($response); // extract various info from route $routeName = $request->get('_route'); $routeParts = explode('.', $routeName); $routeType = end($routeParts); if ($routeType == 'post') { $routeName = substr($routeName, 0, -4) . 'get'; } if ($routeType == 'postNoSlash') { $routeName = substr($routeName, 0, -11) . 'get'; } /** if the request failed in the RestController, $request will not have an record id in case of a POST and $router->generate() will fail. that's why we catch it and fail silently by not including our header in the response. i hope that's a good compromise. **/ /** Nope, it's not a good compromise...catch and handle it where it happens. * I will refactory this in another branch*/ $addHeader = true; $url = ''; try { $params = $this->generateParameters($routeType, $request); $query = ''; if (array_key_exists('q', $params)) { $query = '?' . strtr($params['q'], [',' => '%2C']); unset($params['q']); } $url = $this->getRqlUrl($request, $this->router->generate($routeName, $params, true) . $query); } catch (\Exception $e) { $addHeader = false; } if ($addHeader) { // append rel=self link to link headers $linkHeader->add(new LinkHeaderItem($url, array('rel' => 'self'))); // overwrite link headers with new headers $response->headers->set('Link', (string) $linkHeader); // set in request and dispatch new event for interested parties $event->getRequest()->attributes->set('selfLink', $url); $dispatcher->dispatch('graviton.rest.response.selfaware', $event); } }
/** * add a rel=eventStatus Link header to the response if necessary * * @param FilterResponseEvent $event response listener event * * @return void */ public function onKernelResponse(FilterResponseEvent $event) { // exit if not master request or uninteresting method.. if (!$event->isMasterRequest() || $this->isNotConcerningRequest()) { return; } // we can always safely call this, it doesn't need much resources. // only if we have subscribers, it will create more load as it persists an EventStatus $queueEvent = $this->createQueueEventObject(); /** @var Response $response */ $response = $event->getResponse(); if (!empty($queueEvent->getStatusurl()) && !empty($queueEvent->getEvent())) { $linkHeader = LinkHeader::fromResponse($response); $linkHeader->add(new LinkHeaderItem($queueEvent->getStatusurl(), array('rel' => 'eventStatus'))); $response->headers->set('Link', (string) $linkHeader); } // let's send it to the queue if appropriate if (!empty($queueEvent->getEvent())) { $this->rabbitMqProducer->publish(json_encode($queueEvent), $queueEvent->getEvent()); } }
/** * Prepares the header field containing information about pagination. * * @return string */ protected function prepareLinkHeader() { $links = new LinkHeader(array()); $links->add(new LinkHeaderItem($this->router->generate('graviton.core.rest.app.all', array(), true), array('rel' => 'apps', 'type' => 'application/json'))); return (string) $links; }