Completed
Push — master ( 91e054...12ace7 )
by Kamil
31:08 queued 26:39
created

ResourceController::indexAction()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
c 2
b 0
f 1
dl 0
loc 23
rs 9.0856
cc 2
eloc 14
nc 2
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\HttpException;
25
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
26
use Symfony\Component\PropertyAccess\PropertyAccess;
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;
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;
74
75
    /**
76
     * @var ResourcesCollectionProviderInterface
77
     */
78
    protected $resourcesCollectionProvider;
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
     * @param MetadataInterface $metadata
107
     * @param RequestConfigurationFactoryInterface $requestConfigurationFactory
108
     * @param ViewHandlerInterface $viewHandler
109
     * @param RepositoryInterface $repository
110
     * @param FactoryInterface $factory
111
     * @param NewResourceFactoryInterface $newResourceFactory
112
     * @param ObjectManager $manager
113
     * @param SingleResourceProviderInterface $singleResourceProvider
114
     * @param ResourcesCollectionProviderInterface $resourcesFinder
115
     * @param ResourceFormFactoryInterface $resourceFormFactory
116
     * @param RedirectHandlerInterface $redirectHandler
117
     * @param FlashHelperInterface $flashHelper
118
     * @param AuthorizationCheckerInterface $authorizationChecker
119
     * @param EventDispatcherInterface $eventDispatcher
120
     */
121
    public function __construct(
122
        MetadataInterface $metadata,
123
        RequestConfigurationFactoryInterface $requestConfigurationFactory,
124
        ViewHandlerInterface $viewHandler,
125
        RepositoryInterface $repository,
126
        FactoryInterface $factory,
127
        NewResourceFactoryInterface $newResourceFactory,
128
        ObjectManager $manager,
129
        SingleResourceProviderInterface $singleResourceProvider,
130
        ResourcesCollectionProviderInterface $resourcesFinder,
131
        ResourceFormFactoryInterface $resourceFormFactory,
132
        RedirectHandlerInterface $redirectHandler,
133
        FlashHelperInterface $flashHelper,
134
        AuthorizationCheckerInterface $authorizationChecker,
135
        EventDispatcherInterface $eventDispatcher
136
    )
137
    {
138
        $this->metadata = $metadata;
139
        $this->requestConfigurationFactory = $requestConfigurationFactory;
140
        $this->viewHandler = $viewHandler;
141
        $this->repository = $repository;
142
        $this->factory = $factory;
143
        $this->newResourceFactory = $newResourceFactory;
144
        $this->manager = $manager;
145
        $this->singleResourceProvider = $singleResourceProvider;
146
        $this->resourcesCollectionProvider = $resourcesFinder;
147
        $this->resourceFormFactory = $resourceFormFactory;
148
        $this->redirectHandler = $redirectHandler;
149
        $this->flashHelper = $flashHelper;
150
        $this->authorizationChecker = $authorizationChecker;
151
        $this->eventDispatcher = $eventDispatcher;
152
    }
153
154
    /**
155
     * @param Request $request
156
     *
157
     * @return Response
158
     */
159
    public function showAction(Request $request)
160
    {
161
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
162
163
        $this->isGrantedOr403($configuration, ResourceActions::SHOW);
164
        $resource = $this->findOr404($configuration);
165
166
        $this->eventDispatcher->dispatch(ResourceActions::SHOW, $configuration, $resource);
167
168
        $view = View::create($resource);
169
170
        if ($configuration->isHtmlRequest()) {
171
            $view
172
                ->setTemplate($configuration->getTemplate(ResourceActions::SHOW))
173
                ->setTemplateVar($this->metadata->getName())
174
                ->setData(array(
175
                    'metadata' => $this->metadata,
176
                    'resource' => $resource,
177
                    $this->metadata->getName() => $resource
178
                ))
179
            ;
180
        }
181
182
        return $this->viewHandler->handle($configuration, $view);
183
    }
184
185
    /**
186
     * @param Request $request
187
     *
188
     * @return \Symfony\Component\HttpFoundation\Response
189
     */
190
    public function indexAction(Request $request)
191
    {
192
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
193
194
        $this->isGrantedOr403($configuration, ResourceActions::INDEX);
195
        $resources = $this->resourcesCollectionProvider->get($configuration, $this->repository);
196
197
        $view = View::create($resources);
198
199
        if ($configuration->isHtmlRequest()) {
200
            $view
201
                ->setTemplate($configuration->getTemplate(ResourceActions::INDEX))
202
                ->setTemplateVar($this->metadata->getPluralName())
203
                ->setData(array(
204
                    'metadata' => $this->metadata,
205
                    'resources' => $resources,
206
                    $this->metadata->getPluralName() => $resources
207
                ))
208
            ;
209
        }
210
211
        return $this->viewHandler->handle($configuration, $view);
212
    }
213
214
    /**
215
     * @param Request $request
216
     *
217
     * @return Response
218
     */
219
    public function createAction(Request $request)
220
    {
221
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
222
223
        $this->isGrantedOr403($configuration, ResourceActions::CREATE);
224
        $newResource = $this->newResourceFactory->create($configuration, $this->factory);
225
226
        $form = $this->resourceFormFactory->create($configuration, $newResource);
227
228
        if ($request->isMethod('POST') && $form->submit($request)->isValid()) {
229
            $newResource = $form->getData();
230
231
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::CREATE, $configuration, $newResource);
232
233
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
234
                throw new HttpException($event->getErrorCode(), $event->getMessage());
235
            }
236
            if ($event->isStopped()) {
237
                $this->flashHelper->addFlashFromEvent($configuration, $event);
238
239
                return $this->redirectHandler->redirectToIndex($configuration, $newResource);
240
            }
241
242
            $this->repository->add($newResource);
243
            $this->eventDispatcher->dispatchPostEvent(ResourceActions::CREATE, $configuration, $newResource);
244
245
            if (!$configuration->isHtmlRequest()) {
246
                return $this->viewHandler->handle($configuration, View::create($newResource, 201));
247
            }
248
249
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::CREATE, $newResource);
250
251
            return $this->redirectHandler->redirectToResource($configuration, $newResource);
252
        }
253
254
        if (!$configuration->isHtmlRequest()) {
255
            return $this->viewHandler->handle($configuration, View::create($form, 400));
256
        }
257
258
        $view = View::create()
259
            ->setData(array(
260
                'metadata' => $this->metadata,
261
                'resource' => $newResource,
262
                $this->metadata->getName() => $newResource,
263
                'form' => $form->createView()
264
            ))
265
            ->setTemplate($configuration->getTemplate(ResourceActions::CREATE))
266
        ;
267
268
        return $this->viewHandler->handle($configuration, $view);
269
    }
270
271
    /**
272
     * @param Request $request
273
     *
274
     * @return Response
275
     */
276
    public function updateAction(Request $request)
277
    {
278
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
279
280
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
281
        $resource = $this->findOr404($configuration);
282
283
        $form = $this->resourceFormFactory->create($configuration, $resource);
284
285
        if (in_array($request->getMethod(), array('POST', 'PUT', 'PATCH')) && $form->submit($request, !$request->isMethod('PATCH'))->isValid()) {
286
            $resource = $form->getData();
287
288
            $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
289
290
            if ($event->isStopped() && !$configuration->isHtmlRequest()) {
291
                throw new HttpException($event->getErrorCode(), $event->getMessage());
292
            }
293
            if ($event->isStopped()) {
294
                $this->flashHelper->addFlashFromEvent($configuration, $event);
295
296
                return $this->redirectHandler->redirectToResource($configuration, $resource);
297
            }
298
299
            $this->manager->flush();
300
            $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
301
302
            if (!$configuration->isHtmlRequest()) {
303
                return $this->viewHandler->handle($configuration, View::create($resource, 204));
304
            }
305
306
            $this->flashHelper->addSuccessFlash($configuration, ResourceActions::UPDATE, $resource);
307
308
            return $this->redirectHandler->redirectToResource($configuration, $resource);
309
        }
310
311
        if (!$configuration->isHtmlRequest()) {
312
            return $this->viewHandler->handle($configuration, View::create($form, 400));
313
        }
314
315
        $view = View::create()
316
            ->setData(array(
317
                'metadata' => $this->metadata,
318
                'resource' => $resource,
319
                $this->metadata->getName() => $resource,
320
                'form' => $form->createView()
321
            ))
322
            ->setTemplate($configuration->getTemplate(ResourceActions::UPDATE))
323
        ;
324
325
        return $this->viewHandler->handle($configuration, $view);
326
    }
327
328
    /**
329
     * @param Request $request
330
     *
331
     * @return Response
332
     */
333
    public function deleteAction(Request $request)
334
    {
335
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
336
337
        $this->isGrantedOr403($configuration, ResourceActions::DELETE);
338
        $resource = $this->findOr404($configuration);
339
340
        $event = $this->eventDispatcher->dispatchPreEvent(ResourceActions::DELETE, $configuration, $resource);
341
342
        if ($event->isStopped() && !$configuration->isHtmlRequest()) {
343
            throw new HttpException($event->getErrorCode(), $event->getMessage());
344
        }
345
        if ($event->isStopped()) {
346
            $this->flashHelper->addFlashFromEvent($configuration, $event);
347
348
            return $this->redirectHandler->redirectToIndex($configuration, $resource);
349
        }
350
351
        $this->repository->remove($resource);
352
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::DELETE, $configuration, $resource);
353
354
        if (!$configuration->isHtmlRequest()) {
355
            return $this->viewHandler->handle($configuration, View::create(null, 204));
356
        }
357
358
        $this->flashHelper->addSuccessFlash($configuration, ResourceActions::DELETE, $resource);
359
360
        return $this->redirectHandler->redirectToIndex($configuration, $resource);
361
    }
362
363
    /**
364
     * @param Request $request
365
     *
366
     * @return RedirectResponse
367
     */
368
    public function enableAction(Request $request)
369
    {
370
        return $this->toggle($request, true);
371
    }
372
    /**
373
     * @param Request $request
374
     *
375
     * @return RedirectResponse
376
     */
377
    public function disableAction(Request $request)
378
    {
379
        return $this->toggle($request, false);
380
    }
381
382
    /**
383
     * @param Request $request
384
     * @param $enabled
385
     *
386
     * @return RedirectResponse
387
     */
388
    protected function toggle(Request $request, $enabled)
389
    {
390
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
391
392
        $this->isGrantedOr403($configuration, ResourceActions::UPDATE);
393
394
        $resource = $this->findOr404($configuration);
395
        $resource->setEnabled($enabled);
396
397
        $this->eventDispatcher->dispatchPreEvent(ResourceActions::UPDATE, $configuration, $resource);
398
        $this->manager->flush();
399
        $this->eventDispatcher->dispatchPostEvent(ResourceActions::UPDATE, $configuration, $resource);
400
401
        if (!$configuration->isHtmlRequest()) {
402
            return $this->viewHandler->handle($configuration, View::create($resource, 204));
403
        }
404
405
        $this->flashHelper->addSuccessFlash($configuration, $enabled ? 'enable' : 'disable', $resource);
406
407
        return $this->redirectHandler->redirectToIndex($configuration, $resource);
408
    }
409
410
    /**
411
     * @param Request $request
412
     *
413
     * @return Response
414
     */
415
    public function moveUpAction(Request $request)
416
    {
417
        return $this->move($request, 1);
418
    }
419
420
    /**
421
     * @param Request $request
422
     *
423
     * @return Response
424
     */
425
    public function moveDownAction(Request $request)
426
    {
427
        return $this->move($request, -1);
428
    }
429
430
    /**
431
     * @param Request $request
432
     * @param integer $movement
433
     *
434
     * @return RedirectResponse
435
     */
436
    protected function move(Request $request, $movement)
437
    {
438
        $configuration = $this->requestConfigurationFactory->create($this->metadata, $request);
439
        $resource = $this->findOr404($configuration);
440
441
        $position = $configuration->getSortablePosition();
442
        $accessor = PropertyAccess::createPropertyAccessor();
443
        $accessor->setValue(
444
            $resource,
445
            $position,
446
            $accessor->getValue($resource, $position) + $movement
447
        );
448
449
        if (!$configuration->isHtmlRequest()) {
450
            return $this->viewHandler->handle($configuration, View::create($resource, 204));
451
        }
452
453
        $this->flashHelper->addSuccessFlash($configuration, 'move', $resource);
454
455
        return $this->redirectHandler->redirectToIndex($configuration, $resource);
456
    }
457
458
    /**
459
     * @param RequestConfiguration $configuration
460
     * @param string $permission
461
     *
462
     * @throws AccessDeniedException
463
     */
464
    protected function isGrantedOr403(RequestConfiguration $configuration, $permission)
465
    {
466
        if (!$configuration->hasPermission()) {
467
            return;
468
        }
469
470
        $permission = $configuration->getPermission($permission);
471
472
        if (!$this->authorizationChecker->isGranted($configuration, $permission)) {
473
            throw new AccessDeniedException();
474
        }
475
    }
476
477
    /**
478
     * @param RequestConfiguration $configuration
479
     *
480
     * @return \Sylius\Component\Resource\Model\ResourceInterface
481
     *
482
     * @throws NotFoundHttpException
483
     */
484
    protected function findOr404(RequestConfiguration $configuration)
485
    {
486
        if (null === $resource = $this->singleResourceProvider->get($configuration, $this->repository)) {
487
            throw new NotFoundHttpException();
488
        }
489
490
        return $resource;
491
    }
492
}
493