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