ResourceLoader::createRoute()   F
last analyzed

Complexity

Conditions 24
Paths > 20000

Size

Total Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 71
rs 0
c 0
b 0
f 0
cc 24
nc 32768
nop 6

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * This file is part of the Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
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
declare(strict_types=1);
13
14
namespace Sylius\Bundle\ResourceBundle\Routing;
15
16
use Gedmo\Sluggable\Util\Urlizer;
17
use Sylius\Component\Resource\Metadata\MetadataInterface;
18
use Sylius\Component\Resource\Metadata\RegistryInterface;
19
use Symfony\Component\Config\Definition\Processor;
20
use Symfony\Component\Config\Loader\LoaderInterface;
21
use Symfony\Component\Config\Loader\LoaderResolverInterface;
22
use Symfony\Component\Routing\Route;
23
use Symfony\Component\Routing\RouteCollection;
24
use Symfony\Component\Yaml\Yaml;
25
26
final class ResourceLoader implements LoaderInterface
27
{
28
    /**
29
     * @var RegistryInterface
30
     */
31
    private $resourceRegistry;
32
33
    /**
34
     * @var RouteFactoryInterface
35
     */
36
    private $routeFactory;
37
38
    /**
39
     * @param RegistryInterface $resourceRegistry
40
     * @param RouteFactoryInterface $routeFactory
41
     */
42
    public function __construct(RegistryInterface $resourceRegistry, RouteFactoryInterface $routeFactory)
43
    {
44
        $this->resourceRegistry = $resourceRegistry;
45
        $this->routeFactory = $routeFactory;
46
    }
47
48
    /**
49
     * {@inheritdoc}
50
     */
51
    public function load($resource, $type = null): RouteCollection
52
    {
53
        $processor = new Processor();
54
        $configurationDefinition = new Configuration();
55
56
        $configuration = Yaml::parse($resource);
57
        $configuration = $processor->processConfiguration($configurationDefinition, ['routing' => $configuration]);
58
59
        if (!empty($configuration['only']) && !empty($configuration['except'])) {
60
            throw new \InvalidArgumentException('You can configure only one of "except" & "only" options.');
61
        }
62
63
        $routesToGenerate = ['show', 'index', 'create', 'update', 'delete', 'bulkDelete'];
64
65
        if (!empty($configuration['only'])) {
66
            $routesToGenerate = $configuration['only'];
67
        }
68
        if (!empty($configuration['except'])) {
69
            $routesToGenerate = array_diff($routesToGenerate, $configuration['except']);
70
        }
71
72
        $isApi = $type === 'sylius.resource_api';
73
74
        /** @var MetadataInterface $metadata */
75
        $metadata = $this->resourceRegistry->get($configuration['alias']);
76
        $routes = $this->routeFactory->createRouteCollection();
77
78
        $rootPath = sprintf('/%s/', $configuration['path'] ?? Urlizer::urlize($metadata->getPluralName()));
79
        $identifier = sprintf('{%s}', $configuration['identifier']);
80
81
        if (in_array('index', $routesToGenerate, true)) {
82
            $indexRoute = $this->createRoute($metadata, $configuration, $rootPath, 'index', ['GET'], $isApi);
83
            $routes->add($this->getRouteName($metadata, $configuration, 'index'), $indexRoute);
84
        }
85
86
        if (in_array('create', $routesToGenerate, true)) {
87
            $createRoute = $this->createRoute($metadata, $configuration, $isApi ? $rootPath : $rootPath . 'new', 'create', $isApi ? ['POST'] : ['GET', 'POST'], $isApi);
88
            $routes->add($this->getRouteName($metadata, $configuration, 'create'), $createRoute);
89
        }
90
91
        if (in_array('update', $routesToGenerate, true)) {
92
            $updateRoute = $this->createRoute($metadata, $configuration, $isApi ? $rootPath . $identifier : $rootPath . $identifier . '/edit', 'update', $isApi ? ['PUT', 'PATCH'] : ['GET', 'PUT', 'PATCH'], $isApi);
93
            $routes->add($this->getRouteName($metadata, $configuration, 'update'), $updateRoute);
94
        }
95
96
        if (in_array('show', $routesToGenerate, true)) {
97
            $showRoute = $this->createRoute($metadata, $configuration, $rootPath . $identifier, 'show', ['GET'], $isApi);
98
            $routes->add($this->getRouteName($metadata, $configuration, 'show'), $showRoute);
99
        }
100
101
        if (!$isApi && in_array('bulkDelete', $routesToGenerate, true)) {
102
            $bulkDeleteRoute = $this->createRoute($metadata, $configuration, $rootPath . 'bulk-delete', 'bulkDelete', ['DELETE'], $isApi);
103
            $routes->add($this->getRouteName($metadata, $configuration, 'bulk_delete'), $bulkDeleteRoute);
104
        }
105
106
        if (in_array('delete', $routesToGenerate, true)) {
107
            $deleteRoute = $this->createRoute($metadata, $configuration, $rootPath . $identifier, 'delete', ['DELETE'], $isApi);
108
            $routes->add($this->getRouteName($metadata, $configuration, 'delete'), $deleteRoute);
109
        }
110
111
        return $routes;
112
    }
113
114
    /**
115
     * {@inheritdoc}
116
     */
117
    public function supports($resource, $type = null): bool
118
    {
119
        return 'sylius.resource' === $type || 'sylius.resource_api' === $type;
120
    }
121
122
    /**
123
     * {@inheritdoc}
124
     */
125
    public function getResolver(): void
126
    {
127
        // Intentionally left blank.
128
    }
129
130
    /**
131
     * {@inheritdoc}
132
     */
133
    public function setResolver(LoaderResolverInterface $resolver): void
134
    {
135
        // Intentionally left blank.
136
    }
137
138
    /**
139
     * @param MetadataInterface $metadata
140
     * @param array $configuration
141
     * @param string $path
142
     * @param string $actionName
143
     * @param array $methods
144
     * @param bool $isApi
145
     *
146
     * @return Route
147
     */
148
    private function createRoute(
149
        MetadataInterface $metadata,
150
        array $configuration,
151
        string $path,
152
        string $actionName,
153
        array $methods,
154
        bool $isApi = false
155
    ): Route {
156
        $defaults = [
157
            '_controller' => $metadata->getServiceId('controller') . sprintf(':%sAction', $actionName),
158
        ];
159
160
        if ($isApi && 'index' === $actionName) {
161
            $defaults['_sylius']['serialization_groups'] = ['Default'];
162
        }
163
        if ($isApi && in_array($actionName, ['show', 'create', 'update'], true)) {
164
            $defaults['_sylius']['serialization_groups'] = ['Default', 'Detailed'];
165
        }
166
        if ($isApi && 'delete' === $actionName) {
167
            $defaults['_sylius']['csrf_protection'] = false;
168
        }
169
        if (isset($configuration['grid']) && 'index' === $actionName) {
170
            $defaults['_sylius']['grid'] = $configuration['grid'];
171
        }
172
        if (isset($configuration['form']) && in_array($actionName, ['create', 'update'], true)) {
173
            $defaults['_sylius']['form'] = $configuration['form'];
174
        }
175
        if (isset($configuration['serialization_version'])) {
176
            $defaults['_sylius']['serialization_version'] = $configuration['serialization_version'];
177
        }
178
        if (isset($configuration['section'])) {
179
            $defaults['_sylius']['section'] = $configuration['section'];
180
        }
181
        if (!empty($configuration['criteria'])) {
182
            $defaults['_sylius']['criteria'] = $configuration['criteria'];
183
        }
184
        if (array_key_exists('filterable', $configuration)) {
185
            $defaults['_sylius']['filterable'] = $configuration['filterable'];
186
        }
187
        if (isset($configuration['templates']) && in_array($actionName, ['show', 'index', 'create', 'update'], true)) {
188
            $defaults['_sylius']['template'] = sprintf(
189
                false === strpos($configuration['templates'], ':') ? '%s/%s.html.twig' : '%s:%s.html.twig',
190
                $configuration['templates'],
191
                $actionName
192
            );
193
        }
194
        if (isset($configuration['redirect']) && in_array($actionName, ['create', 'update'], true)) {
195
            $defaults['_sylius']['redirect'] = $this->getRouteName($metadata, $configuration, $configuration['redirect']);
196
        }
197
        if (isset($configuration['permission'])) {
198
            $defaults['_sylius']['permission'] = $configuration['permission'];
199
        }
200
        if (isset($configuration['vars']['all'])) {
201
            $defaults['_sylius']['vars'] = $configuration['vars']['all'];
202
        }
203
204
        if (isset($configuration['vars'][$actionName])) {
205
            $vars = $configuration['vars']['all'] ?? [];
206
            $defaults['_sylius']['vars'] = array_merge($vars, $configuration['vars'][$actionName]);
207
        }
208
209
        if ($actionName === 'bulkDelete') {
210
            $defaults['_sylius']['paginate'] = false;
211
            $defaults['_sylius']['repository'] = [
212
                'method' => 'findById',
213
                'arguments' => ['$ids'],
214
            ];
215
        }
216
217
        return $this->routeFactory->createRoute($path, $defaults, [], [], '', [], $methods);
218
    }
219
220
    /**
221
     * @param MetadataInterface $metadata
222
     * @param array $configuration
223
     * @param string $actionName
224
     *
225
     * @return string
226
     */
227
    private function getRouteName(MetadataInterface $metadata, array $configuration, string $actionName): string
228
    {
229
        $sectionPrefix = isset($configuration['section']) ? $configuration['section'] . '_' : '';
230
231
        return sprintf('%s_%s%s_%s', $metadata->getApplicationName(), $sectionPrefix, $metadata->getName(), $actionName);
232
    }
233
}
234