Completed
Push — dev ( c656a3...5504ea )
by Arnaud
03:07
created

ExtraConfigurationSubscriber::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 4
Bugs 2 Features 1
Metric Value
c 4
b 2
f 1
dl 0
loc 10
ccs 0
cts 5
cp 0
rs 9.4285
cc 1
eloc 7
nc 1
nop 3
crap 2
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\Configuration\ApplicationConfiguration;
9
use LAG\AdminBundle\Event\AdminEvent;
10
use LAG\AdminBundle\Utils\FieldTypeGuesser;
11
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
12
13
/**
14
 * Add extra default configuration for actions and fields. Bind to ADMIN_CREATE and ACTION_CREATE events
15
 */
16
class ExtraConfigurationSubscriber implements EventSubscriberInterface
17
{
18
    /**
19
     * @var bool
20
     */
21
    protected $enableExtraConfiguration;
22
23
    /**
24
     * @var EntityManager
25
     */
26
    protected $entityManager;
27
28
    /**
29
     * @var ApplicationConfiguration
30
     */
31
    protected $applicationConfiguration;
32
33
    /**
34
     * @return array
35
     */
36 1
    public static function getSubscribedEvents()
37
    {
38
        return [
39 1
            AdminEvent::ADMIN_CREATE => 'adminCreate',
40 1
            AdminEvent::ACTION_CREATE => 'actionCreate',
41 1
        ];
42
    }
43
44
    /**
45
     * ExtraConfigurationSubscriber constructor
46
     *
47
     * @param bool $enableExtraConfiguration
48
     * @param Registry $doctrine
49
     * @param ApplicationConfiguration $applicationConfiguration
50
     */
51
    public function __construct(
52
        $enableExtraConfiguration = true,
53
        Registry $doctrine,
54
        ApplicationConfiguration $applicationConfiguration
55
    ) {
56
        $this->enableExtraConfiguration = $enableExtraConfiguration;
57
        // entity manager can be closed. Scrutinizer recommands to inject registry instead
58
        $this->entityManager = $doctrine->getManager();
59
        $this->applicationConfiguration = $applicationConfiguration;
60
    }
61
62
    /**
63
     * Adding default CRUD if none is defined
64
     *
65
     * @param AdminEvent $event
66
     */
67
    public function adminCreate(AdminEvent $event)
68
    {
69
        if (!$this->enableExtraConfiguration) {
70
            return;
71
        }
72
        $configuration = $event->getConfiguration();
73
74
        // if no actions are defined, we set default CRUD action
75
        if (!array_key_exists('actions', $configuration) || !count($configuration['actions'])) {
76
            $configuration['actions'] = [
77
                'create' => [],
78
                'list' => [],
79
                'edit' => [],
80
                'delete' => [],
81
                'batch' => []
82
            ];
83
        } else {
84
            $actions = $configuration['actions'];
85
86
            foreach ($actions as $name => $action) {
87
                if (!array_key_exists('batch', $action) || $action['batch'] !== false) {
88
                    if ($name == 'list') {
89
                        $configuration['actions']['batch'] = [];
90
                    }
91
                }
92
            }
93
        }
94
        $event->setConfiguration($configuration);
95
    }
96
97
    /**
98
     * Add default linked actions and default menu actions
99
     *
100
     * @param AdminEvent $event
101
     * @throws MappingException
102
     */
103
    public function actionCreate(AdminEvent $event)
104
    {
105
        // add configuration only if extra configuration is enabled
106
        if (!$this->enableExtraConfiguration) {
107
            return;
108
        }
109
        // action configuration array
110
        $configuration = $event->getConfiguration();
111
        // current action admin
112
        $admin = $event->getAdmin();
113
        // allowed actions according to the admin
114
        $keys = $admin
115
            ->getConfiguration()
116
            ->getActions();
117
        $allowedActions = array_keys($keys);
118
119
        // if no field was provided in configuration, we try to take fields from doctrine metadata
120
        if (empty($configuration['fields']) || !count($configuration['fields'])) {
121
            $fields = [];
122
            $guesser = new FieldTypeGuesser();
123
            $metadata = $this
124
                ->entityManager
125
                ->getMetadataFactory()
126
                ->getMetadataFor($admin->getConfiguration()->getEntityName());
127
            $fieldsName = $metadata->getFieldNames();
128
129
            foreach ($fieldsName as $name) {
130
                $type = $metadata->getTypeOfField($name);
131
                // get field type from doctrine type
132
                $fieldConfiguration = $guesser->getTypeAndOptions($type);
133
134
                // if a field configuration was found, we take it
135
                if (count($fieldConfiguration)) {
136
                    $fields[$name] = $fieldConfiguration;
137
                }
138
            }
139
            if (count($fields)) {
140
                // adding new fields to action configuration
141
                $configuration['fields'] = $fields;
142
            }
143
        }
144
        // configured linked actions
145
        if (array_key_exists('_actions', $configuration['fields'])
146
            && !array_key_exists('type', $configuration['fields']['_actions'])
147
        ) {
148
            // in list view, we add by default and an edit and a delete button
149
            if ($event->getActionName() == 'list') {
150 View Code Duplication
                if (in_array('edit', $allowedActions)) {
151
                    $configuration['fields']['_actions']['type'] = 'collection';
152
                    $configuration['fields']['_actions']['options']['_edit'] = [
153
                        'type' => 'action',
154
                        'options' => [
155
                            'title' => $this->applicationConfiguration->getTranslationKey('edit', $event->getAdmin()->getName()),
156
                            'route' => $admin->generateRouteName('edit'),
157
                            'parameters' => [
158
                                'id' => false
159
                            ],
160
                            'icon' => 'pencil'
161
                        ]
162
                    ];
163
                }
164 View Code Duplication
                if (in_array('delete', $allowedActions)) {
165
                    $configuration['fields']['_actions']['type'] = 'collection';
166
                    $configuration['fields']['_actions']['options']['_delete'] = [
167
                        'type' => 'action',
168
                        'options' => [
169
                            'title' => $this->applicationConfiguration->getTranslationKey('delete', $event->getAdmin()->getName()),
170
                            'route' => $admin->generateRouteName('delete'),
171
                            'parameters' => [
172
                                'id' => false
173
                            ],
174
                            'icon' => 'remove'
175
                        ]
176
                    ];
177
                }
178
            }
179
        }
180
        // add default menu actions if none was provided
181
        if (empty($configuration['actions'])) {
182
            // by default, in list action we add a create linked action
183
            if ($event->getActionName() == 'list') {
184
                if (in_array('create', $allowedActions)) {
185
                    $configuration['actions']['create'] = [
186
                        'title' => $this->applicationConfiguration->getTranslationKey('create', $event->getAdmin()->getName()),
187
                        'route' => $admin->generateRouteName('create'),
188
                        'icon' => 'pencil'
189
                    ];
190
                }
191
            }
192
        }
193
        // for list action, add the delete batch action by defaut
194
        if (empty($configuration['batch'])) {
195
            if ($event->getActionName() == 'list') {
196
                $configuration['batch'] = [
197
                    'delete' => null
198
                ];
199
            }
200
        }
201
        // reset action configuration
202
        $event->setConfiguration($configuration);
203
    }
204
}
205