Completed
Branch master (01610a)
by Arnaud
06:29
created

ExtraConfigurationSubscriber::actionCreate()   D

Complexity

Conditions 14
Paths 41

Size

Total Lines 100
Code Lines 59

Duplication

Lines 28
Ratio 28 %

Code Coverage

Tests 19
CRAP Score 80.768

Importance

Changes 11
Bugs 2 Features 2
Metric Value
c 11
b 2
f 2
dl 28
loc 100
ccs 19
cts 63
cp 0.3016
rs 4.9516
cc 14
eloc 59
nc 41
nop 1
crap 80.768

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\Bundle\DoctrineBundle\Registry;
6
use Doctrine\Common\Persistence\Mapping\MappingException;
7
use Doctrine\ORM\EntityManager;
8
use LAG\AdminBundle\Admin\Behaviors\TranslationKeyTrait;
9
use LAG\AdminBundle\Application\Configuration\ApplicationConfiguration;
10
use LAG\AdminBundle\Configuration\Factory\ConfigurationFactory;
11
use LAG\AdminBundle\Event\AdminEvent;
12
use LAG\AdminBundle\Utils\FieldTypeGuesser;
13
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
14
use Symfony\Component\OptionsResolver\OptionsResolver;
15
16
/**
17
 * Add extra default configuration for actions and fields. Bind to ADMIN_CREATE and ACTION_CREATE events
18
 */
19
class ExtraConfigurationSubscriber implements EventSubscriberInterface
20
{
21
    use TranslationKeyTrait;
22
23
    /**
24
     * If is true, the extra configuration will be added.
25
     *
26
     * @var bool
27
     */
28
    protected $extraConfigurationEnabled = false;
29
30
    /**
31
     * @var EntityManager
32
     */
33
    protected $entityManager;
34
35
    /**
36
     * @var ApplicationConfiguration
37
     */
38
    protected $applicationConfiguration;
39
40
    /**
41
     * @return array
42
     */
43 1
    public static function getSubscribedEvents()
44
    {
45
        return [
46 1
            AdminEvent::ADMIN_CREATE => 'adminCreate',
47 1
            AdminEvent::ACTION_CREATE => 'actionCreate',
48 1
        ];
49
    }
50
51
    /**
52
     * ExtraConfigurationSubscriber constructor.
53
     *
54
     * @param bool $extraConfigurationEnabled
55
     * @param Registry $doctrine
56
     * @param ConfigurationFactory $configurationFactory
57
     */
58 3
    public function __construct(
59
        $extraConfigurationEnabled = true,
60
        Registry $doctrine,
61
        ConfigurationFactory $configurationFactory
62
    ) {
63 3
        $this->extraConfigurationEnabled = $extraConfigurationEnabled;
64
        // entity manager can be closed, so its better to inject the Doctrine registry instead
65 3
        $this->entityManager = $doctrine->getManager();
66 3
        $this->applicationConfiguration = $configurationFactory->getApplicationConfiguration();
67 3
    }
68
69
    /**
70
     * Adding default CRUD if none is defined.
71
     *
72
     * @param AdminEvent $event
73
     */
74 2
    public function adminCreate(AdminEvent $event)
75
    {
76 2
        if (!$this->extraConfigurationEnabled) {
77 2
            return;
78
        }
79 1
        $configuration = $event->getConfiguration();
80
81
        // if no actions are defined, we set default CRUD action
82 1
        if (!array_key_exists('actions', $configuration) || !count($configuration['actions'])) {
83 1
            $configuration['actions'] = [
84 1
                'create' => [],
85 1
                'list' => [],
86 1
                'edit' => [],
87 1
                'delete' => [],
88 1
                'batch' => []
89 1
            ];
90 1
            $event->setConfiguration($configuration);
91 1
        }
92 1
    }
93
94
    /**
95
     * Add default linked actions and default menu actions.
96
     *
97
     * @param AdminEvent $event
98
     * @throws MappingException
99
     */
100 1
    public function actionCreate(AdminEvent $event)
101
    {
102
        // add configuration only if extra configuration is enabled
103 1
        if (!$this->extraConfigurationEnabled) {
104
            return;
105
        }
106
        // action configuration array
107 1
        $configuration = $event->getConfiguration();
108
        // current action admin
109 1
        $admin = $event->getAdmin();
110
        // allowed actions according to the admin
111
        $keys = $admin
112 1
            ->getConfiguration()
113 1
            ->getParameter('actions');
114 1
        $allowedActions = array_keys($keys);
115
116
        // add default menu configuration
117 1
        $configuration = $this->addDefaultMenuConfiguration(
118 1
            $admin->getName(),
119 1
            $event->getActionName(),
120 1
            $configuration,
121
            $allowedActions
122 1
        );
123
124
        // if no field was provided in configuration, we try to take fields from doctrine metadata
125 1
        if (empty($configuration['fields']) || !count($configuration['fields'])) {
126
            $fields = [];
127
            $guesser = new FieldTypeGuesser();
128
            $metadata = $this
129
                ->entityManager
130
                ->getMetadataFactory()
131
                ->getMetadataFor($admin->getConfiguration()->getParameter('entity'));
132
            $fieldsName = $metadata->getFieldNames();
133
134
            foreach ($fieldsName as $name) {
135
                $type = $metadata->getTypeOfField($name);
136
                // get field type from doctrine type
137
                $fieldConfiguration = $guesser->getTypeAndOptions($type);
138
139
                // if a field configuration was found, we take it
140
                if (count($fieldConfiguration)) {
141
                    $fields[$name] = $fieldConfiguration;
142
                }
143
            }
144
            if (count($fields)) {
145
                // adding new fields to action configuration
146
                $configuration['fields'] = $fields;
147
148
                if ($event->getActionName() == 'list') {
149
                    $configuration['fields']['_actions'] = null;
150
                }
151
            }
152
        }
153
        // configured linked actions :
154
        // _action key should exists and be null
155 1
        $_actionExists = array_key_exists('_actions', $configuration['fields']);
156 1
        $_actionIsNull = $_actionExists && $configuration['fields']['_actions'] === null;
157
        // _action is added extra configuration only for the "list" action
158 1
        $isListAction = $event->getActionName() == 'list';
159
160 1
        if ($_actionExists && $_actionIsNull && $isListAction) {
161
            // in list view, we add by default and an edit and a delete button
162
            $translationPattern = $this
163
                ->applicationConfiguration
164
                ->getParameter('translation')['pattern'];
165
166
            // add a link to the "edit" action, if it is allowed
167 View Code Duplication
            if (in_array('edit', $allowedActions)) {
168
                $configuration['fields']['_actions']['type'] = 'collection';
169
                $configuration['fields']['_actions']['options']['_edit'] = [
170
                    'type' => 'action',
171
                    'options' => [
172
                        'title' => $this->getTranslationKey($translationPattern, 'edit', $event->getAdmin()->getName()),
173
                        'route' => $admin->generateRouteName('edit'),
174
                        'parameters' => [
175
                            'id' => false
176
                        ],
177
                        'icon' => 'pencil'
178
                    ]
179
                ];
180
            }
181
            // add a link to the "delete" action, if it is allowed
182 View Code Duplication
            if (in_array('delete', $allowedActions)) {
183
                $configuration['fields']['_actions']['type'] = 'collection';
184
                $configuration['fields']['_actions']['options']['_delete'] = [
185
                    'type' => 'action',
186
                    'options' => [
187
                        'title' => $this->getTranslationKey($translationPattern, 'delete', $event->getAdmin()->getName()),
188
                        'route' => $admin->generateRouteName('delete'),
189
                        'parameters' => [
190
                            'id' => false
191
                        ],
192
                        'icon' => 'remove'
193
                    ]
194
                ];
195
            }
196
        }
197
        // reset action configuration
198 1
        $event->setConfiguration($configuration);
199 1
    }
200
201
    /**
202
     * Add default menu configuration for an action.
203
     *
204
     * @param string $admiName
205
     * @param string $actionName
206
     * @param array $actionConfiguration
207
     * @param array $allowedActions
208
     * @return array The modified configuration
209
     */
210 1
    protected function addDefaultMenuConfiguration($admiName, $actionName, array $actionConfiguration, array $allowedActions)
211
    {
212
        // we add a default top menu item "create" only for list action
213 1
        if ($actionName === 'list') {
214
215
            // the create action should enabled
216 1
            if (in_array('create', $allowedActions)) {
217
218 1
                if (!array_key_exists('menus', $actionConfiguration)) {
219 1
                    $actionConfiguration['menus'] = [];
220 1
                }
221
                // if the menu is disabled we do not add the menu item
222 1
                if ($actionConfiguration['menus'] !== false) {
223 1
                    $resolver = new OptionsResolver();
224 1
                    $resolver->setDefaults([
225
                        'top' => [
226
                            'items' => [
227
                                'create' => [
228 1
                                    'admin' => $admiName,
229 1
                                    'action' => 'create',
230 1
                                    'icon' => 'fa fa-plus',
231
                                ]
232 1
                            ]
233 1
                        ]
234 1
                    ]);
235
                    // resolve default menu options
236 1
                    $actionConfiguration['menus'] = $resolver->resolve($actionConfiguration['menus']);
237 1
                }
238 1
            }
239 1
        }
240
241 1
        return $actionConfiguration;
242
    }
243
}
244