/** * cf. https://github.com/willdurand/Negotiation/issues/30, * https://github.com/FriendsOfSymfony/FOSRestBundle/issues/610 * * @dataProvider dataProviderForTakesParametersIntoAccount */ public function testTakesParametersIntoAccount($acceptHeaderString, $expectedFormat) { $this->negotiator->registerFormat('xml', array('application/vnd.my.app+xml'), true); $this->negotiator->registerFormat('json', array('application/vnd.my.app+json'), true); $this->negotiator->registerFormat('odata-v4', array('application/json;odata.metadata=full', 'application/json;odata.metadata=none', 'application/json;odata.metadata=minimal'), true); $this->negotiator->registerFormat('odata-v4-minimal-streaming', array('application/json;odata.metadata=minimal;odata.streaming=true'), true); $this->negotiator->registerFormat('odata-v3-verbose', array('application/json;odata=verbose'), true); $this->negotiator->registerFormat('atom-entry', array('application/atom+xml;type=entry'), true); $this->assertEquals('json', $this->negotiator->getBestFormat('application/vnd.my.app', array('json', 'xml'))); $this->assertEquals('json', $this->negotiator->getBestFormat('application/vnd.my.app+json', array('json', 'xml'))); $this->assertEquals('xml', $this->negotiator->getBestFormat('application/vnd.my.app+xml', array('json', 'xml'))); $this->assertNotNull($this->negotiator->getBest($acceptHeaderString, array('*/*'))); $this->assertEquals($expectedFormat, $this->negotiator->getBestFormat($acceptHeaderString, array('*/*'))); }
/** * @expectedException \InvalidArgumentException * @expectedExceptionMessage Format "html" already registered, and override was set to "false". */ public function testRegisterFormatWithExistingFormat() { $this->negotiator->registerFormat('html', array()); }
/** * Format using requested formatter (via extension, Accept-header or default) * * @param Tdt\Core\Datasets\Data $data The data object on which the response will be based * @param string $extension The preferred format in which the data should be returned * * @return \Response */ public static function getResponse($data, $extension = null) { // Check Accept-header $accept_header = \Request::header('Accept'); // Safety first $extension = strtoupper($extension); // Formatter class $formatter_class = 'Tdt\\Core\\Formatters\\' . $extension . 'Formatter'; if (empty($extension)) { $negotiator = new FormatNegotiator(); foreach (self::$mime_types_map as $format_name => $mime_types) { $negotiator->registerFormat($format_name, $mime_types, true); } // Create a priority list of formats $priorities = array(); $format_helper = new FormatHelper(); if (empty($data->preferred_formats)) { // Still nothing? Use default formatter if (empty($extension) && !$data->is_semantic) { // Default formatter for non semantic data $data->preferred_formats = array('json'); } elseif (empty($extension) && $data->is_semantic) { // Default formatter for semantic data is turtle $data->preferred_formats = array('ttl'); } } if (!in_array('html', $priorities)) { array_push($priorities, 'html'); } $priorities = array_merge($data->preferred_formats, $priorities); // Add support for our other formatters as well, if they're not already in the priorities foreach ($format_helper->getAvailableFormats($data) as $format) { if (!in_array($format, $priorities)) { array_push($priorities, $format); } } array_push($priorities, '*/*'); $format = $negotiator->getBestFormat($accept_header, $priorities); $format_object = $negotiator->getBest($accept_header, $priorities); if (!$format || $format_object->getQuality() == 0) { $format_helper = new FormatHelper(); $available_formats = implode(', ', array_values($format_helper->getAvailableFormats($data))); \App::abort(406, "The requested Content-Type is not supported, or the best quality we found was 0. The supported formats for this resource are: " . $available_formats); } // Safety first $extension = strtoupper($format); // Formatter class $formatter_class = 'Tdt\\Core\\Formatters\\' . $extension . 'Formatter'; } elseif (!class_exists($formatter_class)) { $format_helper = new FormatHelper(); $available_formats = implode(', ', array_values($format_helper->getAvailableFormats($data))); \App::abort(406, "The requested Content-Type is not supported, or the best quality we found was 0. The supported formats for this resource are: " . $available_formats); } // Create the response from the designated formatter $response = $formatter_class::createResponse($data); // Set the paging header if (!empty($data->paging)) { $response->header('Link', self::getLinkHeader($data->paging)); } // Set the URI template header if (!empty($data->optional_parameters) || !empty($data->rest_parameters)) { // http://www.mnot.net/blog/2006/10/04/uri_templating $link_template = self::fetchUrl($extension); if (substr($link_template, -1, 1) == '/') { $link_template = substr($link_template, 0, -1); } // Add the required parameters foreach ($data->rest_parameters as $required_parameter) { $link_template .= '/{' . $required_parameter . '}'; } // Add the extension if given if (!empty($extension)) { $link_template .= '.' . strtolower($extension); } // Add the optional parameters if (!empty($data->optional_parameters)) { $link_template .= '{?'; foreach ($data->optional_parameters as $optional_parameter) { $link_template .= $optional_parameter . ', '; } $link_template = rtrim($link_template, ', '); $link_template .= '}'; } $response->header('Link-Template', $link_template); } // Cache settings $cache_minutes = -1; if (\Config::get('cache.enabled', true)) { $cache_minutes = 1; // Cache per resource if (!empty($data->source_definition['cache'])) { $cache_minutes = $data->source_definition['cache']; } } // Cache headers $response->header('Cache-Control', 'public, max-age=' . $cache_minutes * 60 . ', pre-check=' . $cache_minutes * 60 . ''); $response->header('Pragma', 'public'); $response->header('Expires', date(DATE_RFC822, strtotime("{$cache_minutes} minute"))); $response->header('Vary', 'Accept, Accept-encoding'); // Return formatted response return $response; }