MockApiResourceDataLayer::addId()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 10
rs 10
1
<?php
2
3
namespace Apie\MockPlugin\DataLayers;
4
5
use Apie\Core\Exceptions\ResourceNotFoundException;
6
use Apie\Core\IdentifierExtractor;
7
use Apie\Core\Interfaces\ApiResourcePersisterInterface;
8
use Apie\Core\Interfaces\ApiResourceRetrieverInterface;
9
use Apie\Core\Interfaces\SearchFilterProviderInterface;
10
use Apie\Core\SearchFilters\SearchFilterFromMetadataTrait;
11
use Apie\Core\SearchFilters\SearchFilterRequest;
12
use Apie\ObjectAccessNormalizer\ObjectAccess\ObjectAccessInterface;
13
use Pagerfanta\Pagerfanta;
14
use Psr\Cache\CacheItemPoolInterface;
15
use ReflectionClass;
16
17
/**
18
 * If the implementation of a REST API is mocked this is the class that persists and retrieves all API resources.
19
 *
20
 * It does this by persisting it with a cache pool.
21
 */
22
class MockApiResourceDataLayer implements ApiResourcePersisterInterface, ApiResourceRetrieverInterface, SearchFilterProviderInterface
23
{
24
    use SearchFilterFromMetadataTrait;
25
26
    /**
27
     * @var CacheItemPoolInterface
28
     */
29
    private $cacheItemPool;
30
31
    /**
32
     * @var IdentifierExtractor
33
     */
34
    private $identifierExtractor;
35
36
    /**
37
     * @var ObjectAccessInterface
38
     */
39
    private $objectAccess;
40
41
    public function __construct(
42
        CacheItemPoolInterface $cacheItemPool,
43
        IdentifierExtractor $identifierExtractor,
44
        ObjectAccessInterface $objectAccess
45
    ) {
46
        $this->cacheItemPool = $cacheItemPool;
47
        $this->identifierExtractor = $identifierExtractor;
48
        $this->objectAccess = $objectAccess;
49
    }
50
51
    /**
52
     * @param mixed $resource
53
     * @param array $context
54
     * @return mixed
55
     */
56
    public function persistNew($resource, array $context = [])
57
    {
58
        $id = $this->identifierExtractor->getIdentifierValue($resource, $context);
59
        if (is_null($id)) {
60
            return $resource;
61
        }
62
63
        $this->persist($resource, $id);
64
        return $resource;
65
    }
66
67
    /**
68
     * @param mixed $resource
69
     * @param string|int $int
70
     * @param array $context
71
     * @return mixed
72
     */
73
    public function persistExisting($resource, $int, array $context = [])
74
    {
75
        $this->persist($resource, $int);
76
        return $resource;
77
    }
78
79
    private function persist($resource, $id)
80
    {
81
        $cacheKey = 'mock-server.' . $this->shortName($resource) . '.' . $id;
82
        $cacheItem = $this->cacheItemPool->getItem($cacheKey)->set(serialize($resource));
83
        $this->addId(get_class($resource), $id);
84
        $this->cacheItemPool->save($cacheItem);
85
        $this->cacheItemPool->commit();
86
    }
87
88
    /**
89
     * @param string $resourceClass
90
     * @param string|int $id
91
     * @param array $context
92
     */
93
    public function remove(string $resourceClass, $id, array $context)
94
    {
95
        $cacheKey = 'mock-server.' . $this->shortName($resourceClass) . '.' . $id;
96
        $this->cacheItemPool->deleteItem($cacheKey);
97
        $this->removeId($resourceClass, $id);
98
        $this->cacheItemPool->commit();
99
    }
100
101
    /**
102
     * @param string $resourceClass
103
     * @param string|int $id
104
     * @param array $context
105
     * @return mixed
106
     */
107
    public function retrieve(string $resourceClass, $id, array $context)
108
    {
109
        $cacheKey = 'mock-server.' . $this->shortName($resourceClass) . '.' . $id;
110
        $cacheItem = $this->cacheItemPool->getItem($cacheKey);
111
        if (!$cacheItem->isHit()) {
112
            throw new ResourceNotFoundException((string) $id);
113
        }
114
        return unserialize($cacheItem->get());
115
    }
116
117
    /**
118
     * @param string $resourceClass
119
     * @param array $context
120
     * @param SearchFilterRequest $searchFilterRequest
121
     * @return Pagerfanta|array
122
     */
123
    public function retrieveAll(string $resourceClass, array $context, SearchFilterRequest $searchFilterRequest): iterable
124
    {
125
        $cacheKey = 'mock-server-all.' . $this->shortName($resourceClass);
126
        $cacheItem = $this->cacheItemPool->getItem($cacheKey);
127
        if (!$cacheItem->isHit()) {
128
            return [];
129
        }
130
        $paginator = new Pagerfanta(new MockAdapter($this, $cacheItem->get(), $searchFilterRequest->getSearches(), $resourceClass, $context, $this->objectAccess));
0 ignored issues
show
Bug introduced by
The type Apie\MockPlugin\DataLayers\MockAdapter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
131
        $searchFilterRequest->updatePaginator($paginator);
132
        return $paginator;
133
    }
134
135
    /**
136
     * Marks an id as found, so the get all can retrieve it.
137
     *
138
     * @param string $resourceClass
139
     * @param string|int $id
140
     */
141
    private function addId(string $resourceClass, $id)
142
    {
143
        $cacheKey = 'mock-server-all.' . $this->shortName($resourceClass);
144
        $cacheItem = $this->cacheItemPool->getItem($cacheKey);
145
        $ids = [];
146
        if ($cacheItem->isHit()) {
147
            $ids = $cacheItem->get();
148
        }
149
        $ids[$id] = $id;
150
        $this->cacheItemPool->save($cacheItem->set($ids));
151
    }
152
153
    /**
154
     * Marks an id as not found, so the get all will no longer retrieve it.
155
     *
156
     * @param string $resourceClass
157
     * @param string|int $id
158
     */
159
    private function removeId(string $resourceClass, $id)
160
    {
161
        $cacheKey = 'mock-server-all.' . $this->shortName($resourceClass);
162
        $cacheItem = $this->cacheItemPool->getItem($cacheKey);
163
        $ids = [];
164
        if ($cacheItem->isHit()) {
165
            $ids = $cacheItem->get();
166
        }
167
        unset($ids[$id]);
168
        $this->cacheItemPool->save($cacheItem->set($ids));
169
    }
170
171
    /**
172
     * Returns a short name of a resource or a resource class.
173
     *
174
     * @param mixed $resourceOrResourceClass
175
     * @return string
176
     */
177
    private function shortName($resourceOrResourceClass): string
178
    {
179
        if (is_string($resourceOrResourceClass)) {
180
            $refl = new ReflectionClass($resourceOrResourceClass);
181
182
            return $refl->getShortName();
183
        }
184
185
        return $this->shortName(get_class($resourceOrResourceClass));
186
    }
187
}
188