Completed
Push — refonte ( 758c88...ee8395 )
by Arnaud
02:27
created

ExtraConfigurationSubscriber::addDefaultTopMenu()   C

Complexity

Conditions 11
Paths 44

Size

Total Lines 69

Duplication

Lines 38
Ratio 55.07 %

Importance

Changes 0
Metric Value
dl 38
loc 69
rs 6.5296
c 0
b 0
f 0
cc 11
nc 44
nop 2

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
namespace LAG\AdminBundle\Event\Subscriber;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use LAG\AdminBundle\Bridge\Doctrine\ORM\Helper\MetadataTrait;
7
use LAG\AdminBundle\Configuration\ApplicationConfiguration;
8
use LAG\AdminBundle\Configuration\ApplicationConfigurationStorage;
9
use LAG\AdminBundle\Event\Events;
10
use LAG\AdminBundle\Event\ConfigurationEvent;
11
use LAG\AdminBundle\Event\Menu\MenuConfigurationEvent;
12
use LAG\AdminBundle\Factory\ConfigurationFactory;
13
use LAG\AdminBundle\Field\Helper\FieldConfigurationHelper;
14
use LAG\AdminBundle\Resource\ResourceCollection;
15
use LAG\AdminBundle\Utils\StringUtils;
16
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17
18
/**
19
 * Add extra default configuration for actions and fields.
20
 */
21
class ExtraConfigurationSubscriber implements EventSubscriberInterface
22
{
23
    use MetadataTrait;
24
25
    /**
26
     * @var ApplicationConfiguration
27
     */
28
    private $applicationConfiguration;
29
30
    /**
31
     * @var ResourceCollection
32
     */
33
    private $resourceCollection;
34
35
    /**
36
     * @var ConfigurationFactory
37
     */
38
    private $configurationFactory;
39
40
    /**
41
     * @return array
42
     */
43
    public static function getSubscribedEvents()
44
    {
45
        return [
46
            Events::ADMIN_CONFIGURATION => 'enrichAdminConfiguration',
47
            Events::MENU_CONFIGURATION => 'enrichMenuConfiguration',
48
        ];
49
    }
50
51
    /**
52
     * ExtraConfigurationSubscriber constructor.
53
     *
54
     * @param ApplicationConfigurationStorage $applicationConfigurationStorage
55
     * @param EntityManagerInterface          $entityManager
56
     * @param ResourceCollection              $resourceCollection
57
     * @param ConfigurationFactory            $configurationFactory
58
     */
59 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
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...
60
        ApplicationConfigurationStorage $applicationConfigurationStorage,
61
        EntityManagerInterface $entityManager,
62
        ResourceCollection $resourceCollection,
63
        ConfigurationFactory $configurationFactory
64
    ) {
65
        $this->applicationConfiguration = $applicationConfigurationStorage->getConfiguration();
66
        $this->entityManager = $entityManager;
67
        $this->resourceCollection = $resourceCollection;
68
        $this->configurationFactory = $configurationFactory;
69
    }
70
71
    public function enrichAdminConfiguration(ConfigurationEvent $event)
72
    {
73
        if (!$this->isExtraConfigurationEnabled()) {
74
            return;
75
        }
76
        $configuration = $event->getConfiguration();
77
78
        // Actions
79
        $this->addDefaultActions($configuration);
80
81
        // Add default field configuration: it provides a type, a form type, and a view according to the found metadata
82
        $helper = new FieldConfigurationHelper($this->entityManager, $this->applicationConfiguration);
83
        $helper->addDefaultFields($configuration, $event->getEntityClass(), $event->getAdminName());
84
        $helper->addDefaultStrategy($configuration);
85
        $helper->addDefaultRouteParameters($configuration);
86
        $helper->addDefaultFormUse($configuration);
87
        $helper->provideActionsFieldConfiguration($configuration, $event->getAdminName());
88
89
        // Menus
90
        $this->addDefaultRightMenu($configuration);
91
        $this->addDefaultLeftMenu($configuration);
92
        $this->addDefaultTopMenu($configuration, $event->getAdminName());
93
94
        // Filters
95
        $this->addDefaultFilters($configuration);
96
97
        $event->setConfiguration($configuration);
98
    }
99
100
    public function enrichMenuConfiguration(MenuConfigurationEvent $event)
101
    {
102
        if (!$this->isExtraConfigurationEnabled()) {
103
            return;
104
        }
105
        $configuration = $event->getMenuConfigurations();
106
107
        if (!key_exists('top', $configuration) || [] === $configuration['top']) {
108
            $configuration['top'] = [
109
                'brand' => $this->applicationConfiguration->getParameter('title'),
110
            ];
111
        }
112
113
        if (!key_exists('left', $configuration) || [] === $configuration['left']) {
114
            $configuration['left'] = $this->configurationFactory->createResourceMenuConfiguration();
115
        }
116
117
        $event->setMenuConfigurations($configuration);
118
    }
119
120
    /**
121
     * Defines the default CRUD actions if no action was configured.
122
     *
123
     * @param array $configuration
124
     */
125
    private function addDefaultActions(array &$configuration)
126
    {
127
        if (!key_exists('actions', $configuration) || !is_array($configuration['actions'])) {
128
            $configuration['actions'] = [];
129
        }
130
131
        if (0 !== count($configuration['actions'])) {
132
            return;
133
        }
134
        $configuration['actions'] = [
135
            'create' => [],
136
            'list' => [],
137
            'edit' => [],
138
            'delete' => [],
139
        ];
140
    }
141
142
    /**
143
     * Add the default left menu configuration. One item for each Admin.
144
     *
145
     * @param array $configuration
146
     */
147
    private function addDefaultLeftMenu(array &$configuration)
148
    {
149
        if (!$this->applicationConfiguration->getParameter('enable_menus')) {
150
            return;
151
        }
152
        $menus = $this->configurationFactory->createResourceMenuConfiguration();
153
154
        // Add the resources menu for each action of the admin
155
        foreach ($configuration['actions'] as $name => $action) {
156
            if (key_exists('menus', $action) && key_exists('left', $action)) {
157
                continue;
158
            }
159
160
            $configuration['actions'][$name]['menus']['left'] = $menus;
161
        }
162
    }
163
164
    /**
165
     * Add the default right menu.
166
     *
167
     * @param array  $configuration
168
     */
169
    private function addDefaultRightMenu(array &$configuration)
170
    {
171
        if (!$this->applicationConfiguration->getParameter('enable_menus')) {
172
            return;
173
        }
174
175
        if (!key_exists('list', $configuration['actions'])) {
176
            return;
177
        }
178
179
        if (
180
            key_exists('menus', $configuration['actions']['list']) &&
181
            is_array($configuration['actions']['list']['menus']) &&
182
            key_exists('right', $configuration['actions']['list']['menus'])
183
        ) {
184
            return;
185
        }
186
187
        $configuration['actions']['list']['menus']['right'] = [];
188
    }
189
190
    private function addDefaultTopMenu(array &$configuration, string $adminName)
191
    {
192
        if (!$this->applicationConfiguration->getParameter('enable_menus')) {
193
            return;
194
        }
195
196 View Code Duplication
        if (key_exists('list', $configuration['actions'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
197
            // Add a "Create" link in the top bar if the create action is allowed
198
            if (!key_exists('create', $configuration['actions'])) {
199
                return;
200
            }
201
            $configuration['actions']['list']['menus']['top']['items'][] = [
202
                'admin' => $adminName,
203
                'action' => 'create',
204
                'text' => StringUtils::getTranslationKey(
205
                    $this->applicationConfiguration->getParameter('translation_pattern'),
206
                    $adminName,
207
                    'create'
208
                ),
209
                'icon' => 'plus',
210
            ];
211
        }
212
213 View Code Duplication
        if (key_exists('create', $configuration['actions'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
214
            // Add a "Return" link in the top bar if the list action is allowed
215
            if (!key_exists('list', $configuration['actions'])) {
216
                return;
217
            }
218
            $configuration['actions']['create']['menus']['top']['items'][] = [
219
                'admin' => $adminName,
220
                'action' => 'list',
221
                'text' => StringUtils::getTranslationKey(
222
                    $this->applicationConfiguration->getParameter('translation_pattern'),
223
                    $adminName,
224
                    'return'
225
                ),
226
                'icon' => 'arrow-left',
227
            ];
228
        }
229
230
        if (key_exists('edit', $configuration['actions'])) {
231
            // Add a "Return" link in the top bar if the list action is allowed
232
            if (!key_exists('list', $configuration['actions'])) {
233
                return;
234
            }
235
236
            if (!key_exists('menus', $configuration['actions']['edit'])) {
237
                $configuration['actions']['edit']['menus'] = [];
238
            }
239
240 View Code Duplication
            if (!key_exists('top', $configuration['actions']['edit']['menus'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
241
                $configuration['actions']['edit']['menus']['top'] = [];
242
            }
243
244 View Code Duplication
            if (!key_exists('items', $configuration['actions']['edit']['menus']['top'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
245
                $configuration['actions']['edit']['menus']['top']['items'] = [];
246
            }
247
            array_unshift($configuration['actions']['edit']['menus']['top']['items'], [
248
                'admin' => $adminName,
249
                'action' => 'list',
250
                'text' => StringUtils::getTranslationKey(
251
                    $this->applicationConfiguration->getParameter('translation_pattern'),
252
                    $adminName,
253
                    'return'
254
                ),
255
                'icon' => 'arrow-left',
256
            ]);
257
        }
258
    }
259
260
261
262
    /**
263
     * Add default filters for the list actions, guessed using the entity metadata.
264
     *
265
     * @param array $configuration
266
     */
267
    private function addDefaultFilters(array &$configuration)
268
    {
269
        // Add the filters only for the "list" action
270
        if (!key_exists('list', $configuration['actions'])) {
271
            return;
272
        }
273
274
        // If some filters are already configured, we do not add the default filters
275
        if (key_exists('filter', $configuration['actions']['list'])) {
276
            return;
277
        }
278
        $metadata = $this->findMetadata($configuration['entity']);
279
280
        if (null === $metadata) {
281
            return;
282
        }
283
        $filters = [];
284
285
        foreach ($metadata->getFieldNames() as $fieldName) {
286
            $type = $metadata->getTypeOfField($fieldName);
287
            $operator = $this->getOperatorFromFieldType($type);
288
289
            $filters[$fieldName] = [
290
                'type' => $type,
291
                'options' => [],
292
                'comparator' => $operator,
293
            ];
294
        }
295
        $configuration['actions']['list']['filters'] = $filters;
296
    }
297
298
299
300
    private function getOperatorFromFieldType($type)
301
    {
302
        $mapping = [
303
            'string' => 'like',
304
            'text' => 'like',
305
        ];
306
307
        if (key_exists($type, $mapping)) {
308
            return $mapping[$type];
309
        }
310
311
        return '=';
312
    }
313
314
    /**
315
     * @return bool
316
     */
317
    private function isExtraConfigurationEnabled(): bool
318
    {
319
        return $this->applicationConfiguration->getParameter('enable_extra_configuration');
320
    }
321
}
322