Completed
Push — 1.0 ( 3a78b4...c03df0 )
by Kamil
45:57 queued 15:08
created

ResourceController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 37
rs 9.328
c 0
b 0
f 0
cc 1
nc 1
nop 17

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 Sylius package.
5
 *
6
 * (c) Paweł Jędrzejewski
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
declare(strict_types=1);
13
14
namespace Sylius\Bundle\ResourceBundle\Controller;
15
16
use Doctrine\Common\Persistence\ObjectManager;
17
use FOS\RestBundle\View\View;
18
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
19
use Sylius\Component\Resource\Exception\DeleteHandlingException;
20
use Sylius\Component\Resource\Exception\UpdateHandlingException;
21
use Sylius\Component\Resource\Factory\FactoryInterface;
22
use Sylius\Component\Resource\Metadata\MetadataInterface;
23
use Sylius\Component\Resource\Model\ResourceInterface;
24
use Sylius\Component\Resource\Repository\RepositoryInterface;
25
use Sylius\Component\Resource\ResourceActions;
26
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\HttpFoundation\Response;
29
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
30
use Symfony\Component\HttpKernel\Exception\HttpException;
31
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
32
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
33
34
class ResourceController extends Controller
35
{
36
    /**
37
     * @var MetadataInterface
38
     */
39
    protected $metadata;
40
41
    /**
42
     * @var RequestConfigurationFactoryInterface
43
     */
44
    protected $requestConfigurationFactory;
45
46
    /**
47
     * @var ViewHandlerInterface
48
     */
49
    protected $viewHandler;
50
51
    /**
52
     * @var RepositoryInterface
53
     */
54
    protected $repository;
55
56
    /**
57
     * @var FactoryInterface
58
     */
59
    protected $factory;
60
61
    /**
62
     * @var NewResourceFactoryInterface
63
     */
64
    protected $newResourceFactory;
65
66
    /**
67
     * @var ObjectManager
68
     */
69
    protected $manager;
70
71
    /**
72
     * @var SingleResourceProviderInterface
73
     */
74
    protected $singleResourceProvider;
75
76
    /**
77
     * @var ResourcesCollectionProviderInterface
78
     */
79
    protected $resourcesCollectionProvider;
80
81
    /**
82
     * @var ResourceFormFactoryInterface
83
     */
84
    protected $resourceFormFactory;
85
86
    /**
87
     * @var RedirectHandlerInterface
88
     */
89
    protected $redirectHandler;
90
91
    /**
92
     * @var FlashHelperInterface
93
     */
94
    protected $flashHelper;
95
96
    /**
97
     * @var AuthorizationCheckerInterface
98
     */
99
    protected $authorizationChecker;
100
101
    /**
102
     * @var EventDispatcherInterface
103
     */
104
    protected $eventDispatcher;
105
106
    /**
107
     * @var StateMachineInterface
108
     */
109
    protected $stateMachine;
110
111
    /**
112
     * @var ResourceUpdateHandlerInterface
113
     */
114
    protected $resourceUpdateHandler;
115
116
    /**
117
     * @var ResourceDeleteHandlerInterface
118
     */
119
    protected $resourceDeleteHandler;
120
121
    /**
122
     * @param MetadataInterface $metadata
123
     * @param RequestConfigurationFactoryInterface $requestConfigurationFactory
124
     * @param ViewHandlerInterface $viewHandler
125
     * @param RepositoryInterface $repository
126
     * @param FactoryInterface $factory
127
     * @param NewResourceFactoryInterface $newResourceFactory
128
     * @param ObjectManager $manager
129
     * @param SingleResourceProviderInterface $singleResourceProvider
130
     * @param ResourcesCollectionProviderInterface $resourcesFinder
131
     * @param ResourceFormFactoryInterface $resourceFormFactory
132
     * @param RedirectHandlerInterface $redirectHandler
133
     * @param FlashHelperInterface $flashHelper
134
     * @param AuthorizationCheckerInterface $authorizationChecker
135
     * @param EventDispatcherInterface $eventDispatcher
136
     * @param StateMachineInterface $stateMachine
137
     * @param ResourceUpdateHandlerInterface $resourceUpdateHandler
138
     * @param ResourceDeleteHandlerInterface $resourceDeleteHandler
139
     */
140
    public function __construct(
141
        MetadataInterface $metadata,
142
        RequestConfigurationFactoryInterface $requestConfigurationFactory,
143
        ViewHandlerInterface $viewHandler,
144
        RepositoryInterface $repository,
145
        FactoryInterface $factory,
146
        NewResourceFactoryInterface $newResourceFactory,
147
        ObjectManager $manager,
148
        SingleResourceProviderInterface $singleResourceProvider,
149
        ResourcesCollectionProviderInterface $resourcesFinder,
150
        ResourceFormFactoryInterface $resourceFormFactory,
151
        RedirectHandlerInterface $redirectHandler,
152
        FlashHelperInterface $flashHelper,
153
        AuthorizationCheckerInterface $authorizationChecker,
154
        EventDispatcherInterface $eventDispatcher,
155
        StateMachineInterface $stateMachine,
156
        ResourceUpdateHandlerInterface $resourceUpdateHandler,
157
        ResourceDeleteHandlerInterface $resourceDeleteHandler
158
    ) {
159
        $this->metadata = $metadata;
160
        $this->requestConfigurationFactory = $requestConfigurationFactory;
161
        $this->viewHandler = $viewHandler;
162
        $this->repository = $repository;
163
        $this->factory = $factory;
164
        $this->newResourceFactory = $newResourceFactory;
165
        $this->manager = $manager;
166
        $this->singleResourceProvider = $singleResourceProvider;
167
        $this->resourcesCollectionProvider = $resourcesFinder;
168
        $this->resourceFormFactory = $resourceFormFactory;
169
        $this->redirectHandler = $redirectHandler;
170
        $this->flashHelper = $flashHelper;
171
        $this->authorizationChecker = $authorizationChecker;
172
        $this->eventDispatcher = $eventDispatcher;
173
        $this->stateMachine = $stateMachine;
174
        $this->resourceUpdateHandler = $resourceUpdateHandler;
175
        $this->resourceDeleteHandler = $resourceDeleteHandler;
176
    }
177
178
    /**
179
     * @param Request $request
180
     *
181
     * @return Response
182
     */
183
    public function showAction(Request $request): Response
184
    {
185
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
186
187
        $this->isGrantedOr403($configuration, ResourceActions::SHOW);
188
        $resource = $this->findOr404($configuration);
189
190
        $this->eventDispatcher->dispatch(ResourceActions::SHOW, $configuration, $resource);
191
192
        $view = View::create($resource);
193
194
        if ($configuration->isHtmlRequest()) {
195
            $view
196
                ->setTemplate($configuration->getTemplate(ResourceActions::SHOW . '.html'))
197
                ->setTemplateVar($this->metadata->getName())
198
                ->setData([
199
                    'configuration' => $configuration,
200
                    'metadata' => $this->metadata,
201
                    'resource' => $resource,
202
                    $this->metadata->getName() => $resource,
203
                ])
204
            ;
205
        }
206
207
        return $this->viewHandler->handle($configuration, $view);
208
    }
209
210
    /**
211
     * @param Request $request
212
     *
213
     * @return Response
214
     */
215
    public function indexAction(Request $request): Response
216
    {
217
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
218
219
        $this->isGrantedOr403($configuration, ResourceActions::INDEX);
220
        $resources = $this->resourcesCollectionProvider->get($configuration, $this->repository);
221
222
        $this->eventDispatcher->dispatchMultiple(ResourceActions::INDEX, $configuration, $resources);
223
224
        $view = View::create($resources);
225
226
        if ($configuration->isHtmlRequest()) {
227
            $view
228
                ->setTemplate($configuration->getTemplate(ResourceActions::INDEX . '.html'))
229
                ->setTemplateVar($this->metadata->getPluralName())
230
                ->setData([
231
                    'configuration' => $configuration,
232
                    'metadata' => $this->metadata,
233
                    'resources' => $resources,
234
                    $this->metadata->getPluralName() => $resources,
235
                ])
236
            ;
237
        }
238
239
        return $this->viewHandler->handle($configuration, $view);
240
    }
241
242
    /**
243
     * @param Request $request
244
     *
245
     * @return Response
246
     */
247
    public function createAction(Request $request): Response
248
    {
249
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
250
251
        $this->isGrantedOr403($configuration, ResourceActions::CREATE);
252
        $newResource = $this->newResourceFactory->create($configuration, $this->factory);
253
254
        $form = $this->resourceFormFactory->create($configuration, $newResource);
255
256
        if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
257
            $newResource = $form->getData();
258
259
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource);
260
261
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
262
                throw new HttpException($event->getErrorCode(), $event->getMessage());
263
            }
264
            if ($event->isStopped()) {
265
                $this->flashHelper->addFlashFromEvent($configuration, $event);
266
267
                if ($event->hasResponse()) {
268
                    return $event->getResponse();
269
                }
270
271
                return $this->redirectHandler->redirectToIndex($configuration, $newResource);
272
            }
273
274
            if ($configuration->hasStateMachine()) {
275
                $this->stateMachine->apply($configuration, $newResource);
276
            }
277
278
            $this->repository->add($newResource);
279
            $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
280
281
            if (!$configuration->isHtmlRequest()) {
282
                return $this->viewHandler->handle($configuration, View::create($newResource, Response::HTTP_CREATED));
283
            }
284
285
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
286
287
            if ($postEvent->hasResponse()) {
288
                return $postEvent->getResponse();
289
            }
290
291
            return $this->redirectHandler->redirectToResource($configuration, $newResource);
292
        }
293
294
        if (!$configuration->isHtmlRequest()) {
295
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
296
        }
297
298
        $this->eventDispatcher->dispatchInitializeEvent(ResourceActions::CREATE, $configuration, $newResource);
299
300
        $view = View::create()
301
            ->setData([
302
                'configuration' => $configuration,
303
                'metadata' => $this->metadata,
304
                'resource' => $newResource,
305
                $this->metadata->getName() => $newResource,
306
                'form' => $form->createView(),
307
            ])
308
            ->setTemplate($configuration->getTemplate(ResourceActions::CREATE . '.html'))
309
        ;
310
311
        return $this->viewHandler->handle($configuration, $view);
312
    }
313
314
    /**
315
     * @param Request $request
316
     *
317
     * @return Response
318
     */
319
    public function updateAction(Request $request): Response
320
    {
321
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
322
323
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
324
        $resource = $this->findOr404($configuration);
325
326
        $form = $this->resourceFormFactory->create($configuration, $resource);
327
328
        if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && $form->handleRequest($request)->isValid()) {
329
            $resource = $form->getData();
330
331
            /** @var ResourceControllerEvent $event */
332
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
333
334
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
335
                throw new HttpException($event->getErrorCode(), $event->getMessage());
336
            }
337
            if ($event->isStopped()) {
338
                $this->flashHelper->addFlashFromEvent($configuration, $event);
339
340
                if ($event->hasResponse()) {
341
                    return $event->getResponse();
342
                }
343
344
                return $this->redirectHandler->redirectToResource($configuration, $resource);
345
            }
346
347
            try {
348
                $this->resourceUpdateHandler->handle($resource, $configuration, $this->manager);
349
            } catch (UpdateHandlingException $exception) {
350
                if (!$configuration->isHtmlRequest()) {
351
                    return $this->viewHandler->handle(
352
                        $configuration,
353
                        View::create($form, $exception->getApiResponseCode())
354
                    );
355
                }
356
357
                $this->flashHelper->addErrorFlash($configuration, $exception->getFlash());
358
359
                return $this->redirectHandler->redirectToReferer($configuration);
360
            }
361
362
            $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
363
364
            if (!$configuration->isHtmlRequest()) {
365
                $view = $configuration->getParameters()->get('return_content', false) ? View::create($resource, Response::HTTP_OK) : View::create(null, Response::HTTP_NO_CONTENT);
366
367
                return $this->viewHandler->handle($configuration, $view);
368
            }
369
370
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
371
372
            if ($postEvent->hasResponse()) {
373
                return $postEvent->getResponse();
374
            }
375
376
            return $this->redirectHandler->redirectToResource($configuration, $resource);
377
        }
378
379
        if (!$configuration->isHtmlRequest()) {
380
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
381
        }
382
383
        $this->eventDispatcher->dispatchInitializeEvent(ResourceActions::UPDATE, $configuration, $resource);
384
385
        $view = View::create()
386
            ->setData([
387
                'configuration' => $configuration,
388
                'metadata' => $this->metadata,
389
                'resource' => $resource,
390
                $this->metadata->getName() => $resource,
391
                'form' => $form->createView(),
392
            ])
393
            ->setTemplate($configuration->getTemplate(ResourceActions::UPDATE . '.html'))
394
        ;
395
396
        return $this->viewHandler->handle($configuration, $view);
397
    }
398
399
    /**
400
     * @param Request $request
401
     *
402
     * @return Response
403
     */
404
    public function deleteAction(Request $request): Response
405
    {
406
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
407
408
        $this->isGrantedOr403($configuration, ResourceActions::DELETE);
409
        $resource = $this->findOr404($configuration);
410
411
        if ($configuration->isCsrfProtectionEnabled() && !$this->isCsrfTokenValid($resource->getId(), $request->request->get('_csrf_token'))) {
412
            throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid csrf token.');
413
        }
414
415
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
416
417
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
418
            throw new HttpException($event->getErrorCode(), $event->getMessage());
419
        }
420
        if ($event->isStopped()) {
421
            $this->flashHelper->addFlashFromEvent($configuration, $event);
422
423
            if ($event->hasResponse()) {
424
                return $event->getResponse();
425
            }
426
427
            return $this->redirectHandler->redirectToIndex($configuration, $resource);
428
        }
429
430
        try {
431
            $this->resourceDeleteHandler->handle($resource, $this->repository);
432
        } catch (DeleteHandlingException $exception) {
433
            if (!$configuration->isHtmlRequest()) {
434
                return $this->viewHandler->handle(
435
                    $configuration,
436
                    View::create(null, $exception->getApiResponseCode())
437
                );
438
            }
439
440
            $this->flashHelper->addErrorFlash($configuration, $exception->getFlash());
441
442
            return $this->redirectHandler->redirectToReferer($configuration);
443
        }
444
445
        $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
446
447
        if (!$configuration->isHtmlRequest()) {
448
            return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
449
        }
450
451
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
452
453
        if ($postEvent->hasResponse()) {
454
            return $postEvent->getResponse();
455
        }
456
457
        return $this->redirectHandler->redirectToIndex($configuration, $resource);
458
    }
459
460
    /**
461
     * @param Request $request
462
     *
463
     * @return Response
464
     */
465
    public function applyStateMachineTransitionAction(Request $request): Response
466
    {
467
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
468
469
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
470
        $resource = $this->findOr404($configuration);
471
472
        if ($configuration->isCsrfProtectionEnabled() && !$this->isCsrfTokenValid($resource->getId(), $request->request->get('_csrf_token'))) {
473
            throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid CSRF token.');
474
        }
475
476
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
477
478
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
479
            throw new HttpException($event->getErrorCode(), $event->getMessage());
480
        }
481
        if ($event->isStopped()) {
482
            $this->flashHelper->addFlashFromEvent($configuration, $event);
483
484
            if ($event->hasResponse()) {
485
                return $event->getResponse();
486
            }
487
488
            return $this->redirectHandler->redirectToResource($configuration, $resource);
489
        }
490
491
        if (!$this->stateMachine->can($configuration, $resource)) {
492
            throw new BadRequestHttpException();
493
        }
494
495
        try {
496
            $this->resourceUpdateHandler->handle($resource, $configuration, $this->manager);
497
        } catch (UpdateHandlingException $exception) {
498
            if (!$configuration->isHtmlRequest()) {
499
                return $this->viewHandler->handle(
500
                    $configuration,
501
                    View::create($resource, $exception->getApiResponseCode())
502
                );
503
            }
504
505
            $this->flashHelper->addErrorFlash($configuration, $exception->getFlash());
506
507
            return $this->redirectHandler->redirectToReferer($configuration);
508
        }
509
510
        $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
511
512
        if (!$configuration->isHtmlRequest()) {
513
            $view = $configuration->getParameters()->get('return_content', true) ? View::create($resource, Response::HTTP_OK) : View::create(null, Response::HTTP_NO_CONTENT);
514
515
            return $this->viewHandler->handle($configuration, $view);
516
        }
517
518
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
519
520
        if ($postEvent->hasResponse()) {
521
            return $postEvent->getResponse();
522
        }
523
524
        return $this->redirectHandler->redirectToResource($configuration, $resource);
525
    }
526
527
    /**
528
     * @param RequestConfiguration $configuration
529
     * @param string $permission
530
     *
531
     * @throws AccessDeniedException
532
     */
533
    protected function isGrantedOr403(RequestConfiguration $configuration, string $permission): void
534
    {
535
        if (!$configuration->hasPermission()) {
536
            return;
537
        }
538
539
        $permission = $configuration->getPermission($permission);
540
541
        if (!$this->authorizationChecker->isGranted($configuration, $permission)) {
542
            throw new AccessDeniedException();
543
        }
544
    }
545
546
    /**
547
     * @param RequestConfiguration $configuration
548
     *
549
     * @return ResourceInterface
550
     *
551
     * @throws NotFoundHttpException
552
     */
553
    protected function findOr404(RequestConfiguration $configuration): ResourceInterface
554
    {
555
        if (null === $resource = $this->singleResourceProvider->get($configuration, $this->repository)) {
556
            throw new NotFoundHttpException(sprintf('The "%s" has not been found', $this->metadata->getHumanizedName()));
557
        }
558
559
        return $resource;
560
    }
561
}
562