Completed
Push — symfony3-core ( 6ddaba...73f033 )
by Kamil
60:25 queued 41:49
created

ResourceController::deleteAction()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 18
nc 5
nop 1
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\Component\Resource\Factory\FactoryInterface;
17
use Sylius\Component\Resource\Metadata\MetadataInterface;
18
use Sylius\Component\Resource\Repository\RepositoryInterface;
19
use Sylius\Component\Resource\ResourceActions;
20
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
21
use Symfony\Component\HttpFoundation\RedirectResponse;
22
use Symfony\Component\HttpFoundation\Request;
23
use Symfony\Component\HttpFoundation\Response;
24
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
25
use Symfony\Component\HttpKernel\Exception\HttpException;
26
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
27
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
28
29
/**
30
 * @author Paweł Jędrzejewski <[email protected]>
31
 * @author Saša Stamenković <[email protected]>
32
 */
33
class ResourceController extends Controller
34
{
35
    /**
36
     * @var MetadataInterface
37
     */
38
    protected $metadata;
39
40
    /**
41
     * @var RequestConfigurationFactoryInterface
42
     */
43
    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...
44
45
    /**
46
     * @var ViewHandlerInterface
47
     */
48
    protected $viewHandler;
49
50
    /**
51
     * @var RepositoryInterface
52
     */
53
    protected $repository;
54
55
    /**
56
     * @var FactoryInterface
57
     */
58
    protected $factory;
59
60
    /**
61
     * @var NewResourceFactoryInterface
62
     */
63
    protected $newResourceFactory;
64
65
    /**
66
     * @var ObjectManager
67
     */
68
    protected $manager;
69
70
    /**
71
     * @var SingleResourceProviderInterface
72
     */
73
    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...
74
75
    /**
76
     * @var ResourcesCollectionProviderInterface
77
     */
78
    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...
79
80
    /**
81
     * @var ResourceFormFactoryInterface
82
     */
83
    protected $resourceFormFactory;
84
85
    /**
86
     * @var RedirectHandlerInterface
87
     */
88
    protected $redirectHandler;
89
90
    /**
91
     * @var FlashHelperInterface
92
     */
93
    protected $flashHelper;
94
95
    /**
96
     * @var AuthorizationCheckerInterface
97
     */
98
    protected $authorizationChecker;
99
100
    /**
101
     * @var EventDispatcherInterface
102
     */
103
    protected $eventDispatcher;
104
105
    /**
106
     * @var StateMachineInterface
107
     */
108
    protected $stateMachine;
109
110
    /**
111
     * @param MetadataInterface $metadata
112
     * @param RequestConfigurationFactoryInterface $requestConfigurationFactory
113
     * @param ViewHandlerInterface $viewHandler
114
     * @param RepositoryInterface $repository
115
     * @param FactoryInterface $factory
116
     * @param NewResourceFactoryInterface $newResourceFactory
117
     * @param ObjectManager $manager
118
     * @param SingleResourceProviderInterface $singleResourceProvider
119
     * @param ResourcesCollectionProviderInterface $resourcesFinder
120
     * @param ResourceFormFactoryInterface $resourceFormFactory
121
     * @param RedirectHandlerInterface $redirectHandler
122
     * @param FlashHelperInterface $flashHelper
123
     * @param AuthorizationCheckerInterface $authorizationChecker
124
     * @param EventDispatcherInterface $eventDispatcher
125
     * @param StateMachineInterface $stateMachine
126
     */
127
    public function __construct(
128
        MetadataInterface $metadata,
129
        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...
130
        ViewHandlerInterface $viewHandler,
131
        RepositoryInterface $repository,
132
        FactoryInterface $factory,
133
        NewResourceFactoryInterface $newResourceFactory,
134
        ObjectManager $manager,
135
        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...
136
        ResourcesCollectionProviderInterface $resourcesFinder,
137
        ResourceFormFactoryInterface $resourceFormFactory,
138
        RedirectHandlerInterface $redirectHandler,
139
        FlashHelperInterface $flashHelper,
140
        AuthorizationCheckerInterface $authorizationChecker,
141
        EventDispatcherInterface $eventDispatcher,
142
        StateMachineInterface $stateMachine
143
    ) {
144
        $this->metadata = $metadata;
145
        $this->requestConfigurationFactory = $requestConfigurationFactory;
146
        $this->viewHandler = $viewHandler;
147
        $this->repository = $repository;
148
        $this->factory = $factory;
149
        $this->newResourceFactory = $newResourceFactory;
150
        $this->manager = $manager;
151
        $this->singleResourceProvider = $singleResourceProvider;
152
        $this->resourcesCollectionProvider = $resourcesFinder;
153
        $this->resourceFormFactory = $resourceFormFactory;
154
        $this->redirectHandler = $redirectHandler;
155
        $this->flashHelper = $flashHelper;
156
        $this->authorizationChecker = $authorizationChecker;
157
        $this->eventDispatcher = $eventDispatcher;
158
        $this->stateMachine = $stateMachine;
159
    }
160
161
    /**
162
     * @param Request $request
163
     *
164
     * @return Response
165
     */
166
    public function showAction(Request $request)
167
    {
168
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
169
170
        $this->isGrantedOr403($configuration, ResourceActions::SHOW);
171
        $resource = $this->findOr404($configuration);
172
173
        $this->eventDispatcher->dispatch(ResourceActions::SHOW, $configuration, $resource);
174
175
        $view = View::create($resource);
176
177
        if ($configuration->isHtmlRequest()) {
178
            $view
179
                ->setTemplate($configuration->getTemplate(ResourceActions::SHOW . '.html'))
180
                ->setTemplateVar($this->metadata->getName())
181
                ->setData([
182
                    'configuration' => $configuration,
183
                    'metadata' => $this->metadata,
184
                    'resource' => $resource,
185
                    $this->metadata->getName() => $resource,
186
                ])
187
            ;
188
        }
189
190
        return $this->viewHandler->handle($configuration, $view);
191
    }
192
193
    /**
194
     * @param Request $request
195
     *
196
     * @return \Symfony\Component\HttpFoundation\Response
197
     */
198
    public function indexAction(Request $request)
199
    {
200
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
201
202
        $this->isGrantedOr403($configuration, ResourceActions::INDEX);
203
        $resources = $this->resourcesCollectionProvider->get($configuration, $this->repository);
204
205
        $view = View::create($resources);
206
207
        if ($configuration->isHtmlRequest()) {
208
            $view
209
                ->setTemplate($configuration->getTemplate(ResourceActions::INDEX . '.html'))
210
                ->setTemplateVar($this->metadata->getPluralName())
211
                ->setData([
212
                    'configuration' => $configuration,
213
                    'metadata' => $this->metadata,
214
                    'resources' => $resources,
215
                    $this->metadata->getPluralName() => $resources,
216
                ])
217
            ;
218
        }
219
220
        return $this->viewHandler->handle($configuration, $view);
221
    }
222
223
    /**
224
     * @param Request $request
225
     *
226
     * @return Response
227
     */
228
    public function createAction(Request $request)
229
    {
230
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
231
232
        $this->isGrantedOr403($configuration, ResourceActions::CREATE);
233
        $newResource = $this->newResourceFactory->create($configuration, $this->factory);
234
235
        $form = $this->resourceFormFactory->create($configuration, $newResource);
236
237
        if ($request->isMethod('POST') && $form->handleRequest($request)->isValid()) {
238
            $newResource = $form->getData();
239
240
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource);
241
242
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
243
                throw new HttpException($event->getErrorCode(), $event->getMessage());
244
            }
245
            if ($event->isStopped()) {
246
                $this->flashHelper->addFlashFromEvent($configuration, $event);
247
248
                return $this->redirectHandler->redirectToIndex($configuration, $newResource);
249
            }
250
251
            if ($configuration->hasStateMachine()) {
252
                $this->stateMachine->apply($configuration, $newResource);
253
            }
254
255
            $this->repository->add($newResource);
256
            $this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
257
258
            if (!$configuration->isHtmlRequest()) {
259
                return $this->viewHandler->handle($configuration, View::create($newResource, Response::HTTP_CREATED));
260
            }
261
262
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
263
264
            return $this->redirectHandler->redirectToResource($configuration, $newResource);
265
        }
266
267
        if (!$configuration->isHtmlRequest()) {
268
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
269
        }
270
271
        $view = View::create()
272
            ->setData([
273
                'configuration' => $configuration,
274
                'metadata' => $this->metadata,
275
                'resource' => $newResource,
276
                $this->metadata->getName() => $newResource,
277
                'form' => $form->createView(),
278
            ])
279
            ->setTemplate($configuration->getTemplate(ResourceActions::CREATE . '.html'))
280
        ;
281
282
        return $this->viewHandler->handle($configuration, $view);
283
    }
284
285
    /**
286
     * @param Request $request
287
     *
288
     * @return Response
289
     */
290
    public function updateAction(Request $request)
291
    {
292
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
293
294
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
295
        $resource = $this->findOr404($configuration);
296
297
        $form = $this->resourceFormFactory->create($configuration, $resource);
298
299
        if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH'], true) && $form->handleRequest($request)->isValid()) {
300
            $resource = $form->getData();
301
302
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
303
304
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
305
                throw new HttpException($event->getErrorCode(), $event->getMessage());
306
            }
307
            if ($event->isStopped()) {
308
                $this->flashHelper->addFlashFromEvent($configuration, $event);
309
310
                return $this->redirectHandler->redirectToResource($configuration, $resource);
311
            }
312
313
            if ($configuration->hasStateMachine()) {
314
                $this->stateMachine->apply($configuration, $resource);
315
            }
316
317
            $this->manager->flush();
318
            $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
319
320
            if (!$configuration->isHtmlRequest()) {
321
                return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
322
            }
323
324
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
325
326
            return $this->redirectHandler->redirectToResource($configuration, $resource);
327
        }
328
329
        if (!$configuration->isHtmlRequest()) {
330
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
331
        }
332
333
        $view = View::create()
334
            ->setData([
335
                'configuration' => $configuration,
336
                'metadata' => $this->metadata,
337
                'resource' => $resource,
338
                $this->metadata->getName() => $resource,
339
                'form' => $form->createView(),
340
            ])
341
            ->setTemplate($configuration->getTemplate(ResourceActions::UPDATE . '.html'))
342
        ;
343
344
        return $this->viewHandler->handle($configuration, $view);
345
    }
346
347
    /**
348
     * @param Request $request
349
     *
350
     * @return Response
351
     */
352
    public function deleteAction(Request $request)
353
    {
354
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
355
356
        $this->isGrantedOr403($configuration, ResourceActions::DELETE);
357
        $resource = $this->findOr404($configuration);
358
359
        if ($configuration->isCsrfProtectionEnabled() && !$this->isCsrfTokenValid($resource->getId(), $request->get('_csrf_token'))) {
360
            throw new HttpException(Response::HTTP_FORBIDDEN, 'Invalid csrf token.');
361
        }
362
363
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
364
365
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
366
            throw new HttpException($event->getErrorCode(), $event->getMessage());
367
        }
368
        if ($event->isStopped()) {
369
            $this->flashHelper->addFlashFromEvent($configuration, $event);
370
371
            return $this->redirectHandler->redirectToIndex($configuration, $resource);
372
        }
373
374
        $this->repository->remove($resource);
375
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
376
377
        if (!$configuration->isHtmlRequest()) {
378
            return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
379
        }
380
381
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
382
383
        return $this->redirectHandler->redirectToIndex($configuration, $resource);
384
    }
385
386
    /**
387
     * @param Request $request
388
     *
389
     * @return RedirectResponse
390
     */
391
    public function applyStateMachineTransitionAction(Request $request)
392
    {
393
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
394
395
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
396
        $resource = $this->findOr404($configuration);
397
398
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
399
400
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
401
            throw new HttpException($event->getErrorCode(), $event->getMessage());
402
        }
403
        if ($event->isStopped()) {
404
            $this->flashHelper->addFlashFromEvent($configuration, $event);
405
406
            return $this->redirectHandler->redirectToResource($configuration, $resource);
407
        }
408
409
        if (!$this->stateMachine->can($configuration, $resource)) {
410
            throw new BadRequestHttpException();
411
        }
412
413
        $this->stateMachine->apply($configuration, $resource);
414
        $this->manager->flush();
415
416
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
417
418
        if (!$configuration->isHtmlRequest()) {
419
            return $this->viewHandler->handle($configuration, View::create($resource, Response::HTTP_OK));
420
        }
421
422
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
423
424
        return $this->redirectHandler->redirectToResource($configuration, $resource);
425
    }
426
427
    /**
428
     * @param RequestConfiguration $configuration
429
     * @param string $permission
430
     *
431
     * @throws AccessDeniedException
432
     */
433
    protected function isGrantedOr403(RequestConfiguration $configuration, $permission)
434
    {
435
        if (!$configuration->hasPermission()) {
436
            return;
437
        }
438
439
        $permission = $configuration->getPermission($permission);
440
441
        if (!$this->authorizationChecker->isGranted($configuration, $permission)) {
442
            throw new AccessDeniedException();
443
        }
444
    }
445
446
    /**
447
     * @param RequestConfiguration $configuration
448
     *
449
     * @return \Sylius\Component\Resource\Model\ResourceInterface
450
     *
451
     * @throws NotFoundHttpException
452
     */
453
    protected function findOr404(RequestConfiguration $configuration)
454
    {
455
        if (null === $resource = $this->singleResourceProvider->get($configuration, $this->repository)) {
456
            throw new NotFoundHttpException();
457
        }
458
459
        return $resource;
460
    }
461
}
462