Passed
Push — master ( 424d33...081b0f )
by Jonathan
14:08
created

AbstractReportingCloud::getAuthorizationHeader()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 13
ccs 8
cts 8
cp 1
rs 10
c 0
b 0
f 0
cc 4
nc 3
nop 0
crap 4
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * ReportingCloud PHP Wrapper
6
 *
7
 * PHP wrapper for ReportingCloud Web API. Authored and supported by Text Control GmbH.
8
 *
9
 * @link      https://www.reporting.cloud to learn more about ReportingCloud
10
 * @link      https://github.com/TextControl/txtextcontrol-reportingcloud-php for the canonical source repository
11
 * @license   https://raw.githubusercontent.com/TextControl/txtextcontrol-reportingcloud-php/master/LICENSE.md
12
 * @copyright © 2019 Text Control GmbH
13
 */
14
15
namespace TxTextControl\ReportingCloud;
16
17
use GuzzleHttp\Client;
18
use GuzzleHttp\Exception\GuzzleException;
19
use GuzzleHttp\Psr7\Response;
20
use GuzzleHttp\RequestOptions;
21
use TxTextControl\ReportingCloud\Exception\InvalidArgumentException;
22
use TxTextControl\ReportingCloud\Exception\RuntimeException;
23
use TxTextControl\ReportingCloud\Filter\Filter;
24
25
/**
26
 * Abstract ReportingCloud
27
 *
28
 * @package TxTextControl\ReportingCloud
29
 * @author  Jonathan Maron (@JonathanMaron)
30
 */
31
abstract class AbstractReportingCloud
32
{
33
    // <editor-fold desc="Constants (default values)">
34
35
    /**
36
     * Default date/time format of backend is 'ISO 8601'
37
     *
38
     * Note, last letter is 'P' and not 'O':
39
     *
40
     * O - Difference to Greenwich time (GMT) in hours (e.g. +0200)
41
     * P - Difference to Greenwich time (GMT) with colon between hours and minutes (e.g. +02:00)
42
     *
43
     * Backend uses the 'P' variant
44
     *
45
     * @const DEFAULT_DATE_FORMAT
46
     */
47
    public const DEFAULT_DATE_FORMAT = 'Y-m-d\TH:i:sP';
48
49
    /**
50
     * Default time zone of backend
51
     *
52
     * @const DEFAULT_TIME_ZONE
53
     */
54
    public const DEFAULT_TIME_ZONE = 'UTC';
55
56
    /**
57
     * Default base URI of backend
58
     *
59
     * @const DEFAULT_BASE_URI
60
     */
61
    protected const DEFAULT_BASE_URI = 'https://api.reporting.cloud';
62
63
    /**
64
     * Default version string of backend
65
     *
66
     * @const DEFAULT_VERSION
67
     */
68
    protected const DEFAULT_VERSION = 'v1';
69
70
    /**
71
     * Default timeout of backend in seconds
72
     *
73
     * @const DEFAULT_TIMEOUT
74
     */
75
    protected const DEFAULT_TIMEOUT = 120;
76
77
    /**
78
     * Default test flag of backend
79
     *
80
     * @const DEFAULT_TEST
81
     */
82
    protected const DEFAULT_TEST = false;
83
84
    /**
85
     * Default debug flag of REST client
86
     *
87
     * @const DEFAULT_DEBUG
88
     */
89
    protected const DEFAULT_DEBUG = false;
90
91
    // </editor-fold>
92
93
    // <editor-fold desc="Constants (document dividers)">
94
95
    /**
96
     * Document divider - none
97
     */
98
    public const DOCUMENT_DIVIDER_NONE = 1;
99
100
    /**
101
     * Document divider - new paragraph
102
     */
103
    public const DOCUMENT_DIVIDER_NEW_PARAGRAPH = 2;
104
105
    /**
106
     * Document divider - new section
107
     */
108
    public const DOCUMENT_DIVIDER_NEW_SECTION = 3;
109
110
    // </editor-fold>
111
112
    // <editor-fold desc="Constants (file formats)">
113
114
    /**
115
     * Image file formats
116
     */
117
    public const FILE_FORMATS_IMAGE
118
        = [
119
            'BMP',
120
            'GIF',
121
            'JPG',
122
            'PNG',
123
        ];
124
125
    /**
126
     * Template file formats
127
     */
128
    public const FILE_FORMATS_TEMPLATE
129
        = [
130
            'DOC',
131
            'DOCX',
132
            'RTF',
133
            'TX',
134
        ];
135
136
    /**
137
     * Document file formats
138
     */
139
    public const FILE_FORMATS_DOCUMENT
140
        = [
141
            'DOC',
142
            'DOCX',
143
            'HTML',
144
            'PDF',
145
            'RTF',
146
            'TX',
147
        ];
148
149
    /**
150
     * Return file formats
151
     */
152
    public const FILE_FORMATS_RETURN
153
        = [
154
            'DOC',
155
            'DOCX',
156
            'HTML',
157
            'PDF',
158
            'PDFA',
159
            'RTF',
160
            'TX',
161
        ];
162
163
    // </editor-fold>
164
165
    // <editor-fold desc="Properties">
166
167
    /**
168
     * Backend API key
169
     *
170
     * @var string|null
171
     */
172
    private $apiKey;
173
174
    /**
175
     * Backend username
176
     *
177
     * @var string|null
178
     */
179
    private $username;
180
181
    /**
182
     * Backend password
183
     *
184
     * @var string|null
185
     */
186
    private $password;
187
188
    /**
189
     * When true, API call does not count against quota
190
     * "TEST MODE" watermark is added to document
191
     *
192
     * @var bool|null
193
     */
194
    private $test;
195
196
    /**
197
     * Backend base URI
198
     *
199
     * @var string|null
200
     */
201
    private $baseUri;
202
203
    /**
204
     * Backend version string
205
     *
206
     * @var string|null
207
     */
208
    private $version;
209
210
    /**
211
     * Backend timeout in seconds
212
     *
213
     * @var int|null
214
     */
215
    private $timeout;
216
217
    /**
218
     * Debug flag of REST client
219
     *
220
     * @var bool|null
221
     */
222
    private $debug;
223
224
    /**
225
     * REST client to backend
226
     *
227
     * @var Client|null
228
     */
229
    private $client;
230
231
    // </editor-fold>
232
233
    // <editor-fold desc="Methods">
234
235
    /**
236
     * Return the API key
237
     *
238
     * @return string|null
239
     */
240 76
    public function getApiKey(): ?string
241
    {
242 76
        return $this->apiKey;
243
    }
244
245
    /**
246
     * Set the API key
247
     *
248
     * @param string $apiKey
249
     *
250
     * @return AbstractReportingCloud
251
     */
252 193
    public function setApiKey(string $apiKey): self
253
    {
254 193
        $this->apiKey = $apiKey;
255
256 193
        return $this;
257
    }
258
259
    /**
260
     * Return the username
261
     *
262
     * @return string|null
263
     */
264 15
    public function getUsername(): ?string
265
    {
266 15
        return $this->username;
267
    }
268
269
    /**
270
     * Set the username
271
     *
272
     * @param string $username
273
     *
274
     * @return AbstractReportingCloud
275
     */
276 12
    public function setUsername(string $username): self
277
    {
278 12
        $this->username = $username;
279
280 12
        return $this;
281
    }
282
283
    /**
284
     * Return the password
285
     *
286
     * @return string|null
287
     */
288 12
    public function getPassword(): ?string
289
    {
290 12
        return $this->password;
291
    }
292
293
    /**
294
     * Set the password
295
     *
296
     * @param string $password
297
     *
298
     * @return AbstractReportingCloud
299
     */
300 12
    public function setPassword(string $password): self
301
    {
302 12
        $this->password = $password;
303
304 12
        return $this;
305
    }
306
307
    /**
308
     * Return the base URI of the backend web service
309
     *
310
     * @return string|null
311
     */
312 85
    public function getBaseUri(): ?string
313
    {
314 85
        if (null === $this->baseUri) {
315 79
            $this->setBaseUri(self::DEFAULT_BASE_URI);
316
        }
317
318 85
        return $this->baseUri;
319
    }
320
321
    /**
322
     * Set the base URI of the backend web service
323
     *
324
     * @param string $baseUri
325
     *
326
     * @return AbstractReportingCloud
327
     */
328 85
    public function setBaseUri(string $baseUri): self
329
    {
330 85
        $this->baseUri = $baseUri;
331
332 85
        return $this;
333
    }
334
335
    /**
336
     * Get the timeout (in seconds) of the backend web service
337
     *
338
     * @return int|null
339
     */
340 82
    public function getTimeout(): ?int
341
    {
342 82
        if (null === $this->timeout) {
343 76
            $this->setTimeout(self::DEFAULT_TIMEOUT);
344
        }
345
346 82
        return $this->timeout;
347
    }
348
349
    /**
350
     * Set the timeout (in seconds) of the backend web service
351
     *
352
     * @param int $timeout
353
     *
354
     * @return AbstractReportingCloud
355
     */
356 82
    public function setTimeout(int $timeout): self
357
    {
358 82
        $this->timeout = $timeout;
359
360 82
        return $this;
361
    }
362
363
    /**
364
     * Return the debug flag
365
     *
366
     * @return bool|null
367
     */
368 82
    public function getDebug(): ?bool
369
    {
370 82
        if (null === $this->debug) {
371 76
            $this->setDebug(self::DEFAULT_DEBUG);
372
        }
373
374 82
        return $this->debug;
375
    }
376
377
    /**
378
     * Set the debug flag
379
     *
380
     * @param bool $debug Debug flag
381
     *
382
     * @return ReportingCloud
383
     */
384 82
    public function setDebug(bool $debug): self
385
    {
386 82
        $this->debug = $debug;
387
388 82
        return $this;
389
    }
390
391
    /**
392
     * Return the test flag
393
     *
394
     * @return bool|null
395
     */
396 73
    public function getTest(): ?bool
397
    {
398 73
        if (null === $this->test) {
399 67
            $this->setTest(self::DEFAULT_TEST);
400
        }
401
402 73
        return $this->test;
403
    }
404
405
    /**
406
     * Set the test flag
407
     *
408
     * @param bool $test
409
     *
410
     * @return AbstractReportingCloud
411
     */
412 73
    public function setTest(bool $test): self
413
    {
414 73
        $this->test = $test;
415
416 73
        return $this;
417
    }
418
419
    /**
420
     * Get the version string of the backend web service
421
     *
422
     * @return string|null
423
     */
424 79
    public function getVersion(): ?string
425
    {
426 79
        if (null === $this->version) {
427 73
            $this->version = self::DEFAULT_VERSION;
428
        }
429
430 79
        return $this->version;
431
    }
432
433
    /**
434
     * Set the version string of the backend web service
435
     *
436
     * @param string $version
437
     *
438
     * @return AbstractReportingCloud
439
     */
440 6
    public function setVersion(string $version): self
441
    {
442 6
        $this->version = $version;
443
444 6
        return $this;
445
    }
446
447
    /**
448
     * Return the REST client of the backend web service
449
     *
450
     * @return Client
451
     */
452 76
    public function getClient(): Client
453
    {
454 76
        if (!$this->client instanceof Client) {
455
456
            $headers = [
457 76
                'Authorization' => $this->getAuthorizationHeader()
458
            ];
459
460
            $options = [
461 73
                'base_uri'              => $this->getBaseUri(),
462 73
                RequestOptions::TIMEOUT => $this->getTimeout(),
463 73
                RequestOptions::DEBUG   => $this->getDebug(),
464 73
                RequestOptions::HEADERS => $headers,
465
            ];
466
467 73
            $client = new Client($options);
468
469 73
            $this->setClient($client);
470
        }
471
472 73
        return $this->client;
473
    }
474
475
    /**
476
     * Set the REST client of the backend web service
477
     *
478
     * @param Client $client
479
     *
480
     * @return AbstractReportingCloud
481
     */
482 73
    public function setClient(Client $client): self
483
    {
484 73
        $this->client = $client;
485
486 73
        return $this;
487
    }
488
489
    /**
490
     * Request the URI with options
491
     *
492
     * @param string $method  HTTP method
493
     * @param string $uri     URI
494
     * @param array  $options Options
495
     *
496
     * @return \GuzzleHttp\Psr7\Response
497
     * @throws \TxTextControl\ReportingCloud\Exception\RuntimeException
498
     */
499 70
    protected function request(string $method, string $uri, array $options): Response
500
    {
501 70
        $client = $this->getClient();
502
503
        try {
504 67
            if ($this->getTest()) {
505 3
                $options[RequestOptions::QUERY]['test'] = Filter::filterBooleanToString($this->getTest());
506
            }
507 67
            $response = $client->request($method, $uri, $options);
508 6
        } catch (GuzzleException $e) {
509 6
            $message = (string) $e->getMessage();
510 6
            $code    = (int) $e->getCode();
511 6
            throw new RuntimeException($message, $code);
512
        }
513
514 64
        return $response;
515
    }
516
517
    /**
518
     * Construct URI with version number
519
     *
520
     * @param string $uri URI
521
     *
522
     * @return string
523
     */
524 70
    protected function uri(string $uri): string
525
    {
526 70
        return sprintf('/%s%s', $this->getVersion(), $uri);
527
    }
528
529
    /**
530
     * Return Authorization Header, with either API key or username and password
531
     *
532
     * @return string
533
     * @throws \TxTextControl\ReportingCloud\Exception\InvalidArgumentException
534
     */
535 76
    private function getAuthorizationHeader(): string
536
    {
537 76
        if (!empty($this->getApiKey())) {
538 70
            return sprintf('ReportingCloud-APIKey %s', $this->getApiKey());
539
        }
540
541 6
        if (!empty($this->getUsername()) && !empty($this->getPassword())) {
542 3
            $value = sprintf('%s:%s', $this->getUsername(), $this->getPassword());
543 3
            return sprintf('Basic %s', base64_encode($value));
544
        }
545
546 3
        $message = 'Either the API key, or username and password must be set for authorization';
547 3
        throw new InvalidArgumentException($message);
548
    }
549
550
    // </editor-fold>
551
}
552