Passed
Pull Request — feature/publishable (#43)
by Vincent
06:24
created

PublishableEventListener   A

Complexity

Total Complexity 13

Size/Duplication

Total Lines 65
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 13
eloc 32
c 1
b 0
f 0
dl 0
loc 65
ccs 0
cts 33
cp 0
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A getValue() 0 3 1
A __construct() 0 5 1
A onKernelResponse() 0 23 4
B onKernelRequest() 0 20 7
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Component Bundle Project
5
 *
6
 * (c) Daniel West <[email protected]>
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 Silverback\ApiComponentBundle\EventListener\Api;
15
16
use Doctrine\Persistence\ManagerRegistry;
17
use Silverback\ApiComponentBundle\Entity\Utility\PublishableTrait;
18
use Silverback\ApiComponentBundle\Publishable\ClassMetadataTrait;
19
use Silverback\ApiComponentBundle\Publishable\PublishableHelper;
20
use Symfony\Component\HttpFoundation\Request;
21
use Symfony\Component\HttpKernel\Event\RequestEvent;
22
use Symfony\Component\HttpKernel\Event\ResponseEvent;
23
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
24
25
/**
26
 * @author Vincent Chalamon <[email protected]>
27
 */
28
final class PublishableEventListener
29
{
30
    use ClassMetadataTrait;
31
32
    private PublishableHelper $publishableHelper;
33
    private ManagerRegistry $registry;
34
35
    public function __construct(PublishableHelper $publishableHelper, ManagerRegistry $registry)
36
    {
37
        $this->publishableHelper = $publishableHelper;
38
        // not unused, used by the trait
39
        $this->registry = $registry;
40
    }
41
42
    public function onKernelResponse(ResponseEvent $event): void
43
    {
44
        $request = $event->getRequest();
45
        /** @var PublishableTrait $data */
46
        $data = $request->attributes->get('data');
47
        if (!$this->publishableHelper->isPublishable($data)) {
48
            return;
49
        }
50
        $response = $event->getResponse();
51
        $response->setVary('Authorization');
52
53
        $configuration = $this->publishableHelper->getConfiguration($data);
54
        $classMetadata = $this->getClassMetadata($data);
55
56
        $draftResource = $classMetadata->getFieldValue($data, $configuration->reverseAssociationName) ?? $data;
57
58
        /** @var \DateTime|null $publishedAt */
59
        $publishedAt = $classMetadata->getFieldValue($draftResource, $configuration->fieldName);
60
        if (!$publishedAt || $publishedAt <= new \DateTime()) {
61
            return;
62
        }
63
64
        $response->setExpires($publishedAt);
65
    }
66
67
    public function onKernelRequest(RequestEvent $event): void
68
    {
69
        $request = $event->getRequest();
70
        $data = $request->attributes->get('data');
71
        if (
72
            empty($data) ||
73
            !$this->publishableHelper->isPublishable($data) ||
74
            !($request->isMethod(Request::METHOD_PUT) || $request->isMethod(Request::METHOD_PATCH))
75
        ) {
76
            return;
77
        }
78
79
        $configuration = $this->publishableHelper->getConfiguration($data);
80
81
        // User cannot change the publication date of the original resource
82
        if (
83
            true === $request->query->getBoolean('published', false) &&
84
            $this->getValue($request->attributes->get('previous_data'), $configuration->fieldName) !== $this->getValue($data, $configuration->fieldName)
85
        ) {
86
            throw new BadRequestHttpException('You cannot change the publication date of a published resource.');
87
        }
88
    }
89
90
    private function getValue(object $object, string $property)
91
    {
92
        return $this->getClassMetadata($object)->getFieldValue($object, $property);
93
    }
94
}
95