Passed
Push — main ( 6f7970...605cbe )
by Daniel
03:52
created

HttpCachePurger::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
nc 1
nop 3
dl 0
loc 6
ccs 0
cts 2
cp 0
crap 2
rs 10
c 1
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the Silverback API Components 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\ApiComponentsBundle\HttpCache;
15
16
use ApiPlatform\Api\IriConverterInterface;
17
use ApiPlatform\Api\ResourceClassResolverInterface;
18
use ApiPlatform\Api\UrlGeneratorInterface;
19
use ApiPlatform\Exception\InvalidArgumentException;
20
use ApiPlatform\Exception\OperationNotFoundException;
21
use ApiPlatform\Exception\RuntimeException;
22
use ApiPlatform\HttpCache\PurgerInterface;
23
use ApiPlatform\Metadata\GetCollection;
24
use Doctrine\ORM\PersistentCollection;
25
26
class HttpCachePurger implements ResourceChangedPropagatorInterface
27
{
28
    private array $tags;
29
30
    public function __construct(
31
        private readonly IriConverterInterface $iriConverter,
32
        private readonly ResourceClassResolverInterface $resourceClassResolver,
33
        private readonly PurgerInterface $httpCachePurger,
34
    ) {
35
        $this->reset();
36
    }
37
38
    public function add(object $item, ?string $type = null): void
39
    {
40
        if (!is_iterable($item)) {
41
            $this->collectResource($item);
42
            return;
43
        }
44
45
        if ($item instanceof PersistentCollection) {
46
            $item = clone $item;
47
        }
48
49
        foreach ($item as $i) {
50
            $this->collectResource($i);
51
        }
52
    }
53
54
    public function collectResource($entity): void
55
    {
56
        if (null === $entity) {
57
            return;
58
        }
59
60
        try {
61
            $resourceClass = $this->resourceClassResolver->getResourceClass($entity);
62
63
            // collect cache of any collections being fetched
64
            $resourceIri = $this->iriConverter->getIriFromResource($resourceClass, UrlGeneratorInterface::ABS_PATH, (new GetCollection())->withClass($resourceClass));
65
            $this->collectIri($resourceIri);
66
67
            // clear cache of anything containing this item
68
            $this->collectItem($entity);
69
        } catch (OperationNotFoundException|InvalidArgumentException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
70
        }
71
    }
72
73
    private function collectItem($item): void
74
    {
75
        try {
76
            $iri = $this->iriConverter->getIriFromResource($item);
77
            $this->collectIri($iri);
78
        } catch (InvalidArgumentException|RuntimeException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
79
        }
80
    }
81
82
    private function collectIri($iri): void
83
    {
84
        if (!\in_array($iri, $this->tags, true)) {
85
            $this->tags[$iri] = $iri;
86
        }
87
    }
88
89
    public function propagate(): void
90
    {
91
        if (empty($this->tags)) {
92
            return;
93
        }
94
95
        $this->httpCachePurger->purge(array_values($this->tags));
96
        $this->reset();
97
    }
98
99
    public function reset(): void
100
    {
101
        $this->tags = [];
102
    }
103
}
104