Completed
Push — master ( 6fed26...e3ac15 )
by Guilh
08:12
created

Routing/Loader/RestYamlCollectionLoader.php (1 issue)

Upgrade to new PHP Analysis Engine

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
This method seems to be duplicated in your project.

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.

Loading history...
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