Completed
Push — master ( e8bfce...313e31 )
by Arnaud
13s queued 11s
created

AdminSubscriber::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 8
nc 1
nop 8
dl 0
loc 18
ccs 9
cts 9
cp 1
crap 1
rs 10
c 2
b 0
f 1

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
namespace LAG\AdminBundle\Event\Subscriber;
4
5
use Doctrine\Common\Collections\ArrayCollection;
6
use LAG\AdminBundle\Admin\ActionInterface;
7
use LAG\AdminBundle\Admin\AdminInterface;
8
use LAG\AdminBundle\Admin\Helper\AdminHelperInterface;
9
use LAG\AdminBundle\Configuration\AdminConfiguration;
10
use LAG\AdminBundle\Event\Events;
11
use LAG\AdminBundle\Event\Events\AdminEvent;
12
use LAG\AdminBundle\Event\Events\EntityEvent;
13
use LAG\AdminBundle\Event\Events\ViewEvent;
14
use LAG\AdminBundle\Exception\Exception;
15
use LAG\AdminBundle\Factory\ActionFactory;
16
use LAG\AdminBundle\Factory\DataProviderFactory;
17
use LAG\AdminBundle\Factory\ViewFactory;
18
use LAG\AdminBundle\LAGAdminBundle;
19
use LAG\AdminBundle\Routing\RoutingLoader;
20
use LAG\AdminBundle\Utils\TranslationUtils;
21
use LAG\AdminBundle\View\RedirectView;
22
use LAG\AdminBundle\View\ViewHelper;
23
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\HttpFoundation\Session\Session;
26
use Symfony\Component\HttpFoundation\Session\SessionInterface;
27
use Symfony\Component\Routing\RouterInterface;
28
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
29
use Symfony\Contracts\Translation\TranslatorInterface;
30
31
class AdminSubscriber implements EventSubscriberInterface
32
{
33
    /**
34
     * @var ActionFactory
35
     */
36
    private $actionFactory;
37
38
    /**
39
     * @var ViewFactory
40
     */
41
    private $viewFactory;
42
43
    /**
44
     * @var EventDispatcherInterface
45
     */
46
    private $eventDispatcher;
47
48
    /**
49
     * @var DataProviderFactory
50
     */
51
    private $dataProviderFactory;
52
53
    /**
54
     * @var Session|SessionInterface
55
     */
56
    private $session;
57
58
    /**
59
     * @var TranslatorInterface
60
     */
61
    private $translator;
62
63
    /**
64
     * @var RouterInterface
65
     */
66
    private $router;
67
68
    /**
69
     * @var AdminHelperInterface
70
     */
71
    private $helper;
72
73
    /**
74
     * @return array
75
     */
76 6
    public static function getSubscribedEvents()
77
    {
78
        return [
79 6
            Events::ADMIN_HANDLE_REQUEST => 'handleRequest',
80
            Events::ADMIN_VIEW => 'createView',
81
            Events::ENTITY_LOAD => [
82
                'loadEntities', 255,
83
            ],
84
            Events::ENTITY_SAVE => 'saveEntity',
85
        ];
86
    }
87
88
    /**
89
     * AdminSubscriber constructor.
90
     */
91 24
    public function __construct(
92
        ActionFactory $actionFactory,
93
        ViewFactory $viewFactory,
94
        DataProviderFactory $dataProviderFactory,
95
        EventDispatcherInterface $eventDispatcher,
96
        SessionInterface $session,
97
        TranslatorInterface $translator,
98
        RouterInterface $router,
99
        AdminHelperInterface $helper
100
    ) {
101 24
        $this->actionFactory = $actionFactory;
102 24
        $this->viewFactory = $viewFactory;
103 24
        $this->eventDispatcher = $eventDispatcher;
104 24
        $this->dataProviderFactory = $dataProviderFactory;
105 24
        $this->session = $session;
106 24
        $this->translator = $translator;
107 24
        $this->router = $router;
108 24
        $this->helper = $helper;
109 24
    }
110
111
    /**
112
     * Define the current action according to the routing configuration.
113
     *
114
     * @throws Exception
115
     */
116 4
    public function handleRequest(AdminEvent $event)
117
    {
118 4
        $actionName = $event->getRequest()->get('_action');
119
120 4
        if (null === $actionName) {
121 2
            throw new Exception('The _action was not found in the request');
122
        }
123 2
        $admin = $event->getAdmin();
124 2
        $this->helper->setCurrent($admin);
125 2
        $action = $this->actionFactory->create($actionName, $admin->getName(), $admin->getConfiguration());
126
127 2
        $event->setAction($action);
128 2
    }
129
130
    /**
131
     * Create a view using the view factory.
132
     */
133 8
    public function createView(ViewEvent $event)
134
    {
135 8
        $admin = $event->getAdmin();
136 8
        $action = $admin->getAction();
137 8
        $formName = '';
138
139
        // The form name is different according to the current action
140 8
        if ('edit' === $action->getName()) {
141 4
            $formName = 'entity';
142 4
        } elseif ('create' === $action->getName()) {
143 2
            $formName = 'entity';
144 2
        } elseif ('delete' === $action->getName()) {
145 2
            $formName = 'delete';
146
        }
147 8
        $viewHelper = new ViewHelper();
148
149 8
        if ($viewHelper->shouldRedirect($event->getRequest(), $admin->getConfiguration(), $admin, $action, $formName)) {
150
            $url = $this->getRedirectionUrl(
151
                $admin,
152
                $action,
153
                $admin->getConfiguration(),
154
                $event->getRequest()
155
            );
156
157
            $view = new RedirectView(
158
                $action->getName(),
159
                $admin->getName(),
160
                $action->getConfiguration(),
161
                $admin->getConfiguration()
162
            );
163
            $view->setUrl($url);
164
        } else {
165 8
            $view = $this->viewFactory->create(
166 8
                $event->getRequest(),
167 8
                $action->getName(),
168 8
                $admin->getName(),
169 8
                $admin->getConfiguration(),
170 8
                $action->getConfiguration(),
171 8
                $admin->getEntities(),
172 8
                $admin->getForms()
173
            );
174
        }
175 8
        $event->setView($view);
176 8
    }
177
178
    /**
179
     * Load entities into the event data to pass them to the Admin.
180
     *
181
     * @throws Exception
182
     */
183 8
    public function loadEntities(EntityEvent $event)
184
    {
185 8
        $admin = $event->getAdmin();
186 8
        $configuration = $admin->getConfiguration();
187 8
        $actionConfiguration = $admin->getAction()->getConfiguration();
188
189 8
        $dataProvider = $this->dataProviderFactory->get($configuration->getParameter('data_provider'));
190 8
        $strategy = $actionConfiguration->getParameter('load_strategy');
191 8
        $class = $configuration->getParameter('entity');
192
193 8
        if (LAGAdminBundle::LOAD_STRATEGY_NONE === $strategy) {
194 2
            return;
195 6
        } elseif (LAGAdminBundle::LOAD_STRATEGY_MULTIPLE === $strategy) {
196 2
            $entities = $dataProvider->getCollection($admin, $event->getFilters());
197 2
            $event->setEntities($entities);
198 4
        } elseif (LAGAdminBundle::LOAD_STRATEGY_UNIQUE === $strategy) {
199 4
            $requirements = $actionConfiguration->getParameter('route_requirements');
200 4
            $identifier = null;
201
202 4
            foreach ($requirements as $name => $requirement) {
203 4
                if (null !== $event->getRequest()->get($name)) {
204 2
                    $identifier = $event->getRequest()->get($name);
205 2
                    break;
206
                }
207
            }
208
209 4
            if (null === $identifier) {
210 2
                throw new Exception('Unable to find a identifier for the class "'.$class.'"');
211
            }
212 2
            $entity = $dataProvider->get($admin, $identifier);
213
214 2
            $event->setEntities(new ArrayCollection([
215 2
                $entity,
216
            ]));
217
        }
218 4
    }
219
220
    /**
221
     * Save an entity.
222
     */
223 2
    public function saveEntity(EntityEvent $event)
224
    {
225 2
        $admin = $event->getAdmin();
226 2
        $configuration = $admin->getConfiguration();
227
228
        // Save the entity changes using the configured data provider
229
        $dataProvider = $this
230 2
            ->dataProviderFactory
231 2
            ->get($configuration->getParameter('data_provider'))
232
        ;
233 2
        $dataProvider->save($admin);
234
235
        // Inform the user that the save is successful
236 2
        $message = $this->translateMessage('saved', $admin->getName(), $configuration);
237
238
        $this
239 2
            ->session
240 2
            ->getFlashBag()
241 2
            ->add('success', $message)
242
        ;
243 2
    }
244
245 2
    private function translateMessage(string $message, string $adminName, AdminConfiguration $configuration): string
246
    {
247 2
        if (!$configuration->isTranslationEnabled()) {
248 2
            return $message;
249
        }
250
        $message = TranslationUtils::getTranslationKey($configuration->getTranslationPattern(), $adminName, $message);
251
252
        return $this->translator->trans($message, [], $configuration->getTranslationCatalog());
253
    }
254
255
    /**
256
     * Return the url where the user should be redirected to. An exception will be thrown if no url can be generated.
257
     *
258
     * @throws Exception
259
     */
260
    private function getRedirectionUrl(
261
        AdminInterface $admin,
262
        ActionInterface $action,
263
        AdminConfiguration $configuration,
264
        Request $request
265
    ): string {
266
        if ('edit' === $action->getName()) {
267
            $routeName = RoutingLoader::generateRouteName(
268
                $admin->getName(),
269
                'list',
270
                $configuration->get('routing_name_pattern')
271
            );
272
            $url = $this->router->generate($routeName);
273
274
            return $url;
275
        }
276
277
        // When the create form is submitted, the user should be redirected to the edit action after saving the form
278
        // data
279
        if ('create' === $action->getName()) {
280
            $targetAction = 'list';
281
            $routeParameters = [];
282
283
            if (!$request->get('submit_and_redirect')) {
284
                $targetAction = 'edit';
285
                $routeParameters = [
286
                    'id' => $admin->getEntities()->first()->getId(),
287
                ];
288
            }
289
            $routeName = RoutingLoader::generateRouteName(
290
                $admin->getName(),
291
                $targetAction,
292
                $configuration->get('routing_name_pattern')
293
            );
294
            $url = $this->router->generate($routeName, $routeParameters);
295
296
            return $url;
297
        }
298
299
        if ('delete' === $action->getName()) {
300
            $routeName = RoutingLoader::generateRouteName(
301
                $admin->getName(),
302
                'list',
303
                $configuration->get('routing_name_pattern')
304
            );
305
            $url = $this->router->generate($routeName);
306
307
            return $url;
308
        }
309
310
        throw new Exception('Unable to generate an redirection url for the current action');
311
    }
312
}
313