Passed
Branch master (776013)
by payever
03:51
created

CommonApiClient::loadTokens()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 9
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace Payever\ExternalIntegration\Core;
4
5
use Payever\ExternalIntegration\Core\Authorization\DummyOauthTokenList;
6
use Payever\ExternalIntegration\Core\Authorization\OauthToken;
7
use Payever\ExternalIntegration\Core\Authorization\OauthTokenList;
8
use Payever\ExternalIntegration\Core\Base\ClientConfigurationInterface;
9
use Payever\ExternalIntegration\Core\Base\CommonApiClientInterface;
10
use Payever\ExternalIntegration\Core\Base\HttpClientInterface;
11
use Payever\ExternalIntegration\Core\Base\OauthTokenInterface;
12
use Payever\ExternalIntegration\Core\Base\ResponseInterface;
13
use Payever\ExternalIntegration\Core\Http\Client\CurlClient;
14
use Payever\ExternalIntegration\Core\Http\RequestBuilder;
15
use Payever\ExternalIntegration\Core\Http\RequestEntity\AuthenticationRequest;
16
use Payever\ExternalIntegration\Core\Http\ResponseEntity\AuthenticationResponse;
17
use Payever\ExternalIntegration\Core\Http\ResponseEntity\GetCurrenciesResponse;
18
use Payever\ExternalIntegration\Core\Http\ResponseEntity\ListChannelSetsResponse;
19
use Psr\Log\LoggerAwareInterface;
20
21
class CommonApiClient implements CommonApiClientInterface
22
{
23
    const URL_SANDBOX = 'https://sandbox.payever.de/';
24
    const URL_LIVE    = 'https://mein.payever.de/';
25
26
    const SUB_URL_AUTH              = 'oauth/v2/token';
27
    const SUB_URL_LIST_CHANNEL_SETS = 'api/shop/%s/channel-sets';
28
    const SUB_URL_CURRENCY          = 'api/rest/v1/currency';
29
30
    /**
31
     * Stores oAuth Authentication Tokens
32
     *
33
     * @var OauthTokenList $tokens
34
     */
35
    protected $tokens;
36
37
    /**
38
     * Stores API Configuration
39
     *
40
     * @var ClientConfigurationInterface $configuration
41
     */
42
    protected $configuration;
43
44
    /**
45
     * Stores current Client
46
     *
47
     * @var HttpClientInterface $httpClient
48
     */
49
    protected $httpClient;
50
51
    /**
52
     * Payever Payments API Instance constructor
53
     *
54
     * @param ClientConfigurationInterface $clientConfiguration
55
     * @param OauthTokenList $oauthTokenList
56
     * @param HttpClientInterface $httpClient
57
     *
58
     * @throws \Exception
59
     */
60
    public function __construct(
61
        ClientConfigurationInterface $clientConfiguration,
62
        OauthTokenList $oauthTokenList = null,
63
        HttpClientInterface $httpClient = null
64
    ) {
65
        $this->configuration = $clientConfiguration;
66
        $this->httpClient = $httpClient;
67
        $this->loadTokens($oauthTokenList);
68
    }
69
70
    /**
71
     * Returns Base URL to payever Payments API
72
     *
73
     * @return string
74
     */
75
    public function getBaseUrl()
76
    {
77
        switch ($this->configuration->getApiMode()) {
78
            case ClientConfiguration::API_MODE_SANDBOX:
79
                $url = $this->configuration->getCustomApiUrl() ?: static::URL_SANDBOX;
80
                break;
81
            case ClientConfiguration::API_MODE_LIVE:
82
            default:
83
                $url = static::URL_LIVE;
84
                break;
85
        }
86
87
        if (substr($url, -1) != '/') {
88
            $url .= '/';
89
        }
90
91
        return $url;
92
    }
93
94
    /**
95
     * Returns current configuration
96
     *
97
     * @return ClientConfigurationInterface
98
     */
99
    public function getConfiguration()
100
    {
101
        return $this->configuration;
102
    }
103
104
    /**
105
     * Returns current OauthToken list
106
     *
107
     * @return OauthTokenList
108
     */
109
    public function getTokens()
110
    {
111
        return $this->tokens;
112
    }
113
114
    /**
115
     * Overrides configuration
116
     *
117
     * @param ClientConfigurationInterface $configuration
118
     */
119
    public function setConfiguration(ClientConfigurationInterface $configuration)
120
    {
121
        $this->configuration = $configuration;
122
123
        $this->getTokens()->clear()->save();
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function getHttpClient()
130
    {
131
        if ($this->httpClient === null) {
132
            $this->httpClient = new CurlClient();
133
        }
134
135
        if ($this->httpClient instanceof LoggerAwareInterface) {
136
            $this->httpClient->setLogger($this->configuration->getLogger());
137
        }
138
139
        return $this->httpClient;
140
    }
141
142
    /**
143
     * {@inheritdoc}
144
     */
145
    public function setHttpClient(HttpClientInterface $httpClient)
146
    {
147
        $this->configuration->getLogger()->debug(
148
            sprintf('Got new HTTP Client: %s', get_class($httpClient))
149
        );
150
151
        $this->httpClient = $httpClient;
152
153
        return $this;
154
    }
155
156
    /**
157
     * Returns Authentication OauthToken
158
     *
159
     * @param string $scope OauthToken scope
160
     *
161
     * @return OauthTokenInterface
162
     *
163
     * @throws \Exception
164
     */
165
    public function getToken($scope = OauthTokenInterface::SCOPE_PAYMENT_ACTIONS)
166
    {
167
        $key = md5($this->getConfiguration()->getHash() . $scope);
168
169
        $this->configuration->getLogger()->debug(sprintf('Getting OAuth token. Hash: %s', $key));
170
171
        /** @var OauthTokenInterface|boolean $token */
172
        $token = $this->getTokens()->get($key);
173
174
        if (!$token || ($token->isExpired() && !$token->isRefreshable())) {
175
            $tokenData = $this->obtainTokenRequest($scope)->getResponseEntity()->toArray();
176
177
            $token = $this->getTokens()->add(
178
                $key,
179
                $this->getTokens()->create()->load($tokenData)->setUpdatedAt()
180
            )->get($key);
181
182
            $this->getTokens()->save();
183
        } elseif ($token->isExpired() && $token->isRefreshable()) {
184
            $tokenData = $this->refreshTokenRequest($token)->getResponseEntity()->toArray();
0 ignored issues
show
Bug introduced by
$token of type true is incompatible with the type Payever\ExternalIntegrat...ase\OauthTokenInterface expected by parameter $token of Payever\ExternalIntegrat...::refreshTokenRequest(). ( Ignorable by Annotation )

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

184
            $tokenData = $this->refreshTokenRequest(/** @scrutinizer ignore-type */ $token)->getResponseEntity()->toArray();
Loading history...
185
186
            $token->load($tokenData)->setUpdatedAt();
187
188
            $this->getTokens()->save();
189
        }
190
191
        $this->configuration->getLogger()->debug(
192
            sprintf('Got OAuth token. Hash: %s', $key),
193
            $token->getParams()
194
        );
195
196
        return $token;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $token also could return the type array|boolean which is incompatible with the documented return type Payever\ExternalIntegrat...ase\OauthTokenInterface.
Loading history...
197
    }
198
199
    /**
200
     * {@inheritdoc}
201
     *
202
     * @throws \Exception
203
     */
204
    public function getCurrenciesRequest($lang = '')
205
    {
206
        $request = RequestBuilder::get($this->getCurrenciesURL($lang))
207
            ->setResponseEntity(new GetCurrenciesResponse())
208
            ->build()
209
        ;
210
211
        $response = $this->getHttpClient()->execute($request);
212
213
        return $response;
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     *
219
     * @throws \Exception
220
     */
221
    public function listChannelSetsRequest($businessUuid)
222
    {
223
        $this->configuration->assertLoaded();
224
225
        $request = RequestBuilder::get($this->getListChannelSetsURL($businessUuid))
226
            ->setResponseEntity(new ListChannelSetsResponse())
227
            ->build()
228
        ;
229
230
        $response = $this->getHttpClient()->execute($request);
231
232
        return $response;
233
    }
234
235
    /**
236
     * Loads Tokens
237
     *
238
     * @param OauthTokenList|null $oauthTokenList
239
     *
240
     * @return $this
241
     */
242
    protected function loadTokens(OauthTokenList $oauthTokenList = null)
243
    {
244
        if (is_null($oauthTokenList)) {
245
            $oauthTokenList = new DummyOauthTokenList();
246
        }
247
248
        $this->tokens = $oauthTokenList->load();
249
250
        return $this;
251
    }
252
253
    /**
254
     * Requests new oAuth OauthToken which will be used further
255
     *
256
     * @link https://getpayever.com/developer/api-documentation/#authentication Documentation
257
     *
258
     * @param string $scope Scope in which the token will be used
259
     *
260
     * @return ResponseInterface
261
     *
262
     * @throws \Exception
263
     */
264
    protected function obtainTokenRequest($scope)
265
    {
266
        $this->configuration->assertLoaded();
267
268
        if (!in_array($scope, OauthToken::getScopes())) {
269
            throw new \Exception('Scope provided is not valid');
270
        }
271
272
        $requestEntity = new AuthenticationRequest();
273
        $requestEntity
274
            ->setClientId($this->configuration->getClientId())
275
            ->setClientSecret($this->configuration->getClientSecret())
276
            ->setScope($scope)
277
            ->setGrantType(OauthTokenInterface::GRAND_TYPE_OBTAIN_TOKEN)
278
        ;
279
280
        $request = RequestBuilder::post($this->getAuthenticationURL())
281
            ->setRequestEntity($requestEntity)
282
            ->setResponseEntity(new AuthenticationResponse())
283
            ->build()
284
        ;
285
286
        $response = $this->getHttpClient()->execute($request);
287
288
        return $response;
289
    }
290
291
    /**
292
     * Requests for an updated oAuth OauthToken data
293
     *
294
     * @param OauthTokenInterface|object|array $token OauthToken for the update
295
     *
296
     * @return ResponseInterface
297
     *
298
     * @throws \Exception
299
     */
300
    protected function refreshTokenRequest(OauthTokenInterface $token)
301
    {
302
        $this->configuration->assertLoaded();
303
304
        $requestEntity = new AuthenticationRequest();
305
        $requestEntity
306
            ->setClientId($this->configuration->getClientId())
307
            ->setClientSecret($this->configuration->getClientSecret())
308
            ->setScope($token->getScope())
309
            ->setGrantType(OauthTokenInterface::GRAND_TYPE_REFRESH_TOKEN)
310
            ->setRefreshToken($token->getRefreshToken())
311
        ;
312
313
        $request = RequestBuilder::post($this->getAuthenticationURL())
314
            ->setRequestEntity($requestEntity)
315
            ->setResponseEntity(new AuthenticationResponse())
316
            ->build()
317
        ;
318
319
        $response = $this->getHttpClient()->execute($request);
320
321
        return $response;
322
    }
323
324
    /**
325
     * Returns URL for Authentication path
326
     *
327
     * @return string
328
     */
329
    protected function getAuthenticationURL()
330
    {
331
        return $this->getBaseUrl() . self::SUB_URL_AUTH;
332
    }
333
334
    /**
335
     * Returns URL for Available Channel Sets path
336
     *
337
     * @param string $businessUuid
338
     *
339
     * @return string
340
     */
341
    protected function getListChannelSetsURL($businessUuid)
342
    {
343
        return $this->getBaseUrl() . sprintf(self::SUB_URL_LIST_CHANNEL_SETS, $businessUuid);
344
    }
345
346
    /**
347
     * Returns URL to Currencies path
348
     *
349
     * @param string $lang
350
     *
351
     * @return string
352
     */
353
    protected function getCurrenciesURL($lang = '')
354
    {
355
        return $this->getBaseUrl() . self::SUB_URL_CURRENCY . (empty($lang) ? '' : '?_locale=' . $lang);
356
    }
357
}
358