Passed
Pull Request — 1.x (#54)
by Pavel
02:32
created

DigiSign::my()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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