547e6117e7021af97ae70ab6001c1d399f4a50e6
[yaffs-website] / web / core / lib / Drupal / Core / Routing / RequestFormatRouteFilter.php
1 <?php
2
3 namespace Drupal\Core\Routing;
4
5 use Symfony\Component\HttpFoundation\Request;
6 use Symfony\Component\HttpKernel\Exception\NotAcceptableHttpException;
7 use Symfony\Component\Routing\Route;
8 use Symfony\Component\Routing\RouteCollection;
9
10 /**
11  * Provides a route filter, which filters by the request format.
12  */
13 class RequestFormatRouteFilter implements RouteFilterInterface {
14
15   /**
16    * {@inheritdoc}
17    */
18   public function applies(Route $route) {
19     return $route->hasRequirement('_format');
20   }
21
22   /**
23    * {@inheritdoc}
24    */
25   public function filter(RouteCollection $collection, Request $request) {
26     // Determine the request format.
27     $default_format = static::getDefaultFormat($collection);
28     $format = $request->getRequestFormat($default_format);
29
30     /** @var \Symfony\Component\Routing\Route $route */
31     foreach ($collection as $name => $route) {
32       // If the route has no _format specification, we move it to the end. If it
33       // does, then no match means the route is removed entirely.
34       if ($supported_formats = array_filter(explode('|', $route->getRequirement('_format')))) {
35         if (!in_array($format, $supported_formats)) {
36           $collection->remove($name);
37         }
38       }
39       else {
40         $collection->add($name, $route);
41       }
42     }
43
44     if (count($collection)) {
45       return $collection;
46     }
47
48     // We do not throw a
49     // \Symfony\Component\Routing\Exception\ResourceNotFoundException here
50     // because we don't want to return a 404 status code, but rather a 406.
51     throw new NotAcceptableHttpException("No route found for the specified format $format.");
52   }
53
54   /**
55    * Determines the default request format.
56    *
57    * By default, use 'html' as the default format. But when there's only a
58    * single route match, and that route specifies a '_format' requirement
59    * listing a single format, then use that as the default format.
60    *
61    * @param \Symfony\Component\Routing\RouteCollection $collection
62    *   The route collection to filter.
63    *
64    * @return string
65    *   The default format.
66    */
67   protected static function getDefaultFormat(RouteCollection $collection) {
68     $default_format = 'html';
69     if ($collection->count() === 1) {
70       $only_route = $collection->getIterator()->current();
71       $required_format = $only_route->getRequirement('_format');
72       if (strpos($required_format, '|') === FALSE) {
73         $default_format = $required_format;
74       }
75     }
76     return $default_format;
77   }
78
79 }