Completed
Push — currency-cookie ( 8ef560...28b724 )
by Kamil
24:47
created

ResourceController::updateAction()   C

Complexity

Conditions 11
Paths 11

Size

Total Lines 65
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 65
rs 5.9999
cc 11
eloc 36
nc 11
nop 1

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
/*
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
namespace Sylius\Bundle\ResourceBundle\Controller;
13
14
use Doctrine\Common\Persistence\ObjectManager;
15
use FOS\RestBundle\View\View;
16
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
17
use Sylius\Component\Resource\Factory\FactoryInterface;
18
use Sylius\Component\Resource\Metadata\MetadataInterface;
19
use Sylius\Component\Resource\Repository\RepositoryInterface;
20
use Sylius\Component\Resource\ResourceActions;
21
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
22
use Symfony\Component\HttpFoundation\RedirectResponse;
23
use Symfony\Component\HttpFoundation\Request;
24
use Symfony\Component\HttpFoundation\Response;
25
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
26
use Symfony\Component\HttpKernel\Exception\HttpException;
27
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
28
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
29
30
/**
31
 * @author Paweł Jędrzejewski <[email protected]>
32
 * @author Saša Stamenković <[email protected]>
33
 */
34
class ResourceController extends Controller
35
{
36
    /**
37
     * @var MetadataInterface
38
     */
39
    protected $metadata;
40
41
    /**
42
     * @var RequestConfigurationFactoryInterface
43
     */
44
    protected $requestConfigurationFactory;
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $requestConfigurationFactory exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
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;
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $singleResourceProvider exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
75
76
    /**
77
     * @var ResourcesCollectionProviderInterface
78
     */
79
    protected $resourcesCollectionProvider;
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $resourcesCollectionProvider exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
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
     * @param MetadataInterface $metadata
113
     * @param RequestConfigurationFactoryInterface $requestConfigurationFactory
114
     * @param ViewHandlerInterface $viewHandler
115
     * @param RepositoryInterface $repository
116
     * @param FactoryInterface $factory
117
     * @param NewResourceFactoryInterface $newResourceFactory
118
     * @param ObjectManager $manager
119
     * @param SingleResourceProviderInterface $singleResourceProvider
120
     * @param ResourcesCollectionProviderInterface $resourcesFinder
121
     * @param ResourceFormFactoryInterface $resourceFormFactory
122
     * @param RedirectHandlerInterface $redirectHandler
123
     * @param FlashHelperInterface $flashHelper
124
     * @param AuthorizationCheckerInterface $authorizationChecker
125
     * @param EventDispatcherInterface $eventDispatcher
126
     * @param StateMachineInterface $stateMachine
127
     */
128
    public function __construct(
129
        MetadataInterface $metadata,
130
        RequestConfigurationFactoryInterface $requestConfigurationFactory,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $requestConfigurationFactory exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
131
        ViewHandlerInterface $viewHandler,
132
        RepositoryInterface $repository,
133
        FactoryInterface $factory,
134
        NewResourceFactoryInterface $newResourceFactory,
135
        ObjectManager $manager,
136
        SingleResourceProviderInterface $singleResourceProvider,
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $singleResourceProvider exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
137
        ResourcesCollectionProviderInterface $resourcesFinder,
138
        ResourceFormFactoryInterface $resourceFormFactory,
139
        RedirectHandlerInterface $redirectHandler,
140
        FlashHelperInterface $flashHelper,
141
        AuthorizationCheckerInterface $authorizationChecker,
142
        EventDispatcherInterface $eventDispatcher,
143
        StateMachineInterface $stateMachine
144
    ) {
145
        $this->metadata = $metadata;
146
        $this->requestConfigurationFactory = $requestConfigurationFactory;
147
        $this->viewHandler = $viewHandler;
148
        $this->repository = $repository;
149
        $this->factory = $factory;
150
        $this->newResourceFactory = $newResourceFactory;
151
        $this->manager = $manager;
152
        $this->singleResourceProvider = $singleResourceProvider;
153
        $this->resourcesCollectionProvider = $resourcesFinder;
154
        $this->resourceFormFactory = $resourceFormFactory;
155
        $this->redirectHandler = $redirectHandler;
156
        $this->flashHelper = $flashHelper;
157
        $this->authorizationChecker = $authorizationChecker;
158
        $this->eventDispatcher = $eventDispatcher;
159
        $this->stateMachine = $stateMachine;
160
    }
161
162
    /**
163
     * @param Request $request
164
     *
165
     * @return Response
166
     */
167
    public function showAction(Request $request)
168
    {
169
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
170
171
        $this->isGrantedOr403($configuration, ResourceActions::SHOW);
172
        $resource = $this->findOr404($configuration);
173
174
        $this->eventDispatcher->dispatch(ResourceActions::SHOW, $configuration, $resource);
175
176
        $view = View::create($resource);
177
178
        if ($configuration->isHtmlRequest()) {
179
            $view
180
                ->setTemplate($configuration->getTemplate(ResourceActions::SHOW . '.html'))
181
                ->setTemplateVar($this->metadata->getName())
182
                ->setData([
183
                    'configuration' => $configuration,
184
                    'metadata' => $this->metadata,
185
                    'resource' => $resource,
186
                    $this->metadata->getName() => $resource,
187
                ])
188
            ;
189
        }
190
191
        return $this->viewHandler->handle($configuration, $view);
192
    }
193
194
    /**
195
     * @param Request $request
196
     *
197
     * @return \Symfony\Component\HttpFoundation\Response
198
     */
199
    public function indexAction(Request $request)
200
    {
201
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
202
203
        $this->isGrantedOr403($configuration, ResourceActions::INDEX);
204
        $resources = $this->resourcesCollectionProvider->get($configuration, $this->repository);
205
206
        $view = View::create($resources);
207
208
        if ($configuration->isHtmlRequest()) {
209
            $view
210
                ->setTemplate($configuration->getTemplate(ResourceActions::INDEX . '.html'))
211
                ->setTemplateVar($this->metadata->getPluralName())
212
                ->setData([
213
                    'configuration' => $configuration,
214
                    'metadata' => $this->metadata,
215
                    'resources' => $resources,
216
                    $this->metadata->getPluralName() => $resources,
217
                ])
218
            ;
219
        }
220
221
        return $this->viewHandler->handle($configuration, $view);
222
    }
223
224
    /**
225
     * @param Request $request
226
     *
227
     * @return Response
228
     */
229
    public function createAction(Request $request)
230
    {
231
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
232
233
        $this->isGrantedOr403($configuration, ResourceActions::CREATE);
234
        $newResource = $this->newResourceFactory->create($configuration, $this->factory);
235
236
        $form = $this->resourceFormFactory->create($configuration, $newResource);
237
238
        if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
239
            $newResource = $form->getData();
240
241
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource);
242
243
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
244
                throw new HttpException($event->getErrorCode(), $event->getMessage());
245
            }
246
            if ($event->isStopped()) {
247
                $this->flashHelper->addFlashFromEvent($configuration, $event);
248
249
                return $this->redirectHandler->redirectToIndex($configuration, $newResource);
250
            }
251
252
            if ($configuration->hasStateMachine()) {
253
                $this->stateMachine->apply($configuration, $newResource);
254
            }
255
256
            $this->repository->add($newResource);
257
            $this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
258
259
            if (!$configuration->isHtmlRequest()) {
260
                return $this->viewHandler->handle($configuration, View::create($newResource, Response::HTTP_CREATED));
261
            }
262
263
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
264
265
            return $this->redirectHandler->redirectToResource($configuration, $newResource);
266
        }
267
268
        if (!$configuration->isHtmlRequest()) {
269
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
270
        }
271
272
        $view = View::create()
273
            ->setData([
274
                'configuration' => $configuration,
275
                'metadata' => $this->metadata,
276
                'resource' => $newResource,
277
                $this->metadata->getName() => $newResource,
278
                'form' => $form->createView(),
279
            ])
280
            ->setTemplate($configuration->getTemplate(ResourceActions::CREATE . '.html'))
281
        ;
282
283
        return $this->viewHandler->handle($configuration, $view);
284
    }
285
286
    /**
287
     * @param Request $request
288
     *
289
     * @return Response
290
     */
291
    public function updateAction(Request $request)
292
    {
293
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
294
295
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
296
        $resource = $this->findOr404($configuration);
297
298
        $form = $this->resourceFormFactory->create($configuration, $resource);
299
300
        if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && $form->handleRequest($request)->isValid()) {
301
            $resource = $form->getData();
302
303
            /** @var ResourceControllerEvent $event */
304
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
305
306
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
307
                throw new HttpException($event->getErrorCode(), $event->getMessage());
308
            }
309
            if ($event->isStopped()) {
310
                $this->flashHelper->addFlashFromEvent($configuration, $event);
311
312
                if ($event->hasResponse()) {
313
                    return $event->getResponse();
314
                }
315
316
                return $this->redirectHandler->redirectToResource($configuration, $resource);
317
            }
318
319
            if ($configuration->hasStateMachine()) {
320
                $this->stateMachine->apply($configuration, $resource);
321
            }
322
323
            $this->manager->flush();
324
            $postEvent = $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
325
326
            if (!$configuration->isHtmlRequest()) {
327
                return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
328
            }
329
330
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
331
332
            if ($postEvent->hasResponse()) {
333
                return $postEvent->getResponse();
334
            }
335
336
            return $this->redirectHandler->redirectToResource($configuration, $resource);
337
        }
338
339
        if (!$configuration->isHtmlRequest()) {
340
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
341
        }
342
343
        $view = View::create()
344
            ->setData([
345
                'configuration' => $configuration,
346
                'metadata' => $this->metadata,
347
                'resource' => $resource,
348
                $this->metadata->getName() => $resource,
349
                'form' => $form->createView(),
350
            ])
351
            ->setTemplate($configuration->getTemplate(ResourceActions::UPDATE . '.html'))
352
        ;
353
354
        return $this->viewHandler->handle($configuration, $view);
355
    }
356
357
    /**
358
     * @param Request $request
359
     *
360
     * @return Response
361
     */
362
    public function deleteAction(Request $request)
363
    {
364
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
365
366
        $this->isGrantedOr403($configuration, ResourceActions::DELETE);
367
        $resource = $this->findOr404($configuration);
368
369
        if ($configuration->isCsrfProtectionEnabled() && !$this->isCsrfTokenValid($resource->getId(), $request->request->get('_csrf_token'))) {
370
            throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid csrf token.');
371
        }
372
373
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
374
375
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
376
            throw new HttpException($event->getErrorCode(), $event->getMessage());
377
        }
378
        if ($event->isStopped()) {
379
            $this->flashHelper->addFlashFromEvent($configuration, $event);
380
381
            return $this->redirectHandler->redirectToIndex($configuration, $resource);
382
        }
383
384
        $this->repository->remove($resource);
385
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
386
387
        if (!$configuration->isHtmlRequest()) {
388
            return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
389
        }
390
391
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
392
393
        return $this->redirectHandler->redirectToIndex($configuration, $resource);
394
    }
395
396
    /**
397
     * @param Request $request
398
     *
399
     * @return RedirectResponse
400
     */
401
    public function applyStateMachineTransitionAction(Request $request)
402
    {
403
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
404
405
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
406
        $resource = $this->findOr404($configuration);
407
408
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
409
410
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
411
            throw new HttpException($event->getErrorCode(), $event->getMessage());
412
        }
413
        if ($event->isStopped()) {
414
            $this->flashHelper->addFlashFromEvent($configuration, $event);
415
416
            return $this->redirectHandler->redirectToResource($configuration, $resource);
417
        }
418
419
        if (!$this->stateMachine->can($configuration, $resource)) {
420
            throw new BadRequestHttpException();
421
        }
422
423
        $this->stateMachine->apply($configuration, $resource);
424
        $this->manager->flush();
425
426
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
427
428
        if (!$configuration->isHtmlRequest()) {
429
            return $this->viewHandler->handle($configuration, View::create($resource, Response::HTTP_OK));
430
        }
431
432
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
433
434
        return $this->redirectHandler->redirectToResource($configuration, $resource);
435
    }
436
437
    /**
438
     * @param RequestConfiguration $configuration
439
     * @param string $permission
440
     *
441
     * @throws AccessDeniedException
442
     */
443
    protected function isGrantedOr403(RequestConfiguration $configuration, $permission)
444
    {
445
        if (!$configuration->hasPermission()) {
446
            return;
447
        }
448
449
        $permission = $configuration->getPermission($permission);
450
451
        if (!$this->authorizationChecker->isGranted($configuration, $permission)) {
452
            throw new AccessDeniedException();
453
        }
454
    }
455
456
    /**
457
     * @param RequestConfiguration $configuration
458
     *
459
     * @return \Sylius\Component\Resource\Model\ResourceInterface
460
     *
461
     * @throws NotFoundHttpException
462
     */
463
    protected function findOr404(RequestConfiguration $configuration)
464
    {
465
        if (null === $resource = $this->singleResourceProvider->get($configuration, $this->repository)) {
466
            throw new NotFoundHttpException();
467
        }
468
469
        return $resource;
470
    }
471
}
472