Service::__construct()   A
last analyzed

Complexity

Conditions 3
Paths 4

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 24
ccs 14
cts 14
cp 1
rs 9.536
cc 3
nc 4
nop 8
crap 3

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/*
4
 * This file is part of the CRUDlex package.
5
 *
6
 * (c) Philip Lehmann-Böhm <[email protected]>
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 CRUDlex;
13
14
use League\Flysystem\FilesystemInterface;
15
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
16
use Symfony\Component\Translation\TranslatorInterface;
17
18
/**
19
 * The Service setups and initializes the whole CRUD system and is initialized via the framework
20
 * specific implementation, the Silex one for example.
21
 * It offers access to AbstractData instances, one for each defined entity off the CRUD YAML file
22
 * and various other helper functions.
23
 */
24
class Service
25
{
26
27
    /**
28
     * Holds the data instances.
29
     * @var array
30
     */
31
    protected $datas;
32
33
    /**
34
     * Holds the map for overriding templates.
35
     * @var array
36
     */
37
    protected $templates;
38
39
    /**
40
     * Holds whether CRUDlex manages i18n.
41
     * @var bool
42
     */
43
    protected $manageI18n = true;
44
45
    /**
46
     * Holds the URL generator.
47
     * @var \Symfony\Component\Routing\Generator\UrlGeneratorInterface
48
     */
49
    protected $urlGenerator;
50
51
    /**
52
     * Gets the available locales.
53
     *
54
     * @return array
55
     * the available locales
56
     */
57 80
    public static function getLocales()
58
    {
59 80
        $localeDir     = __DIR__.'/../locales';
60 80
        $languageFiles = scandir($localeDir);
61 80
        $locales       = [];
62 80
        foreach ($languageFiles as $languageFile) {
63 80
            if (in_array($languageFile, ['.', '..'])) {
64 80
                continue;
65
            }
66 80
            $extensionPos = strpos($languageFile, '.yml');
67 80
            if ($extensionPos !== false) {
68 80
                $locale    = substr($languageFile, 0, $extensionPos);
69 80
                $locales[] = $locale;
70
            }
71
        }
72 80
        sort($locales);
73 80
        return $locales;
74
    }
75
76
    /**
77
     * Initializes the children of the data entries.
78
     */
79 79
    protected function initChildren()
80
    {
81 79
        foreach ($this->datas as $name => $data) {
82 79
            $fields = $data->getDefinition()->getFieldNames();
83 79
            foreach ($fields as $field) {
84 79
                if ($data->getDefinition()->getType($field) == 'reference') {
85 79
                    $this->datas[$data->getDefinition()->getSubTypeField($field, 'reference', 'entity')]->getDefinition()->addChild($data->getDefinition()->getTable(), $field, $name);
86
                }
87
            }
88
        }
89 79
    }
90
91
    /**
92
     * Gets a map with localized entity labels from the CRUD YML.
93
     *
94
     * @param array $crud
95
     * the CRUD entity map
96
     *
97
     * @return array
98
     * the map with localized entity labels
99
     */
100 79
    protected function getLocaleLabels(array $crud)
101
    {
102 79
        $locales      = $this->getLocales();
103 79
        $localeLabels = [];
104 79
        foreach ($locales as $locale) {
105 79
            if (array_key_exists('label_'.$locale, $crud)) {
106 79
                $localeLabels[$locale] = $crud['label_'.$locale];
107
            }
108
        }
109 79
        return $localeLabels;
110
    }
111
112
    /**
113
     * Configures the EntityDefinition according to the given
114
     * CRUD entity map.
115
     *
116
     * @param EntityDefinition $definition
117
     * the definition to configure
118
     * @param array $crud
119
     * the CRUD entity map
120
     */
121 79
    protected function configureDefinition(EntityDefinition $definition, array $crud)
122
    {
123
        $toConfigure = [
124 79
            'deleteCascade',
125
            'listFields',
126
            'filter',
127
            'childrenLabelFields',
128
            'pageSize',
129
            'initialSortField',
130
            'initialSortAscending',
131
            'navBarGroup',
132
            'optimisticLocking',
133
            'hardDeletion',
134
        ];
135 79
        foreach ($toConfigure as $field) {
136 79
            if (array_key_exists($field, $crud)) {
137 79
                $function = 'set'.ucfirst($field);
138 79
                $definition->$function($crud[$field]);
139
            }
140
        }
141 79
    }
142
143
    /**
144
     * Creates and setups an EntityDefinition instance.
145
     *
146
     * @param TranslatorInterface $translator
147
     * the Translator to use for some standard field labels
148
     * @param EntityDefinitionFactoryInterface $entityDefinitionFactory
149
     * the EntityDefinitionFactory to use
150
     * @param array $crud
151
     * the parsed YAML of a CRUD entity
152
     * @param string $name
153
     * the name of the entity
154
     *
155
     * @return EntityDefinition
156
     * the EntityDefinition good to go
157
     */
158 79
    protected function createDefinition(TranslatorInterface $translator, EntityDefinitionFactoryInterface $entityDefinitionFactory, array $crud, $name)
159
    {
160 79
        $label               = array_key_exists('label', $crud) ? $crud['label'] : $name;
161 79
        $localeLabels        = $this->getLocaleLabels($crud);
162
        $standardFieldLabels = [
163 79
            'id' => $translator->trans('crudlex.label.id'),
164 79
            'created_at' => $translator->trans('crudlex.label.created_at'),
165 79
            'updated_at' => $translator->trans('crudlex.label.updated_at')
166
        ];
167
168 79
        $definition = $entityDefinitionFactory->createEntityDefinition(
169 79
            $crud['table'],
170 79
            $crud['fields'],
171 79
            $label,
172 79
            $localeLabels,
173 79
            $standardFieldLabels,
174 79
            $this
175
        );
176 79
        $this->configureDefinition($definition, $crud);
177 79
        return $definition;
178
    }
179
180
    /**
181
     * Initializes the instance.
182
     *
183
     * @param string $crudFile
184
     * the CRUD YAML file
185
     * @param string|null $crudFileCachingDirectory
186
     * the writable directory to store the CRUD YAML file cache
187
     * @param UrlGeneratorInterface $urlGenerator
188
     * the URL generator to use
189
     * @param TranslatorInterface $translator
190
     * the translator to use
191
     * @param DataFactoryInterface $dataFactory
192
     * the data factory to use
193
     * @param EntityDefinitionFactoryInterface $entityDefinitionFactory
194
     * the EntityDefinitionFactory to use
195
     * @param FilesystemInterface $filesystem
196
     * the filesystem to use
197
     * @param EntityDefinitionValidatorInterface|null $validator
198
     * the validator to use, null if no validation required
199
     */
200 80
    public function __construct($crudFile, $crudFileCachingDirectory, UrlGeneratorInterface $urlGenerator, TranslatorInterface $translator, DataFactoryInterface $dataFactory, EntityDefinitionFactoryInterface $entityDefinitionFactory, FilesystemInterface $filesystem, ?EntityDefinitionValidatorInterface $validator)
201
    {
202
203 80
        $this->urlGenerator = $urlGenerator;
204
205 80
        $this->templates = [];
206 80
        $this->setTemplate('layout', '@crud/layout.twig');
207
208 80
        $reader     = new YamlReader($crudFileCachingDirectory);
209 80
        $parsedYaml = $reader->read($crudFile);
210
211 79
        if ($validator !== null) {
212 79
            $validator->validate($parsedYaml);
213
        }
214
215 79
        $this->datas = [];
216 79
        foreach ($parsedYaml as $name => $crud) {
217 79
            $definition         = $this->createDefinition($translator, $entityDefinitionFactory, $crud, $name);
218 79
            $this->datas[$name] = $dataFactory->createData($definition, $filesystem);
219
        }
220
221 79
        $this->initChildren();
222
223 79
    }
224
225
    /**
226
     * Getter for the AbstractData instances.
227
     *
228
     * @param string $name
229
     * the entity name of the desired Data instance
230
     *
231
     * @return AbstractData
232
     * the AbstractData instance or null on invalid name
233
     */
234 72
    public function getData($name)
235
    {
236 72
        if (!array_key_exists($name, $this->datas)) {
237 10
            return null;
238
        }
239 72
        return $this->datas[$name];
240
    }
241
242
    /**
243
     * Getter for all available entity names.
244
     *
245
     * @return string[]
246
     * a list of all available entity names
247
     */
248 6
    public function getEntities()
249
    {
250 6
        return array_keys($this->datas);
251
    }
252
253
    /**
254
     * Getter for the entities for the navigation bar.
255
     *
256
     * @return string[]
257
     * a list of all available entity names with their group
258
     */
259 11
    public function getEntitiesNavBar()
260
    {
261 11
        $result = [];
262 11
        foreach ($this->datas as $entity => $data) {
263 11
            $navBarGroup = $data->getDefinition()->getNavBarGroup();
264 11
            if ($navBarGroup !== 'main') {
265 11
                $result[$navBarGroup][] = $entity;
266
            } else {
267
                $result[$entity] = 'main';
268
            }
269
        }
270 11
        return $result;
271
    }
272
273
    /**
274
     * Sets a template to use instead of the build in ones.
275
     *
276
     * @param string $key
277
     * the template key to use in this format:
278
     * $section.$action.$entity
279
     * $section.$action
280
     * $section
281
     * @param string $template
282
     * the template to use for this key
283
     */
284 80
    public function setTemplate($key, $template)
285
    {
286 80
        $this->templates[$key] = $template;
287 80
    }
288
289
    /**
290
     * Determines the Twig template to use for the given parameters depending on
291
     * the existance of certain template keys set in this order:
292
     *
293
     * $section.$action.$entity
294
     * $section.$action
295
     * $section
296
     *
297
     * If nothing exists, this string is returned: "@crud/<action>.twig"
298
     *
299
     * @param string $section
300
     * the section of the template, either "layout" or "template"
301
     * @param string $action
302
     * the current calling action like "create" or "show"
303
     * @param string $entity
304
     * the current calling entity
305
     *
306
     * @return string
307
     * the best fitting template
308
     */
309 11
    public function getTemplate($section, $action, $entity)
310
    {
311 11
        $sectionAction = $section.'.'.$action;
312
313
        $offsets = [
314 11
            $sectionAction.'.'.$entity,
315 11
            $section.'.'.$entity,
316 11
            $sectionAction,
317 11
            $section
318
        ];
319 11
        foreach ($offsets as $offset) {
320 11
            if (array_key_exists($offset, $this->templates)) {
321 11
                return $this->templates[$offset];
322
            }
323
        }
324
325 11
        return '@crud/'.$action.'.twig';
326
    }
327
328
    /**
329
     * Sets the locale to be used.
330
     *
331
     * @param string $locale
332
     * the locale to be used.
333
     */
334 3
    public function setLocale($locale)
335
    {
336 3
        foreach ($this->datas as $data) {
337 3
            $data->getDefinition()->setLocale($locale);
338
        }
339 3
    }
340
341
    /**
342
     * Gets whether CRUDlex manages the i18n.
343
     * @return bool
344
     * true if so
345
     */
346 11
    public function isManageI18n()
347
    {
348 11
        return $this->manageI18n;
349
    }
350
351
    /**
352
     * Sets whether CRUDlex manages the i18n.
353
     * @param bool $manageI18n
354
     * true if so
355
     */
356 1
    public function setManageI18n($manageI18n)
357
    {
358 1
        $this->manageI18n = $manageI18n;
359 1
    }
360
361
    /**
362
     * Generates an URL.
363
     * @param string $name
364
     * the name of the route
365
     * @param mixed $parameters
366
     * an array of parameters
367
     * @return null|string
368
     * the generated URL
369
     */
370 11
    public function generateURL($name, $parameters)
371
    {
372 11
        return $this->urlGenerator->generate($name, $parameters);
373
    }
374
375
}
376