Passed
Pull Request — master (#77)
by Yuichi
04:41 queued 02:24
created

Config   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 236
Duplicated Lines 0 %

Test Coverage

Coverage 78.82%

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 89
c 4
b 0
f 0
dl 0
loc 236
ccs 67
cts 85
cp 0.7882
rs 9.6
wmc 35

15 Methods

Rating   Name   Duplication   Size   Complexity  
A hasRequired() 0 11 5
A getConfig() 0 3 1
A getBaseUri() 0 14 3
A hasRequiredOnCert() 0 3 1
A hasRequiredOnAuth() 0 7 3
A toGuzzleConfig() 0 19 4
A __construct() 0 13 2
A configureBasicAuth() 0 4 2
A hasKeysByUse() 0 13 4
A getBasicAuthOptions() 0 9 2
A hasRequiredOnBasicAuth() 0 3 1
A configureAuth() 0 7 2
A getCertOptions() 0 9 2
A get() 0 3 1
A configureCert() 0 7 2
1
<?php
2
3
namespace CybozuHttp;
4
5
use CybozuHttp\Exception\NotExistRequiredException;
6
use CybozuHttp\Middleware\FinishMiddleware;
7
use GuzzleHttp\HandlerStack;
8
9
/**
10
 * @author ochi51 <[email protected]>
11
 */
12
class Config
13
{
14
15
    /**
16
     * @var array $config
17
     */
18
    private $config;
19
20
    /**
21
     * @var array $default
22
     */
23
    private static $default = [
24
        'domain' => 'cybozu.com',
25
        'use_api_token' => false,
26
        'use_basic' => false,
27
        'use_client_cert' => false,
28
        'base_uri' => null,
29
        'concurrency' => 1,
30
        'response_middleware' => true,
31
        'debug' => false
32
    ];
33
34
    /**
35
     * @var array $required
36
     */
37
    private static $required = [
38
        'handler',
39
        'domain',
40
        'subdomain',
41
        'use_api_token',
42
        'use_basic',
43
        'use_client_cert',
44
        'base_uri',
45
        'debug'
46
    ];
47
48
    /**
49
     * Config constructor.
50
     * @param array $config
51
     */
52 1
    public function __construct(array $config)
53
    {
54 1
        $this->config = array_merge(self::$default, $config);
55
56 1
        $this->config['base_uri'] = $this->getBaseUri();
57 1
        $this->config['handler'] = $handler = $config['handler'] ?? HandlerStack::create();
58
59 1
        $this->configureAuth();
60 1
        $this->configureBasicAuth();
61 1
        $this->configureCert();
62
63 1
        if ($this->config['response_middleware']) {
64 1
            $handler->before('http_errors', new FinishMiddleware(), 'cybozu_http.finish');
65
        }
66
    }
67
68
69 1
    private function configureAuth(): void
70
    {
71 1
        if ($this->get('use_api_token')) {
72
            $this->config['headers']['X-Cybozu-API-Token'] = $this->get('token');
73
        } else {
74 1
            $this->config['headers']['X-Cybozu-Authorization'] =
75 1
                base64_encode($this->get('login') . ':' . $this->get('password'));
76
        }
77
    }
78
79 1
    private function configureBasicAuth(): void
80
    {
81 1
        if ($this->get('use_basic')) {
82 1
            $this->config['auth'] = $this->getBasicAuthOptions();
83
        }
84
    }
85
86 1
    private function configureCert(): void
87
    {
88 1
        if ($this->get('use_client_cert')) {
89
            $this->config['verify'] = true;
90
            $this->config['cert'] = $this->getCertOptions();
91
        } else {
92 1
            $this->config['verify'] = false;
93
        }
94
    }
95
96
    /**
97
     * @return array
98
     * @throws NotExistRequiredException
99
     */
100 1
    private function getBasicAuthOptions(): array
101
    {
102 1
        if ($this->hasRequiredOnBasicAuth()) {
103 1
            return [
104 1
                $this->get('basic_login'),
105 1
                $this->get('basic_password')
106 1
            ];
107
        }
108
        throw new NotExistRequiredException('kintone.empty_basic_password');
109
    }
110
111
    /**
112
     * @return array
113
     * @throws NotExistRequiredException
114
     */
115
    private function getCertOptions(): array
116
    {
117
        if ($this->hasRequiredOnCert()) {
118
            return [
119
                $this->get('cert_file'),
120
                $this->get('cert_password')
121
            ];
122
        }
123
        throw new NotExistRequiredException('kintone.empty_cert');
124
    }
125
126
    /**
127
     * @return array
128
     */
129 1
    public function toGuzzleConfig(): array
130
    {
131 1
        $config = [
132 1
            'handler' => $this->get('handler'),
133 1
            'base_uri' => $this->get('base_uri'),
134 1
            'headers' => $this->get('headers'),
135 1
            'debug' => $this->get('debug') ? fopen($this->get('logfile'), 'ab') : false,
0 ignored issues
show
Bug introduced by
It seems like $this->get('logfile') can also be of type boolean; however, parameter $filename of fopen() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

135
            'debug' => $this->get('debug') ? fopen(/** @scrutinizer ignore-type */ $this->get('logfile'), 'ab') : false,
Loading history...
136 1
            'concurrency' => $this->get('concurrency'),
137 1
            'timeout' => $this->get('timeout')
138 1
        ];
139 1
        if ($this->get('auth')) {
140 1
            $config['auth'] = $this->get('auth');
141
        }
142 1
        $config['verify'] = $this->get('verify');
143 1
        if ($this->get('cert')) {
144
            $config['cert'] = $this->get('cert');
145
        }
146
147 1
        return $config;
148
    }
149
150
    /**
151
     * @param $key
152
     * @return string|bool
153
     */
154 1
    public function get($key)
155
    {
156 1
        return $this->config[$key] ?? false;
157
    }
158
159
    /**
160
     * @return array
161
     */
162
    public function getConfig(): array
163
    {
164
        return $this->config;
165
    }
166
167
    /**
168
     * @return bool
169
     */
170 1
    public function hasRequired(): bool
171
    {
172 1
        foreach (self::$required as $r) {
173 1
            if (!array_key_exists($r, $this->config)) {
174
                return false;
175
            }
176
        }
177
178 1
        return $this->hasRequiredOnAuth()
179 1
                && $this->hasRequiredOnBasicAuth()
180 1
                && $this->hasRequiredOnCert();
181
    }
182
183
    /**
184
     * @return bool
185
     */
186 1
    private function hasRequiredOnAuth(): bool
187
    {
188 1
        if ($this->get('use_api_token')) {
189
            return !empty($this->get('token'));
190
        }
191
192 1
        return $this->get('login') && $this->get('password');
193
    }
194
195
    /**
196
     * @return bool
197
     */
198 1
    private function hasRequiredOnBasicAuth(): bool
199
    {
200 1
        return $this->hasKeysByUse('use_basic', ['basic_login', 'basic_password']);
201
    }
202
203
    /**
204
     * @return bool
205
     */
206 1
    private function hasRequiredOnCert(): bool
207
    {
208 1
        return $this->hasKeysByUse('use_client_cert', ['cert_file', 'cert_password']);
209
    }
210
211
    /**
212
     * @param string $use
213
     * @param string[] $keys
214
     * @return bool
215
     */
216 1
    private function hasKeysByUse($use, array $keys): bool
217
    {
218 1
        if (!$this->get($use)) {
219 1
            return true;
220
        }
221
222 1
        foreach ($keys as $key) {
223 1
            if (!$this->get($key)) {
224
                return false;
225
            }
226
        }
227
228 1
        return true;
229
    }
230
231
    /**
232
     * @return string
233
     */
234 1
    public function getBaseUri(): string
235
    {
236 1
        $subdomain = $this->get('subdomain');
237 1
        $uri = 'https://'. $subdomain;
238
239 1
        if (strpos($subdomain, '.') === false) {
0 ignored issues
show
Bug introduced by
It seems like $subdomain can also be of type boolean; however, parameter $haystack of strpos() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

239
        if (strpos(/** @scrutinizer ignore-type */ $subdomain, '.') === false) {
Loading history...
240 1
            if ($this->get('use_client_cert')) {
241
                $uri .= '.s';
242
            }
243
244 1
            $uri .= '.'. $this->get('domain');
245
        }
246
247 1
        return $uri;
248
    }
249
}
250