Passed
Push — master ( 159fd0...d43f04 )
by Paul
04:15
created

AbstractClient::createResponseTransform()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace CCT\Component\Rest;
6
7
use CCT\Component\Rest\Exception\InvalidParameterException;
8
use CCT\Component\Rest\Http\RequestInterface;
9
use CCT\Component\Rest\Http\SerializerRequestInterface;
10
use CCT\Component\Rest\Http\Transform\RequestTransform;
11
use CCT\Component\Rest\Http\Transform\ResponseTransform;
12
use CCT\Component\Rest\Serializer\Context\Context;
13
use CCT\Component\Rest\Serializer\JMSSerializerBuilder;
14
use CCT\Component\Rest\Transformer\Request\FormObjectTransformer;
15
use CCT\Component\Rest\Transformer\Response\ObjectCollectionTransformer;
16
use CCT\Component\Rest\Transformer\Response\ObjectTransformer;
17
use GuzzleHttp\Client as GuzzleClient;
18
use CCT\Component\Rest\Serializer\SerializerInterface;
19
20
abstract class AbstractClient
21
{
22
    /**
23
     * @var GuzzleClient
24
     */
25
    protected $client;
26
27
    /**
28
     * @var Config
29
     */
30
    protected $config;
31
32
    /**
33
     * @var bool
34
     */
35
    protected $defaultConfig = true;
36
37
    /**
38
     * @var SerializerInterface
39
     */
40
    protected static $serializer;
41
42
    /**
43
     * AbstractClient constructor.
44
     *
45
     * @param Config $config
46
     * @param bool $defaultConfig
47
     */
48 2
    public function __construct(Config $config, bool $defaultConfig = true)
49
    {
50 2
        if (false === $config->has(Config::ENDPOINT)) {
51 1
            throw new \InvalidArgumentException(
52 1
                sprintf("Configuration key %s is missing", Config::ENDPOINT)
53
            );
54
        }
55
56 2
        $this->defaultConfig = $defaultConfig;
57 2
        $this->config = $config;
58 2
        $this->client = new GuzzleClient([
59 2
            'base_uri' => $config->get(Config::ENDPOINT)
60
        ]);
61
62 2
        if ($defaultConfig) {
63 2
            $this->applyDefaults();
64
        }
65 2
    }
66
67
    /**
68
     * Enable Default Config
69
     */
70
    public function enableDefaultConfig(): void
71
    {
72
        $this->defaultConfig = true;
73
    }
74
75
    /**
76
     * Disabled default config
77
     */
78
    public function disableDefaultConfig(): void
79
    {
80
        $this->defaultConfig = false;
81
    }
82
83
    /**
84
     * Is default config enabled
85
     *
86
     * @return bool
87
     */
88
    public function isDefaultConfig(): bool
89
    {
90
        return $this->defaultConfig;
91
    }
92
93
    /**
94
     * Applies the default config
95
     *
96
     * @return mixed
97
     */
98
    abstract protected function applyDefaults();
99
100
    /**
101
     * Clears Config values
102
     */
103
    public function clearDefaults(): void
104
    {
105
        $this->config->remove(Config::METADATA_DIRS);
106
        $this->config->remove(Config::DEBUG);
107
        $this->config->remove(Config::EVENT_SUBSCRIBERS);
108
        $this->config->remove(Config::SERIALIZATION_HANDLERS);
109
        $this->config->remove(Config::OBJECT_CONSTRUCTOR);
110
        $this->config->remove(Config::USE_DEFAULT_RESPONSE_TRANSFORMERS);
111
    }
112
113
    /**
114
     * @param Config $config
115
     *
116
     * @return SerializerInterface|null
117
     * @throws \JMS\Serializer\Exception\RuntimeException
118
     * @throws \JMS\Serializer\Exception\InvalidArgumentException
119
     */
120 1
    protected function buildSerializer(Config $config): ?SerializerInterface
121
    {
122
123 1
        if (class_exists('JMS\Serializer\Serializer')) {
124 1
            return JMSSerializerBuilder::createByConfig($config)
125 1
                ->configureDefaults()
126 1
                ->build();
127
        }
128
129
        if (class_exists('Symfony\Component\Serializer\Serializer')) {
130
            return JMSSerializerBuilder::createByConfig($config)
131
                ->configureDefaults()
132
                ->build();
133
        }
134
135
        return null;
136
    }
137
138
    /**
139
     * Gets the built serializer
140
     *
141
     * @param Config $config
142
     *
143
     * @return SerializerInterface|null
144
     * @throws \JMS\Serializer\Exception\RuntimeException
145
     * @throws \JMS\Serializer\Exception\InvalidArgumentException
146
     */
147 1
    protected function getBuiltSerializer(Config $config): ?SerializerInterface
148
    {
149 1
        if (null === static::$serializer) {
150 1
            static::$serializer = $this->buildSerializer($config);
151
        }
152
153 1
        return static::$serializer;
154
    }
155
156
    /**
157
     * @param $class
158
     * @param Config $config
159
     * @param SerializerInterface|null $serializer
160
     *
161
     * @return object
162
     * @throws \ReflectionException
163
     * @throws \CCT\Component\Rest\Exception\InvalidParameterException
164
     */
165 1
    protected function createRequestInstance($class, Config $config, SerializerInterface $serializer = null)
166
    {
167 1
        $reflectionClass = new \ReflectionClass($class);
168
169 1
        if (!$reflectionClass->implementsInterface(RequestInterface::class)) {
170
            throw new InvalidParameterException(sprintf(
171
                'The class must be an instance of %s',
172
                RequestInterface::class
173
            ));
174
        }
175
176 1
        if (!$reflectionClass->implementsInterface(SerializerRequestInterface::class)) {
177
            return $reflectionClass->newInstance(
178
                $this->client
179
            );
180
        }
181
182 1
        return $reflectionClass->newInstance(
183 1
            $this->client,
184 1
            $config,
185 1
            $serializer,
186 1
            $this->createRequestTransform($config),
187 1
            $this->createResponseTransform($config)
188
        );
189
    }
190
191
    /**
192
     * Should use the default response transformers?
193
     *
194
     * @return bool
195
     */
196 1
    protected function shouldUseDefaultResponseTransformers(): bool
197
    {
198 1
        return (bool)$this->config->get(Config::USE_DEFAULT_RESPONSE_TRANSFORMERS, true);
199
    }
200
201
    /**
202
     * @param Config $config
203
     * @param SerializerInterface $serializer
204
     * @param $modelClass
205
     */
206 1
    protected function applyDefaultResponseTransformers(
207
        Config $config,
208
        SerializerInterface $serializer,
209
        $modelClass
210
    ): void {
211 1
        $config->set(Config::RESPONSE_TRANSFORMERS, [
212 1
            new ObjectTransformer($serializer, $modelClass, new Context()),
213 1
            new ObjectCollectionTransformer($serializer, $modelClass, new Context())
214
        ]);
215 1
    }
216
217
    /**
218
     * @param Config $config
219
     * @param SerializerInterface $serializer
220
     */
221
    protected function applyDefaultRequestTransformers(Config $config, SerializerInterface $serializer): void
222
    {
223
        $config->set(Config::REQUEST_TRANSFORMERS, [
224
            new FormObjectTransformer($serializer, new Context()),
225
        ]);
226
    }
227
228
    /**
229
     * @param Config $config
230
     *
231
     * @return RequestTransform|null
232
     */
233 1
    protected function createRequestTransform(Config $config): ?RequestTransform
234
    {
235 1
        return new RequestTransform(
236 1
            $config->get(Config::REQUEST_TRANSFORMERS, [])
237
        );
238
    }
239
240
    /**
241
     * @param Config $config
242
     *
243
     * @return ResponseTransform|null
244
     */
245 1
    protected function createResponseTransform(Config $config): ?ResponseTransform
246
    {
247 1
        return new ResponseTransform(
248 1
            $config->get(Config::RESPONSE_TRANSFORMERS, [])
249
        );
250
    }
251
}
252