Completed
Push — cleanup/resource-controller-to... ( 78868a )
by Kamil
45:32 queued 21:48
created

ResourceController::toggle()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
nc 2
cc 3
eloc 12
nop 2

1 Method

Rating   Name   Duplication   Size   Complexity  
A ResourceController::findOr404() 0 8 2
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\PropertyAccess\PropertyAccess;
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->submit($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
            $this->repository->add($newResource);
253
            $this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
254
255
            if (!$configuration->isHtmlRequest()) {
256
                return $this->viewHandler->handle($configuration, View::create($newResource, Response::HTTP_CREATED));
257
            }
258
259
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
260
261
            return $this->redirectHandler->redirectToResource($configuration, $newResource);
262
        }
263
264
        if (!$configuration->isHtmlRequest()) {
265
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
266
        }
267
268
        $view = View::create()
269
            ->setData([
270
                'configuration' => $configuration,
271
                'metadata' => $this->metadata,
272
                'resource' => $newResource,
273
                $this->metadata->getName() => $newResource,
274
                'form' => $form->createView(),
275
            ])
276
            ->setTemplate($configuration->getTemplate(ResourceActions::CREATE . '.html'))
277
        ;
278
279
        return $this->viewHandler->handle($configuration, $view);
280
    }
281
282
    /**
283
     * @param Request $request
284
     *
285
     * @return Response
286
     */
287
    public function updateAction(Request $request)
288
    {
289
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
290
291
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
292
        $resource = $this->findOr404($configuration);
293
294
        $form = $this->resourceFormFactory->create($configuration, $resource);
295
296
        if (in_array($request->getMethod(), ['POST', 'PUT', 'PATCH']) && $form->submit($request, !$request->isMethod('PATCH'))->isValid()) {
297
            $resource = $form->getData();
298
299
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
300
301
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
302
                throw new HttpException($event->getErrorCode(), $event->getMessage());
303
            }
304
            if ($event->isStopped()) {
305
                $this->flashHelper->addFlashFromEvent($configuration, $event);
306
307
                return $this->redirectHandler->redirectToResource($configuration, $resource);
308
            }
309
310
            if ($configuration->hasStateMachine()) {
311
                $this->stateMachine->apply($configuration, $resource);
312
            }
313
314
            $this->manager->flush();
315
            $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
316
317
            if (!$configuration->isHtmlRequest()) {
318
                return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
319
            }
320
321
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
322
323
            return $this->redirectHandler->redirectToResource($configuration, $resource);
324
        }
325
326
        if (!$configuration->isHtmlRequest()) {
327
            return $this->viewHandler->handle($configuration, View::create($form, Response::HTTP_BAD_REQUEST));
328
        }
329
330
        $view = View::create()
331
            ->setData([
332
                'configuration' => $configuration,
333
                'metadata' => $this->metadata,
334
                'resource' => $resource,
335
                $this->metadata->getName() => $resource,
336
                'form' => $form->createView(),
337
            ])
338
            ->setTemplate($configuration->getTemplate(ResourceActions::UPDATE . '.html'))
339
        ;
340
341
        return $this->viewHandler->handle($configuration, $view);
342
    }
343
344
    /**
345
     * @param Request $request
346
     *
347
     * @return Response
348
     */
349
    public function deleteAction(Request $request)
350
    {
351
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
352
353
        $this->isGrantedOr403($configuration, ResourceActions::DELETE);
354
        $resource = $this->findOr404($configuration);
355
356
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
357
358
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
359
            throw new HttpException($event->getErrorCode(), $event->getMessage());
360
        }
361
        if ($event->isStopped()) {
362
            $this->flashHelper->addFlashFromEvent($configuration, $event);
363
364
            return $this->redirectHandler->redirectToIndex($configuration, $resource);
365
        }
366
367
        $this->repository->remove($resource);
368
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
369
370
        if (!$configuration->isHtmlRequest()) {
371
            return $this->viewHandler->handle($configuration, View::create(null, Response::HTTP_NO_CONTENT));
372
        }
373
374
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
375
376
        return $this->redirectHandler->redirectToIndex($configuration, $resource);
377
    }
378
379
    /**
380
     * @param Request $request
381
     *
382
     * @return RedirectResponse
383
     */
384
    public function applyStateMachineTransitionAction(Request $request)
385
    {
386
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
387
388
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
389
        $resource = $this->findOr404($configuration);
390
391
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
392
393
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
394
            throw new HttpException($event->getErrorCode(), $event->getMessage());
395
        }
396
        if ($event->isStopped()) {
397
            $this->flashHelper->addFlashFromEvent($configuration, $event);
398
399
            return $this->redirectHandler->redirectToResource($configuration, $resource);
400
        }
401
402
        if (!$this->stateMachine->can($configuration, $resource)) {
403
            throw new BadRequestHttpException();
404
        }
405
406
        $this->stateMachine->apply($configuration, $resource);
407
        $this->manager->flush();
408
409
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
410
411
        if (!$configuration->isHtmlRequest()) {
412
            return $this->viewHandler->handle($configuration, View::create($resource, Response::HTTP_OK));
413
        }
414
415
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
416
417
        return $this->redirectHandler->redirectToResource($configuration, $resource);
418
    }
419
420
    /**
421
     * @param RequestConfiguration $configuration
422
     * @param string $permission
423
     *
424
     * @throws AccessDeniedException
425
     */
426
    protected function isGrantedOr403(RequestConfiguration $configuration, $permission)
427
    {
428
        if (!$configuration->hasPermission()) {
429
            return;
430
        }
431
432
        $permission = $configuration->getPermission($permission);
433
434
        if (!$this->authorizationChecker->isGranted($configuration, $permission)) {
435
            throw new AccessDeniedException();
436
        }
437
    }
438
439
    /**
440
     * @param RequestConfiguration $configuration
441
     *
442
     * @return \Sylius\Component\Resource\Model\ResourceInterface
443
     *
444
     * @throws NotFoundHttpException
445
     */
446
    protected function findOr404(RequestConfiguration $configuration)
447
    {
448
        if (null === $resource = $this->singleResourceProvider->get($configuration, $this->repository)) {
449
            throw new NotFoundHttpException();
450
        }
451
452
        return $resource;
453
    }
454
}
455