Completed
Push — master ( 4e1005...e65005 )
by Philip
03:42
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 70
    public static function getLocales()
58
    {
59 70
        $localeDir     = __DIR__.'/../locales';
60 70
        $languageFiles = scandir($localeDir);
61 70
        $locales       = [];
62 70
        foreach ($languageFiles as $languageFile) {
63 70
            if (in_array($languageFile, ['.', '..'])) {
64 70
                continue;
65
            }
66 70
            $extensionPos = strpos($languageFile, '.yml');
67 70
            if ($extensionPos !== false) {
68 70
                $locale    = substr($languageFile, 0, $extensionPos);
69 70
                $locales[] = $locale;
70
            }
71
        }
72 70
        sort($locales);
73 70
        return $locales;
74
    }
75
76
    /**
77
     * Initializes the children of the data entries.
78
     */
79 69
    protected function initChildren()
80
    {
81 69
        foreach ($this->datas as $name => $data) {
82 69
            $fields = $data->getDefinition()->getFieldNames();
83 69
            foreach ($fields as $field) {
84 69
                if ($data->getDefinition()->getType($field) == 'reference') {
85 69
                    $this->datas[$data->getDefinition()->getSubTypeField($field, 'reference', 'entity')]->getDefinition()->addChild($data->getDefinition()->getTable(), $field, $name);
86
                }
87
            }
88
        }
89 69
    }
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 69
    protected function getLocaleLabels(array $crud)
101
    {
102 69
        $locales      = $this->getLocales();
103 69
        $localeLabels = [];
104 69
        foreach ($locales as $locale) {
105 69
            if (array_key_exists('label_'.$locale, $crud)) {
106 69
                $localeLabels[$locale] = $crud['label_'.$locale];
107
            }
108
        }
109 69
        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 69
    protected function configureDefinition(EntityDefinition $definition, array $crud)
122
    {
123
        $toConfigure = [
124 69
            'deleteCascade',
125
            'listFields',
126
            'filter',
127
            'childrenLabelFields',
128
            'pageSize',
129
            'initialSortField',
130
            'initialSortAscending',
131
            'navBarGroup',
132
            'optimisticLocking',
133
            'hardDeletion',
134
        ];
135 69
        foreach ($toConfigure as $field) {
136 69
            if (array_key_exists($field, $crud)) {
137 69
                $function = 'set'.ucfirst($field);
138 69
                $definition->$function($crud[$field]);
139
            }
140
        }
141 69
    }
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 69
    protected function createDefinition(TranslatorInterface $translator, EntityDefinitionFactoryInterface $entityDefinitionFactory, array $crud, $name)
159
    {
160 69
        $label               = array_key_exists('label', $crud) ? $crud['label'] : $name;
161 69
        $localeLabels        = $this->getLocaleLabels($crud);
162
        $standardFieldLabels = [
163 69
            'id' => $translator->trans('crudlex.label.id'),
164 69
            'created_at' => $translator->trans('crudlex.label.created_at'),
165 69
            'updated_at' => $translator->trans('crudlex.label.updated_at')
166
        ];
167
168 69
        $definition = $entityDefinitionFactory->createEntityDefinition(
169 69
            $crud['table'],
170 69
            $crud['fields'],
171 69
            $label,
172 69
            $localeLabels,
173 69
            $standardFieldLabels,
174 69
            $this
175
        );
176 69
        $this->configureDefinition($definition, $crud);
177 69
        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 70
    public function __construct($crudFile, $crudFileCachingDirectory, UrlGeneratorInterface $urlGenerator, TranslatorInterface $translator, DataFactoryInterface $dataFactory, EntityDefinitionFactoryInterface $entityDefinitionFactory, FilesystemInterface $filesystem, ?EntityDefinitionValidatorInterface $validator)
201
    {
202
203 70
        $this->urlGenerator = $urlGenerator;
204
205 70
        $this->templates = [];
206 70
        $this->setTemplate('layout', '@crud/layout.twig');
207
208 70
        $reader     = new YamlReader($crudFileCachingDirectory);
209 70
        $parsedYaml = $reader->read($crudFile);
210
211 69
        if ($validator !== null) {
212 69
            $validator->validate($parsedYaml);
213
        }
214
215 69
        $this->datas = [];
216 69
        foreach ($parsedYaml as $name => $crud) {
217 69
            $definition         = $this->createDefinition($translator, $entityDefinitionFactory, $crud, $name);
218 69
            $this->datas[$name] = $dataFactory->createData($definition, $filesystem);
219
        }
220
221 69
        $this->initChildren();
222
223 69
    }
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 62
    public function getData($name)
235
    {
236 62
        if (!array_key_exists($name, $this->datas)) {
237 1
            return null;
238
        }
239 62
        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 1
    public function getEntitiesNavBar()
260
    {
261 1
        $result = [];
262 1
        foreach ($this->datas as $entity => $data) {
263 1
            $navBarGroup = $data->getDefinition()->getNavBarGroup();
264 1
            if ($navBarGroup !== 'main') {
265 1
                $result[$navBarGroup][] = $entity;
266
            } else {
267
                $result[$entity] = 'main';
268
            }
269
        }
270 1
        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 70
    public function setTemplate($key, $template)
285
    {
286 70
        $this->templates[$key] = $template;
287 70
    }
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 1
    public function getTemplate($section, $action, $entity)
310
    {
311 1
        $sectionAction = $section.'.'.$action;
312
313
        $offsets = [
314 1
            $sectionAction.'.'.$entity,
315 1
            $section.'.'.$entity,
316 1
            $sectionAction,
317 1
            $section
318
        ];
319 1
        foreach ($offsets as $offset) {
320 1
            if (array_key_exists($offset, $this->templates)) {
321 1
                return $this->templates[$offset];
322
            }
323
        }
324
325 1
        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 1
    public function setLocale($locale)
335
    {
336 1
        foreach ($this->datas as $data) {
337 1
            $data->getDefinition()->setLocale($locale);
338
        }
339 1
    }
340
341
    /**
342
     * Gets whether CRUDlex manages the i18n.
343
     * @return bool
344
     * true if so
345
     */
346 1
    public function isManageI18n()
347
    {
348 1
        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 1
    public function generateURL($name, $parameters)
371
    {
372 1
        return $this->urlGenerator->generate($name, $parameters);
373
    }
374
375
}
376