Passed
Pull Request — 1.x (#58)
by
unknown
01:46
created

DigiSign   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 211
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 36
eloc 67
c 1
b 0
f 0
dl 0
loc 211
rs 9.52

23 Methods

Rating   Name   Duplication   Size   Complexity  
A setCache() 0 10 2
A envelopes() 0 3 1
A my() 0 3 1
A createBearer() 0 3 1
A request() 0 10 2
A setClient() 0 3 1
A files() 0 3 1
A getCredentials() 0 10 2
A useTesting() 0 6 2
A removeVersion() 0 3 1
A contacts() 0 3 1
A account() 0 3 1
A enums() 0 3 1
A webhooks() 0 3 1
B __construct() 0 35 8
A auth() 0 3 1
A images() 0 3 1
A deliveries() 0 3 1
A createUserAgent() 0 11 3
A setApiBase() 0 3 1
A envelopeTemplates() 0 3 1
A setCredentials() 0 3 1
A addVersion() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DigitalCz\DigiSign;
6
7
use DigitalCz\DigiSign\Auth\ApiKeyCredentials;
8
use DigitalCz\DigiSign\Auth\CachedCredentials;
9
use DigitalCz\DigiSign\Auth\Credentials;
10
use DigitalCz\DigiSign\Endpoint\AccountEndpoint;
11
use DigitalCz\DigiSign\Endpoint\AuthEndpoint;
12
use DigitalCz\DigiSign\Endpoint\ContactsEndpoint;
13
use DigitalCz\DigiSign\Endpoint\DeliveriesEndpoint;
14
use DigitalCz\DigiSign\Endpoint\EndpointInterface;
15
use DigitalCz\DigiSign\Endpoint\EnumsEndpoint;
16
use DigitalCz\DigiSign\Endpoint\EnvelopesEndpoint;
17
use DigitalCz\DigiSign\Endpoint\EnvelopeTemplatesEndpoint;
18
use DigitalCz\DigiSign\Endpoint\FilesEndpoint;
19
use DigitalCz\DigiSign\Endpoint\ImagesEndpoint;
20
use DigitalCz\DigiSign\Endpoint\MyEndpoint;
21
use DigitalCz\DigiSign\Endpoint\WebhooksEndpoint;
22
use InvalidArgumentException;
23
use LogicException;
24
use Psr\Http\Message\ResponseInterface;
25
use Psr\SimpleCache\CacheInterface;
26
27
final class DigiSign implements EndpointInterface
28
{
29
    public const VERSION = '1.2.0';
30
    public const API_BASE = 'https://api.digisign.org';
31
    public const API_BASE_TESTING = 'https://api.digisign.digital.cz';
32
33
    /** @var string The base URL for requests */
34
    private $apiBase = self::API_BASE;
35
36
    /** @var Credentials The credentials used to authenticate to API */
37
    private $credentials;
38
39
    /** @var DigiSignClient The client used to send requests */
40
    private $client;
41
42
    /** @var array<string, string> */
43
    private $versions = [];
44
45
    /**
46
     * Available options:
47
     *  access_key      - string; ApiKey access key
48
     *  secret_key      - string; ApiKey secret key
49
     *  credentials     - DigitalCz\DigiSign\Auth\Credentials instance
50
     *  client          - DigitalCz\DigiSign\DigiSignClient instance with your custom PSR17/18 objects
51
     *  http_client     - Psr\Http\Client\ClientInterface instance of your custom PSR18 client
52
     *  cache           - Psr\SimpleCache\CacheInterface for caching Credentials auth Tokens
53
     *  testing         - bool; whether to use testing or production API
54
     *  api_base        - string; override the base API url
55
     *
56
     * @param mixed[] $options
57
     */
58
    public function __construct(array $options = [])
59
    {
60
        $httpClient = $options['http_client'] ?? null;
61
        $this->setClient($options['client'] ?? new DigiSignClient($httpClient));
62
        $this->useTesting($options['testing'] ?? false);
63
        $this->addVersion('digitalcz/digisign', self::VERSION);
64
        $this->addVersion('PHP', PHP_VERSION);
65
66
        if (isset($options['api_base'])) {
67
            if (!is_string($options['api_base'])) {
68
                throw new InvalidArgumentException('Invalid value for "api_base" option');
69
            }
70
71
            $this->setApiBase($options['api_base']);
72
        }
73
74
        if (isset($options['access_key'], $options['secret_key'])) {
75
            $this->setCredentials(new ApiKeyCredentials($options['access_key'], $options['secret_key']));
76
        }
77
78
        if (isset($options['credentials'])) {
79
            if (!$options['credentials'] instanceof Credentials) {
80
                throw new InvalidArgumentException('Invalid value for "credentials" option');
81
            }
82
83
            $this->setCredentials($options['credentials']);
84
        }
85
86
        // if cache is provided, wrap Credentials with cache decorator
87
        if (isset($options['cache'])) {
88
            if (!$options['cache'] instanceof CacheInterface) {
89
                throw new InvalidArgumentException('Invalid value for "cache" option');
90
            }
91
92
            $this->setCache($options['cache']);
93
        }
94
    }
95
96
    public function setCache(CacheInterface $cache): void
97
    {
98
        $credentials = $this->getCredentials();
99
100
        // if credentials are already decorated, do not double wrap, but get inner
101
        if ($credentials instanceof CachedCredentials) {
102
            $credentials = $credentials->getInner();
103
        }
104
105
        $this->setCredentials(new CachedCredentials($credentials, $cache));
106
    }
107
108
    public function getCredentials(): Credentials
109
    {
110
        if (!isset($this->credentials)) {
111
            throw new LogicException(
112
                'No credentials were provided, Please use setCredentials() ' .
113
                'or constructor options to set them.'
114
            );
115
        }
116
117
        return $this->credentials;
118
    }
119
120
    public function setCredentials(Credentials $credentials): void
121
    {
122
        $this->credentials = $credentials;
123
    }
124
125
    public function setClient(DigiSignClient $client): void
126
    {
127
        $this->client = $client;
128
    }
129
130
    public function useTesting(bool $bool = true): void
131
    {
132
        if ($bool) {
133
            $this->setApiBase(self::API_BASE_TESTING);
134
        } else {
135
            $this->setApiBase(self::API_BASE);
136
        }
137
    }
138
139
    public function setApiBase(string $apiBase): void
140
    {
141
        $this->apiBase = rtrim(trim($apiBase), '/');
142
    }
143
144
    public function addVersion(string $tool, string $version = ''): void
145
    {
146
        $this->versions[$tool] = $version;
147
    }
148
149
    public function removeVersion(string $tool): void
150
    {
151
        unset($this->versions[$tool]);
152
    }
153
154
    /** @inheritDoc */
155
    public function request(string $method, string $path = '', array $options = []): ResponseInterface
156
    {
157
        $options['user-agent'] = $this->createUserAgent();
158
159
        // disable authorization header if options[no_auth]=true
160
        if (($options['no_auth'] ?? false) !== true) {
161
            $options['auth_bearer'] = $options['auth_bearer'] ?? $this->createBearer();
162
        }
163
164
        return $this->client->request($method, $this->apiBase . $path, $options);
165
    }
166
167
    public function auth(): AuthEndpoint
168
    {
169
        return new AuthEndpoint($this);
170
    }
171
172
    public function account(): AccountEndpoint
173
    {
174
        return new AccountEndpoint($this);
175
    }
176
177
    public function contacts(): ContactsEndpoint
178
    {
179
        return new ContactsEndpoint($this);
180
    }
181
182
    public function envelopes(): EnvelopesEndpoint
183
    {
184
        return new EnvelopesEndpoint($this);
185
    }
186
187
    public function envelopeTemplates(): EnvelopeTemplatesEndpoint
188
    {
189
        return new EnvelopeTemplatesEndpoint($this);
190
    }
191
192
    public function deliveries(): DeliveriesEndpoint
193
    {
194
        return new DeliveriesEndpoint($this);
195
    }
196
197
    public function files(): FilesEndpoint
198
    {
199
        return new FilesEndpoint($this);
200
    }
201
202
    public function images(): ImagesEndpoint
203
    {
204
        return new ImagesEndpoint($this);
205
    }
206
207
    public function webhooks(): WebhooksEndpoint
208
    {
209
        return new WebhooksEndpoint($this);
210
    }
211
212
    public function enums(): EnumsEndpoint
213
    {
214
        return new EnumsEndpoint($this);
215
    }
216
217
    public function my(): MyEndpoint
218
    {
219
        return new MyEndpoint($this);
220
    }
221
222
    private function createUserAgent(): string
223
    {
224
        $userAgent = '';
225
226
        foreach ($this->versions as $tool => $version) {
227
            $userAgent .= $tool;
228
            $userAgent .= $version !== '' ? ":$version" : '';
229
            $userAgent .= ' ';
230
        }
231
232
        return $userAgent;
233
    }
234
235
    private function createBearer(): string
236
    {
237
        return $this->getCredentials()->provide($this)->getToken();
238
    }
239
}
240