/**
  * 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;
 }