MemoryDataLayer   A
last analyzed

Complexity

Total Complexity 13

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 37
c 1
b 0
f 0
dl 0
loc 118
rs 10
wmc 13

6 Methods

Rating   Name   Duplication   Size   Complexity  
A retrieve() 0 7 2
A persistExisting() 0 9 2
A persistNew() 0 17 4
A retrieveAll() 0 9 2
A __construct() 0 4 1
A remove() 0 4 2
1
<?php
2
namespace Apie\CorePlugin\DataLayers;
3
4
use Apie\Core\Exceptions\ResourceNotFoundException;
5
use Apie\Core\Interfaces\ApiResourcePersisterInterface;
6
use Apie\Core\Interfaces\ApiResourceRetrieverInterface;
7
use Apie\Core\Interfaces\SearchFilterProviderInterface;
8
use Apie\Core\SearchFilters\SearchFilterFromMetadataTrait;
9
use Apie\Core\SearchFilters\SearchFilterHelper;
10
use Apie\Core\SearchFilters\SearchFilterRequest;
11
use Apie\CorePlugin\Exceptions\CanNotDetermineIdException;
12
use Apie\ObjectAccessNormalizer\ObjectAccess\ObjectAccess;
13
use Apie\ObjectAccessNormalizer\ObjectAccess\ObjectAccessInterface;
14
use Pagerfanta\Pagerfanta;
15
use W2w\Lib\Apie\Core\IdentifierExtractor;
0 ignored issues
show
Bug introduced by
The type W2w\Lib\Apie\Core\IdentifierExtractor 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...
16
17
/**
18
 * Persists and retrieves from an array in memory. Only useful for unit tests.
19
 */
20
class MemoryDataLayer implements ApiResourcePersisterInterface, ApiResourceRetrieverInterface, SearchFilterProviderInterface
21
{
22
    use SearchFilterFromMetadataTrait;
23
24
    /**
25
     * @var ObjectAccessInterface
26
     */
27
    private $propertyAccessor;
28
29
    /**
30
     * @var IdentifierExtractor
31
     */
32
    private $identifierExtractor;
33
34
    /**
35
     * @var mixed[]
36
     */
37
    private $persisted = [];
38
39
    public function __construct(ObjectAccessInterface $propertyAccessor = null, IdentifierExtractor $identifierExtractor = null)
40
    {
41
        $this->propertyAccessor = $propertyAccessor ?? new ObjectAccess();
42
        $this->identifierExtractor = $identifierExtractor ?? new IdentifierExtractor($this->propertyAccessor);
43
    }
44
    /**
45
     * Persist a new API resource. Should return the new API resource.
46
     *
47
     * @param mixed $resource
48
     * @param array $context
49
     * @return mixed
50
     */
51
    public function persistNew($resource, array $context = [])
52
    {
53
        $className = get_class($resource);
54
        $identifier = $this->identifierExtractor->getIdentifierKey($resource, $context);
55
        $keepReference = $context['keep_reference'] ?? false;
56
        if (null === $identifier) {
57
            throw new CanNotDetermineIdException($resource, $identifier ?? 'id');
58
        }
59
        $id = (string) $this->propertyAccessor->getValue($resource, $identifier);
60
        if (empty($this->persisted[$className])) {
61
            $this->persisted[$className] = [];
62
        }
63
        if (!$keepReference) {
64
            $resource = clone $resource;
65
        }
66
        $this->persisted[$className][$id] = $resource;
67
        return $resource;
68
    }
69
70
    /**
71
     * Persist an existing API resource. The input resource is the modified API resource. Should return the new API
72
     * resource.
73
     *
74
     * @param mixed $resource
75
     * @param string|int $int
76
     * @param array $context
77
     * @return mixed
78
     */
79
    public function persistExisting($resource, $int, array $context = [])
80
    {
81
        $className = get_class($resource);
82
        $keepReference = $context['keep_reference'] ?? false;
83
        if (!$keepReference) {
84
            $resource = clone $resource;
85
        }
86
        $this->persisted[$className][(string) $int] = $resource;
87
        return $resource;
88
    }
89
90
    /**
91
     * Removes an existing API resource.
92
     *
93
     * @param string $resourceClass
94
     * @param string|int $id
95
     * @param array $context
96
     */
97
    public function remove(string $resourceClass, $id, array $context)
98
    {
99
        if (!empty($this->persisted[$resourceClass][$id])) {
100
            unset($this->persisted[$resourceClass][$id]);
101
        }
102
    }
103
104
    /**
105
     * Retrieves a single resource by some identifier.
106
     *
107
     * @param string $resourceClass
108
     * @param string|int $id
109
     * @param array $context
110
     * @return mixed
111
     */
112
    public function retrieve(string $resourceClass, $id, array $context)
113
    {
114
        $id = (string) $id;
115
        if (empty($this->persisted[$resourceClass][$id])) {
116
            throw new ResourceNotFoundException($id);
117
        }
118
        return $this->persisted[$resourceClass][$id];
119
    }
120
121
    /**
122
     * Retrieves a list of resources with some pagination.
123
     *
124
     * @param string $resourceClass
125
     * @param array $context
126
     * @param SearchFilterRequest $searchFilterRequest
127
     * @return Pagerfanta|array
128
     */
129
    public function retrieveAll(string $resourceClass, array $context, SearchFilterRequest $searchFilterRequest): iterable
130
    {
131
        if (empty($this->persisted[$resourceClass])) {
132
            return [];
133
        }
134
        return SearchFilterHelper::applyPaginationToSearchFilter(
135
            $this->persisted[$resourceClass],
136
            $searchFilterRequest,
137
            $this->propertyAccessor
138
        );
139
    }
140
}
141