Passed
Push — master ( beb92a...89f5ec )
by Ludwig
01:48
created

Client.php (1 issue)

Labels
Severity
1
<?php
2
3
/*
4
 * This file is part of datamolino client.
5
 *
6
 * (c) 2018 cwd.at GmbH <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Cwd\Datamolino;
15
16
use Cwd\Datamolino\Model\Token;
17
use GuzzleHttp\Psr7\Request;
18
use Http\Client\HttpClient;
19
use Http\Discovery\HttpClientDiscovery;
20
use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor;
21
use Symfony\Component\Serializer\Encoder\JsonEncoder;
22
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
23
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
24
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
25
use Symfony\Component\Serializer\Serializer;
26
use GuzzleHttp\Client as GuzzleClient;
27
28
class Client
29
{
30
    private $apiUrl = 'https://beta.datamolino.com';
31
    private $apiVersion = 'v1_2';
32
    private $apiUri;
33
    private $tokenUrl;
34
    /** @var Token */
35
    private $token;
36
37
    /** @var HttpClient */
38
    private $client;
39
40
    /** @var Serializer */
41
    private $serializer;
42
43
    public function __construct(?GuzzleClient $client = null)
44
    {
45
        if (null === $client) {
46
            $this->client = HttpClientDiscovery::find();
47
        }
48
        $this->apiUri = sprintf('%s/api/%s/', $this->apiUrl, $this->apiVersion);
49
        $this->tokenUrl = $this->apiUrl.'/oauth/token';
50
51
        $normalizer = new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter(), null, new ReflectionExtractor());
52
        $this->serializer = new Serializer([new DateTimeNormalizer(), $normalizer], ['json' => new JsonEncoder()]);
53
    }
54
55
    /**
56
     * @param string|null     $payload
57
     * @param int|string|null $id
58
     * @param string          $endpoint
59
     * @param string|null     $hydrationClass
60
     * @param bool            $isList
61
     * @param string          $method
62
     * @param string|null     $urlExtension   - Special case only needed when retrieving original file!
63
     *
64
     * @throws \Http\Client\Exception
65
     * @throws \LogicException
66
     *
67
     * @return mixed
68
     */
69
    public function call($payload = null, $id = null, $endpoint = '', $hydrationClass = null, $isList = false, $method = 'POST', $urlExtension = null)
70
    {
71
        if (!$this->token instanceof Token) {
72
            throw new \LogicException('Token not set - Authenticate first - or store refresh token for later use');
73
        }
74
75
        if (in_array($method, ['GET', 'PUT', 'DELETE'])) {
76
            $format = (is_int($id)) ? '%s%s/%s' : '%s%s%s';
77
            $uri = sprintf($format, $this->apiUri, $endpoint, $id);
78
        } else {
79
            $uri = (null !== $id) ? sprintf('%s%s/%s', $this->apiUri, $endpoint, $id) : $this->apiUri.$endpoint;
80
        }
81
82
        /* Special case only needed for retrieve original file */
83
        if (null !== $urlExtension) {
84
            $uri .= $urlExtension;
85
        }
86
87
        $request = new Request($method, $uri, [
88
            'Authorization' => sprintf('Bearer %s', $this->token->getAccessToken()),
89
            'Content-Type' => 'application/json',
90
        ], $payload);
91
92
        $response = $this->client->sendRequest($request);
93
        $responseBody = $response->getBody()->getContents();
94
        $responseData = json_decode($responseBody);
95
96
        dump($responseData);
0 ignored issues
show
The function dump was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

96
        /** @scrutinizer ignore-call */ 
97
        dump($responseData);
Loading history...
97
98
        if ($response->getStatusCode() >= 300) {
99
            $message = isset($responseData->message) ?? 'Unknown';
100
            throw new \Exception(sprintf('Error on request %s: %s', $response->getStatusCode(), $message));
101
        }
102
103
        if (null !== $hydrationClass && class_exists($hydrationClass) && isset($responseData->$endpoint)) {
104
            return $this->denormalizeObject($hydrationClass, $responseData->$endpoint, $isList);
105
        } elseif (null !== $hydrationClass && !class_exists($hydrationClass)) {
106
            throw new \Exception(sprintf('HydrationClass (%s) does not exist', $hydrationClass));
107
        } elseif (null !== $hydrationClass && !isset($responseData->$endpoint)) {
108
            throw new \Exception(sprintf('Datapoint (%s) does not exist', $endpoint));
109
        }
110
111
        return $responseData;
112
    }
113
114
    /**
115
     * @param string $clientId
116
     * @param string $clientSecret
117
     * @param string $username
118
     * @param string $password
119
     *
120
     * @throws \Http\Client\Exception
121
     *
122
     * @return Token
123
     */
124
    public function authenticatePassword($clientId, string $clientSecret, string $username, string $password): Token
125
    {
126
        $request = new Request('POST', $this->tokenUrl, [
127
            'Content-Type' => 'application/json',
128
        ], json_encode([
129
            'client_id' => $clientId,
130
            'client_secret' => $clientSecret,
131
            'username' => $username,
132
            'password' => $password,
133
            'grant_type' => 'password',
134
        ]));
135
136
        $response = $this->getClient()->sendRequest($request);
137
        $responseBody = $response->getBody()->getContents();
138
        $this->token = $this->denormalizeObject(Token::class, [json_decode($responseBody)], false);
139
140
        return $this->token;
141
    }
142
143
    /**
144
     * @param string $clientId
145
     * @param string $clientSecret
146
     * @param string $refreshToken
147
     *
148
     * @throws \Http\Client\Exception
149
     *
150
     * @return Token
151
     */
152
    public function refreshToken($clientId, $clientSecret, $refreshToken): Token
153
    {
154
        $request = new Request('POST', $this->tokenUrl, [
155
            'Content-Type' => 'application/json',
156
        ], json_encode([
157
            'client_id' => $clientId,
158
            'client_secret' => $clientSecret,
159
            'refresh_token' => $refreshToken,
160
            'grant_type' => 'refresh_token',
161
        ]));
162
163
        $response = $this->getClient()->sendRequest($request);
164
        $responseBody = $response->getBody()->getContents();
165
166
        $this->token = $this->denormalizeObject(Token::class, [json_decode($responseBody)], false);
167
168
        return $this->token;
169
    }
170
171
    public function setToken(Token $token): Client
172
    {
173
        $this->token = $token;
174
175
        return $this;
176
    }
177
178
    /**
179
     * @return string
180
     */
181
    public function getApiUrl(): string
182
    {
183
        return $this->apiUrl;
184
    }
185
186
    /**
187
     * @param string $apiUrl
188
     *
189
     * @return Client
190
     */
191
    public function setApiUrl(string $apiUrl): Client
192
    {
193
        $this->apiUrl = $apiUrl;
194
195
        return $this;
196
    }
197
198
    /**
199
     * @return string
200
     */
201
    public function getApiVersion(): string
202
    {
203
        return $this->apiVersion;
204
    }
205
206
    /**
207
     * @param string $apiVersion
208
     *
209
     * @return Client
210
     */
211
    public function setApiVersion(string $apiVersion): Client
212
    {
213
        $this->apiVersion = $apiVersion;
214
215
        return $this;
216
    }
217
218
    /**
219
     * @return string
220
     */
221
    public function getApiUri(): string
222
    {
223
        return $this->apiUri;
224
    }
225
226
    /**
227
     * @param string $apiUri
228
     *
229
     * @return Client
230
     */
231
    public function setApiUri(string $apiUri): Client
232
    {
233
        $this->apiUri = $apiUri;
234
235
        return $this;
236
    }
237
238
    /**
239
     * @return string
240
     */
241
    public function getTokenUrl(): string
242
    {
243
        return $this->tokenUrl;
244
    }
245
246
    /**
247
     * @param string $tokenUrl
248
     *
249
     * @return Client
250
     */
251
    public function setTokenUrl(string $tokenUrl): Client
252
    {
253
        $this->tokenUrl = $tokenUrl;
254
255
        return $this;
256
    }
257
258
    public function denormalizeObject($hydrationClass, $dataObject, $isList = false)
259
    {
260
        $result = [];
261
262
        foreach ($dataObject as $data) {
263
            $result[] = $this->serializer->denormalize($data, $hydrationClass, null, [
264
                ObjectNormalizer::DISABLE_TYPE_ENFORCEMENT => true,
265
            ]);
266
        }
267
268
        if ($isList) {
269
            return $result;
270
        }
271
272
        return current($result);
273
    }
274
275
    protected function getClient(): HttpClient
276
    {
277
        return $this->client;
278
    }
279
280
    /**
281
     * @return Serializer
282
     */
283
    public function getSerializer(): Serializer
284
    {
285
        return $this->serializer;
286
    }
287
}
288