Passed
Push — master ( 01c95e...1b44dd )
by Julien
01:08
created

SdkClient   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 226
Duplicated Lines 0 %

Test Coverage

Coverage 32%

Importance

Changes 0
Metric Value
eloc 93
dl 0
loc 226
ccs 24
cts 75
cp 0.32
rs 10
c 0
b 0
f 0
wmc 23

11 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 19 3
A getCachePrefix() 0 3 1
A getSerializer() 0 3 1
A getCacheItemPool() 0 3 1
A setCacheItemPool() 0 8 1
A getModelHydrator() 0 3 1
A getRestClient() 0 3 1
A getRepository() 0 23 3
A getMapping() 0 3 1
A setFileCachePath() 0 6 1
B createProxy() 0 77 9
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Mapado\RestClientSdk;
6
7
use Mapado\RestClientSdk\Model\ModelHydrator;
8
use Mapado\RestClientSdk\Model\Serializer;
9
use ProxyManager\Configuration;
10
use ProxyManager\Factory\LazyLoadingGhostFactory;
11
use ProxyManager\Proxy\GhostObjectInterface;
12
use Psr\Cache\CacheItemPoolInterface;
13
14
/**
15
 * Sdk Client
16
 */
17
class SdkClient
18
{
19
    /**
20
     * @var RestClient
21
     */
22
    protected $restClient;
23
24
    /**
25
     * Cache item pool.
26
     *
27
     * @var ?CacheItemPoolInterface
28
     */
29
    protected $cacheItemPool;
30
31
    /**
32
     * Cache prefix.
33
     *
34
     * @var string
35
     */
36
    protected $cachePrefix;
37
38
    /**
39
     * @var Mapping
40
     */
41
    private $mapping;
42
43
    /**
44
     * @var Serializer
45
     */
46
    private $serializer;
47
48
    /**
49
     * @var ModelHydrator
50
     */
51
    private $modelHydrator;
52
53
    /**
54
     * @var array
55
     */
56
    private $repositoryList = [];
57
58
    /**
59
     * proxyManagerConfig
60
     *
61
     * @var ?Configuration
62
     */
63
    private $proxyManagerConfig;
64
65
    /**
66
     * unitOfWork
67
     *
68
     * @var UnitOfWork
69
     */
70
    private $unitOfWork;
71
72
    public function __construct(
73
        RestClient $restClient,
74
        Mapping $mapping,
75
        ?UnitOfWork $unitOfWork = null,
76
        ?Serializer $serializer = null
77
    ) {
78 1
        $this->restClient = $restClient;
79 1
        $this->mapping = $mapping;
80 1
        if (null === $unitOfWork) {
81
            $unitOfWork = new UnitOfWork($this->mapping);
82
        }
83 1
        $this->unitOfWork = $unitOfWork;
84 1
        if (null === $serializer) {
85
            $serializer = new Serializer($this->mapping, $this->unitOfWork);
86
        }
87 1
        $this->serializer = $serializer;
88 1
        $this->serializer->setSdk($this);
89
90 1
        $this->modelHydrator = new ModelHydrator($this);
91 1
    }
92
93
    public function setCacheItemPool(
94
        CacheItemPoolInterface $cacheItemPool,
95
        string $cachePrefix = ''
96
    ): self {
97
        $this->cacheItemPool = $cacheItemPool;
98
        $this->cachePrefix = $cachePrefix;
99
100
        return $this;
101
    }
102
103
    public function getCacheItemPool(): ?CacheItemPoolInterface
104
    {
105
        return $this->cacheItemPool;
106
    }
107
108
    public function getCachePrefix(): string
109
    {
110
        return $this->cachePrefix;
111
    }
112
113
    public function getRepository(string $modelName): EntityRepository
114
    {
115
        // get repository by key
116 1
        $metadata = $this->mapping->getClassMetadataByKey($modelName);
117 1
        if (!$metadata) {
118
            // get by classname
119 1
            $metadata = $this->mapping->getClassMetadata($modelName);
120
        }
121
122 1
        $modelName = $metadata->getModelName();
123
124 1
        if (!isset($this->repositoryList[$modelName])) {
125 1
            $repositoryName = $metadata->getRepositoryName();
126
127 1
            $this->repositoryList[$modelName] = new $repositoryName(
128 1
                $this,
129 1
                $this->restClient,
130 1
                $this->unitOfWork,
131 1
                $modelName
132
            );
133
        }
134
135 1
        return $this->repositoryList[$modelName];
136
    }
137
138
    public function getRestClient(): RestClient
139
    {
140 1
        return $this->restClient;
141
    }
142
143
    public function getMapping(): Mapping
144
    {
145 1
        return $this->mapping;
146
    }
147
148
    public function getSerializer(): Serializer
149
    {
150 1
        return $this->serializer;
151
    }
152
153
    public function getModelHydrator(): ModelHydrator
154
    {
155
        return $this->modelHydrator;
156
    }
157
158
    public function createProxy(string $id): GhostObjectInterface
159
    {
160
        $key = $this->mapping->getKeyFromId($id);
161
        $classMetadata = $this->mapping->getClassMetadataByKey($key);
162
163
        if (null === $classMetadata) {
164
            throw new \RuntimeException(
165
                "Unable to get classMetadata for key {$key}. This should not happen."
166
            );
167
        }
168
169
        $modelName = $classMetadata->getModelName();
170
171
        $sdk = $this;
172
173
        if ($this->proxyManagerConfig) {
174
            $factory = new LazyLoadingGhostFactory($this->proxyManagerConfig);
175
        } else {
176
            $factory = new LazyLoadingGhostFactory();
177
        }
178
179
        $proxyModelName = preg_replace('/^\\\\*/', '', $modelName);
180
181
        $initializer = function (
182
            GhostObjectInterface $proxy,
183
            string $method,
184
            array $parameters,
185
            &$initializer,
186
            array $properties
187
        ) use ($sdk, $classMetadata, $id, $proxyModelName) {
188
            $isAllowedMethod =
189
                'jsonSerialize' === $method ||
190
                '__set' === $method ||
191
                '__isset' === $method && 'id' === $parameters['name'];
192
193
            if (!$isAllowedMethod) {
194
                $initializer = null; // disable initialization
195
                // load data and modify the object here
196
                if ($id) {
197
                    $repository = $sdk->getRepository(
198
                        $classMetadata->getModelName()
199
                    );
200
                    $model = $repository->find($id);
201
202
                    $attributeList = $classMetadata->getAttributeList();
203
204
                    foreach ($attributeList as $attribute) {
205
                        $getter =
206
                            'get' . ucfirst($attribute->getAttributeName());
207
                        $value = $model->{$getter}();
208
                        $properties[
209
                            "\0" .
210
                            $proxyModelName .
211
                            "\0" .
212
                            $attribute->getAttributeName()
213
                        ] = $value;
214
                    }
215
                }
216
217
                return true; // confirm that initialization occurred correctly
218
            }
219
        };
220
221
        // initialize the proxy instance
222
        $instance = $factory->createProxy($modelName, $initializer, [
223
            'skippedProperties' => ["\0" . $proxyModelName . "\0id"],
224
        ]);
225
226
        // set the id of the object
227
        $idReflexion = new \ReflectionProperty(
228
            $modelName,
229
            $classMetadata->getIdentifierAttribute()->getAttributeName()
230
        );
231
        $idReflexion->setAccessible(true);
232
        $idReflexion->setValue($instance, $id);
233
234
        return $instance;
235
    }
236
237
    public function setFileCachePath(string $fileCachePath): self
238
    {
239
        $this->proxyManagerConfig = new Configuration();
240
        $this->proxyManagerConfig->setProxiesTargetDir($fileCachePath);
241
242
        return $this;
243
    }
244
}
245