Passed
Push — master ( 24d2dd...159fd0 )
by Paul
04:04
created

src/AbstractClient.php (1 issue)

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