Completed
Push — master ( fdffac...bad96d )
by Philip
06:31
created

Service::__construct()   A

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
    public static function getLocales()
58
    {
59
        $localeDir     = __DIR__.'/../locales';
60
        $languageFiles = scandir($localeDir);
61 79
        $locales       = [];
62
        foreach ($languageFiles as $languageFile) {
63 79
            if (in_array($languageFile, ['.', '..'])) {
64 79
                continue;
65 79
            }
66 79
            $extensionPos = strpos($languageFile, '.yml');
67 79
            if ($extensionPos !== false) {
68
                $locale    = substr($languageFile, 0, $extensionPos);
69 79
                $locales[] = $locale;
70
            }
71
        }
72
        sort($locales);
73
        return $locales;
74
    }
75 79
76
    /**
77 79
     * Initializes the children of the data entries.
78 79
     */
79 79
    protected function initChildren()
80 79
    {
81 79
        foreach ($this->datas as $name => $data) {
82
            $fields = $data->getDefinition()->getFieldNames();
83
            foreach ($fields as $field) {
84
                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
    }
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 79
     * the map with localized entity labels
99
     */
100 79
    protected function getLocaleLabels(array $crud)
101 79
    {
102 79
        $locales = $this->getLocales();
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
103 79
        $localeLabels = [];
104
        foreach ($locales as $locale) {
105
            if (array_key_exists('label_'.$locale, $crud)) {
106 79
                $localeLabels[$locale] = $crud['label_'.$locale];
107
            }
108
        }
109
        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 79
     * @param array $crud
119
     * the CRUD entity map
120
     */
121 79
    protected function configureDefinition(EntityDefinition $definition, array $crud)
122
    {
123
        $toConfigure = [
124
            'deleteCascade',
125
            'listFields',
126
            'filter',
127
            'childrenLabelFields',
128
            'pageSize',
129
            'initialSortField',
130
            'initialSortAscending',
131
            'navBarGroup',
132 79
            'optimisticLocking',
133 79
            'hardDeletion',
134 79
        ];
135 79
        foreach ($toConfigure as $field) {
136
            if (array_key_exists($field, $crud)) {
137
                $function = 'set'.ucfirst($field);
138 79
                $definition->$function($crud[$field]);
139
            }
140
        }
141
    }
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 79
     */
158
    protected function createDefinition(TranslatorInterface $translator, EntityDefinitionFactoryInterface $entityDefinitionFactory, array $crud, $name)
159 79
    {
160 79
        $label               = array_key_exists('label', $crud) ? $crud['label'] : $name;
161
        $localeLabels        = $this->getLocaleLabels($crud);
162 79
        $standardFieldLabels = [
163 79
            'id' => $translator->trans('crudlex.label.id'),
164 79
            'created_at' => $translator->trans('crudlex.label.created_at'),
165
            'updated_at' => $translator->trans('crudlex.label.updated_at')
166
        ];
167 79
168 79
        $definition = $entityDefinitionFactory->createEntityDefinition(
169 79
            $crud['table'],
170 79
            $crud['fields'],
171 79
            $label,
172 79
            $localeLabels,
173 79
            $standardFieldLabels,
174
            $this
175 79
        );
176 79
        $this->configureDefinition($definition, $crud);
177
        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 80
     */
200
    public function __construct($crudFile, $crudFileCachingDirectory, UrlGeneratorInterface $urlGenerator, TranslatorInterface $translator, DataFactoryInterface $dataFactory, EntityDefinitionFactoryInterface $entityDefinitionFactory, FilesystemInterface $filesystem, ?EntityDefinitionValidatorInterface $validator)
201
    {
202 80
203
        $this->urlGenerator = $urlGenerator;
204 80
205 80
        $this->templates = [];
206
        $this->setTemplate('layout', '@crud/layout.twig');
207 80
208 80
        $reader     = new YamlReader($crudFileCachingDirectory);
209
        $parsedYaml = $reader->read($crudFile);
210 79
211 79
        if ($validator !== null) {
212
            $validator->validate($parsedYaml);
213
        }
214 79
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 71
    public function getData($name)
235
    {
236 71
        if (!array_key_exists($name, $this->datas)) {
237 3
            return null;
238
        }
239 71
        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 5
    public function getEntities()
249
    {
250 5
        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 11
                $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
    public function isManageI18n()
347 79
    {
348
        return $this->manageI18n;
349 79
    }
350 79
351 79
    /**
352 79
     * Sets whether CRUDlex manages the i18n.
353 79
     * @param bool $manageI18n
354 79
     * true if so
355
     */
356 79
    public function setManageI18n($manageI18n)
357 79
    {
358 79
        $this->manageI18n = $manageI18n;
359 79
    }
360
361
    /**
362 79
     * Generates an URL.
363 79
     * @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
    public function generateURL($name, $parameters)
371 11
    {
372
        return $this->urlGenerator->generate($name, $parameters);
373 11
    }
374
375
}
376