These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /* |
||
4 | * This file is part of the FOSRestBundle package. |
||
5 | * |
||
6 | * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/> |
||
7 | * |
||
8 | * For the full copyright and license information, please view the LICENSE |
||
9 | * file that was distributed with this source code. |
||
10 | */ |
||
11 | |||
12 | namespace FOS\RestBundle\Routing\Loader; |
||
13 | |||
14 | use FOS\RestBundle\Routing\RestRouteCollection; |
||
15 | use Symfony\Component\Config\FileLocatorInterface; |
||
16 | use Symfony\Component\Config\Resource\FileResource; |
||
17 | use Symfony\Component\Routing\Loader\YamlFileLoader; |
||
18 | use Symfony\Component\Routing\RouteCollection; |
||
19 | use Symfony\Component\Yaml\Exception\ParseException; |
||
20 | use Symfony\Component\Yaml\Yaml; |
||
21 | |||
22 | /** |
||
23 | * RestYamlCollectionLoader YAML file collections loader. |
||
24 | */ |
||
25 | class RestYamlCollectionLoader extends YamlFileLoader |
||
26 | { |
||
27 | protected $collectionParents = []; |
||
28 | private $processor; |
||
29 | private $includeFormat; |
||
30 | private $formats; |
||
31 | private $defaultFormat; |
||
32 | |||
33 | /** |
||
34 | * Initializes yaml loader. |
||
35 | * |
||
36 | * @param FileLocatorInterface $locator |
||
37 | * @param RestRouteProcessor $processor |
||
38 | * @param bool $includeFormat |
||
39 | * @param string[] $formats |
||
40 | * @param string $defaultFormat |
||
41 | */ |
||
42 | 29 | View Code Duplication | public function __construct( |
0 ignored issues
–
show
|
|||
43 | FileLocatorInterface $locator, |
||
44 | RestRouteProcessor $processor, |
||
45 | $includeFormat = true, |
||
46 | array $formats = [], |
||
47 | $defaultFormat = null |
||
48 | ) { |
||
49 | 29 | parent::__construct($locator); |
|
50 | |||
51 | 29 | $this->processor = $processor; |
|
52 | 29 | $this->includeFormat = $includeFormat; |
|
53 | 29 | $this->formats = $formats; |
|
54 | 29 | $this->defaultFormat = $defaultFormat; |
|
55 | 29 | } |
|
56 | |||
57 | /** |
||
58 | * {@inheritdoc} |
||
59 | */ |
||
60 | 17 | public function load($file, $type = null) |
|
61 | { |
||
62 | 17 | $path = $this->locator->locate($file); |
|
63 | |||
64 | try { |
||
65 | 17 | $config = Yaml::parse(file_get_contents($path)); |
|
66 | 17 | } catch (ParseException $e) { |
|
67 | 1 | throw new \InvalidArgumentException(sprintf('The file "%s" does not contain valid YAML.', $path), 0, $e); |
|
68 | } |
||
69 | |||
70 | 16 | $collection = new RouteCollection(); |
|
71 | 16 | $collection->addResource(new FileResource($path)); |
|
72 | |||
73 | // empty file |
||
74 | 16 | if (null === $config) { |
|
75 | 1 | return $collection; |
|
76 | } |
||
77 | |||
78 | // not an array |
||
79 | 15 | if (!is_array($config)) { |
|
80 | 1 | throw new \InvalidArgumentException(sprintf('The file "%s" must contain a Yaml mapping (an array).', $path)); |
|
81 | } |
||
82 | |||
83 | // process routes and imports |
||
84 | 14 | foreach ($config as $name => $config) { |
|
85 | 14 | if (isset($config['resource'])) { |
|
86 | 8 | $resource = $config['resource']; |
|
87 | 8 | $prefix = isset($config['prefix']) ? $config['prefix'] : null; |
|
88 | 8 | $namePrefix = isset($config['name_prefix']) ? $config['name_prefix'] : null; |
|
89 | 8 | $parent = isset($config['parent']) ? $config['parent'] : null; |
|
90 | 8 | $type = isset($config['type']) ? $config['type'] : null; |
|
91 | 8 | $host = isset($config['host']) ? $config['host'] : null; |
|
92 | 8 | $requirements = isset($config['requirements']) ? $config['requirements'] : []; |
|
93 | 8 | $defaults = isset($config['defaults']) ? $config['defaults'] : []; |
|
94 | 8 | $options = isset($config['options']) ? $config['options'] : []; |
|
95 | 8 | $currentDir = dirname($path); |
|
96 | |||
97 | 8 | $parents = []; |
|
98 | 8 | View Code Duplication | if (!empty($parent)) { |
99 | 4 | if (!isset($this->collectionParents[$parent])) { |
|
100 | 1 | throw new \InvalidArgumentException(sprintf('Cannot find parent resource with name %s', $parent)); |
|
101 | } |
||
102 | |||
103 | 3 | $parents = $this->collectionParents[$parent]; |
|
104 | 3 | } |
|
105 | |||
106 | 7 | $imported = $this->processor->importResource($this, $resource, $parents, $prefix, $namePrefix, $type, $currentDir); |
|
107 | |||
108 | 7 | if ($imported instanceof RestRouteCollection) { |
|
109 | 7 | $parents[] = ($prefix ? $prefix.'/' : '').$imported->getSingularName(); |
|
110 | 7 | $prefix = null; |
|
111 | 7 | $namePrefix = null; |
|
112 | |||
113 | 7 | $this->collectionParents[$name] = $parents; |
|
114 | 7 | } |
|
115 | |||
116 | 7 | $imported->addRequirements($requirements); |
|
117 | 7 | $imported->addDefaults($defaults); |
|
118 | 7 | $imported->addOptions($options); |
|
119 | |||
120 | 7 | if (!empty($host)) { |
|
121 | $imported->setHost($host); |
||
122 | } |
||
123 | |||
124 | 7 | $imported->addPrefix($prefix); |
|
125 | |||
126 | // Add name prefix from parent config files |
||
127 | 7 | $imported = $this->addParentNamePrefix($imported, $namePrefix); |
|
128 | |||
129 | 7 | $collection->addCollection($imported); |
|
130 | 13 | } elseif (isset($config['pattern']) || isset($config['path'])) { |
|
131 | // the YamlFileLoader of the Routing component only checks for |
||
132 | // the path option |
||
133 | 6 | if (!isset($config['path'])) { |
|
134 | 1 | $config['path'] = $config['pattern']; |
|
135 | |||
136 | 1 | @trigger_error(sprintf('The "pattern" option at "%s" in file "%s" is deprecated. Use the "path" option instead.', $name, $path), E_USER_DEPRECATED); |
|
137 | 1 | } |
|
138 | |||
139 | 6 | if ($this->includeFormat) { |
|
140 | // append format placeholder if not present |
||
141 | 5 | if (false === strpos($config['path'], '{_format}')) { |
|
142 | 5 | $config['path'] .= '.{_format}'; |
|
143 | 5 | } |
|
144 | |||
145 | // set format requirement if configured globally |
||
146 | 5 | View Code Duplication | if (!isset($config['requirements']['_format']) && !empty($this->formats)) { |
147 | 5 | $config['requirements']['_format'] = implode('|', array_keys($this->formats)); |
|
148 | 5 | } |
|
149 | 5 | } |
|
150 | |||
151 | // set the default format if configured |
||
152 | 6 | if (null !== $this->defaultFormat) { |
|
153 | 1 | $config['defaults']['_format'] = $this->defaultFormat; |
|
154 | 1 | } |
|
155 | |||
156 | 6 | $this->parseRoute($collection, $name, $config, $path); |
|
157 | 6 | } else { |
|
158 | throw new \InvalidArgumentException(sprintf('Unable to parse the "%s" route.', $name)); |
||
159 | } |
||
160 | 13 | } |
|
161 | |||
162 | 13 | return $collection; |
|
163 | } |
||
164 | |||
165 | /** |
||
166 | * {@inheritdoc} |
||
167 | */ |
||
168 | 7 | public function supports($resource, $type = null) |
|
169 | { |
||
170 | 7 | return is_string($resource) && |
|
171 | 7 | 'yml' === pathinfo($resource, PATHINFO_EXTENSION) && |
|
172 | 7 | 'rest' === $type; |
|
173 | } |
||
174 | |||
175 | /** |
||
176 | * Adds a name prefix to the route name of all collection routes. |
||
177 | * |
||
178 | * @param RouteCollection $collection Route collection |
||
179 | * @param array $namePrefix NamePrefix to add in each route name of the route collection |
||
180 | * |
||
181 | * @return RouteCollection |
||
182 | */ |
||
183 | 7 | public function addParentNamePrefix(RouteCollection $collection, $namePrefix) |
|
184 | { |
||
185 | 7 | if (!isset($namePrefix) || ($namePrefix = trim($namePrefix)) === '') { |
|
186 | 7 | return $collection; |
|
187 | } |
||
188 | |||
189 | 1 | $iterator = $collection->getIterator(); |
|
190 | |||
191 | 1 | foreach ($iterator as $key1 => $route1) { |
|
192 | 1 | $collection->add($namePrefix.$key1, $route1); |
|
193 | 1 | $collection->remove($key1); |
|
194 | 1 | } |
|
195 | |||
196 | 1 | return $collection; |
|
197 | } |
||
198 | } |
||
199 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.