Protocol   A
last analyzed

Complexity

Total Complexity 32

Size/Duplication

Total Lines 261
Duplicated Lines 0 %

Importance

Changes 5
Bugs 1 Features 1
Metric Value
wmc 32
eloc 73
c 5
b 1
f 1
dl 0
loc 261
rs 9.84

16 Methods

Rating   Name   Duplication   Size   Complexity  
A getCertValidation() 0 2 1
A setProxy() 0 8 3
A getProxy() 0 2 1
A setCertValidation() 0 3 1
A disableCertValidation() 0 3 1
A enableUidCache() 0 2 1
A disableUidCache() 0 2 1
A getConnectionTimeout() 0 2 1
A defaultSocketOptions() 0 23 4
A enableCertValidation() 0 3 1
A createStream() 0 16 3
A buildUIDCommand() 0 2 1
A setUidCache() 0 14 3
A getCryptoMethod() 0 13 3
A getUIDKey() 0 9 5
A setConnectionTimeout() 0 5 2
1
<?php
2
/*
3
* File: ImapProtocol.php
4
* Category: Protocol
5
* Author: M.Goldenbaum
6
* Created: 16.09.20 18:27
7
* Updated: -
8
*
9
* Description:
10
*  -
11
*/
12
13
namespace Webklex\PHPIMAP\Connection\Protocols;
14
15
use Webklex\PHPIMAP\Exceptions\ConnectionFailedException;
16
use Webklex\PHPIMAP\IMAP;
17
18
/**
19
 * Class Protocol
20
 *
21
 * @package Webklex\PHPIMAP\Connection\Protocols
22
 */
23
abstract class Protocol implements ProtocolInterface {
24
25
    /**
26
     * Default connection timeout in seconds
27
     */
28
    protected $connection_timeout = 30;
29
30
    /**
31
     * @var boolean
32
     */
33
    protected $debug = false;
34
35
    /**
36
     * @var boolean
37
     */
38
    protected $enable_uid_cache = true;
39
40
    /**
41
     * @var false|\IMAP\Connection|resource
0 ignored issues
show
Bug introduced by
The type IMAP\Connection was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
42
     */
43
    public $stream = false;
44
45
    /**
46
     * Connection encryption method
47
     * @var mixed $encryption
48
     */
49
    protected $encryption = false;
50
51
    /**
52
     * Set to false to ignore SSL certificate validation
53
     * @var bool
54
     */
55
    protected $cert_validation = true;
56
57
    /**
58
     * Proxy settings
59
     * @var array
60
     */
61
    protected $proxy = [
62
        'socket' => null,
63
        'request_fulluri' => false,
64
        'username' => null,
65
        'password' => null,
66
    ];
67
68
    /**
69
     * Cache for uid of active folder.
70
     *
71
     * @var null|array
72
     */
73
    protected $uid_cache = null;
74
75
    /**
76
     * Get an available cryptographic method
77
     *
78
     * @return int
79
     */
80
    public function getCryptoMethod() {
81
        // Allow the best TLS version(s) we can
82
        $cryptoMethod = STREAM_CRYPTO_METHOD_TLS_CLIENT;
83
84
        // PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT
85
        // so add them back in manually if we can
86
        if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
87
            $cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
88
        }elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
89
            $cryptoMethod = STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
90
        }
91
92
        return $cryptoMethod;
93
    }
94
95
    /**
96
     * Enable SSL certificate validation
97
     *
98
     * @return $this
99
     */
100
    public function enableCertValidation() {
101
        $this->cert_validation = true;
102
        return $this;
103
    }
104
105
    /**
106
     * Disable SSL certificate validation
107
     * @return $this
108
     */
109
    public function disableCertValidation() {
110
        $this->cert_validation = false;
111
        return $this;
112
    }
113
114
    /**
115
     * Set SSL certificate validation
116
     * @var int $cert_validation
117
     *
118
     * @return $this
119
     */
120
    public function setCertValidation($cert_validation) {
121
        $this->cert_validation = $cert_validation;
0 ignored issues
show
Documentation Bug introduced by
The property $cert_validation was declared of type boolean, but $cert_validation is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
122
        return $this;
123
    }
124
125
    /**
126
     * Should we validate SSL certificate?
127
     *
128
     * @return bool
129
     */
130
    public function getCertValidation() {
131
        return $this->cert_validation;
132
    }
133
134
    /**
135
     * Set connection proxy settings
136
     * @var array $options
137
     *
138
     * @return $this
139
     */
140
    public function setProxy($options) {
141
        foreach ($this->proxy as $key => $val) {
142
            if (isset($options[$key])) {
143
                $this->proxy[$key] = $options[$key];
144
            }
145
        }
146
147
        return $this;
148
    }
149
150
    /**
151
     * Get the current proxy settings
152
     *
153
     * @return array
154
     */
155
    public function getProxy() {
156
        return $this->proxy;
157
    }
158
159
    /**
160
     * Prepare socket options
161
     * @var string $transport
162
     *
163
     * @return array
164
     */
165
    private function defaultSocketOptions($transport) {
166
        $options = [];
167
        if ($this->encryption != false) {
168
            $options["ssl"] = [
169
                'verify_peer_name' => $this->getCertValidation(),
170
                'verify_peer'      => $this->getCertValidation(),
171
            ];
172
        }
173
174
        if ($this->proxy["socket"] != null) {
175
            $options[$transport]["proxy"] = $this->proxy["socket"];
176
            $options[$transport]["request_fulluri"] = $this->proxy["request_fulluri"];
177
178
            if ($this->proxy["username"] != null) {
179
                $auth = base64_encode($this->proxy["username"].':'.$this->proxy["password"]);
180
181
                $options[$transport]["header"] = [
182
                    "Proxy-Authorization: Basic $auth"
183
                ];
184
            }
185
        }
186
187
        return $options;
188
    }
189
190
    /**
191
     * Create a new resource stream
192
     * @param $transport
193
     * @param string $host hostname or IP address of IMAP server
194
     * @param int $port of IMAP server, default is 143 (993 for ssl)
195
     * @param int $timeout timeout in seconds for initiating session
196
     *
197
     * @return resource|boolean The socket created.
198
     * @throws ConnectionFailedException
199
     */
200
    protected function createStream($transport, $host, $port, $timeout) {
201
        $socket = "$transport://$host:$port";
202
        $stream = stream_socket_client($socket, $errno, $errstr, $timeout,
203
            STREAM_CLIENT_CONNECT,
204
            stream_context_create($this->defaultSocketOptions($transport))
205
        );
206
207
        if (!$stream) {
0 ignored issues
show
introduced by
$stream is of type resource, thus it always evaluated to false.
Loading history...
208
            throw new ConnectionFailedException($errstr, $errno);
209
        }
210
211
        if (false === stream_set_timeout($stream, $timeout)) {
212
            throw new ConnectionFailedException('Failed to set stream timeout');
213
        }
214
215
        return $stream;
216
    }
217
218
    /**
219
     * @return int
220
     */
221
    public function getConnectionTimeout() {
222
        return $this->connection_timeout;
223
    }
224
225
    /**
226
     * @param int $connection_timeout
227
     * @return Protocol
228
     */
229
    public function setConnectionTimeout($connection_timeout) {
230
        if ($connection_timeout !== null) {
0 ignored issues
show
introduced by
The condition $connection_timeout !== null is always true.
Loading history...
231
            $this->connection_timeout = $connection_timeout;
232
        }
233
        return $this;
234
    }
235
236
    /**
237
     * Get the UID key string
238
     * @param int|string $uid
239
     *
240
     * @return string
241
     */
242
    public function getUIDKey($uid) {
243
        if ($uid == IMAP::ST_UID || $uid == IMAP::FT_UID) {
244
            return "UID";
245
        }
246
        if (strlen($uid) > 0 && !is_numeric($uid)) {
247
            return (string)$uid;
248
        }
249
250
        return "";
251
    }
252
253
    public function buildUIDCommand($command, $uid) {
254
        return trim($this->getUIDKey($uid)." ".$command);
255
    }
256
257
    /**
258
     * Set the uid cache of current active folder
259
     *
260
     * @param array|null $uids
261
     */
262
    public function setUidCache($uids) {
263
        if (is_null($uids)) {
264
            $this->uid_cache = null;
265
            return;
266
        }
267
268
        $messageNumber = 1;
269
270
        $uid_cache = [];
271
        foreach ($uids as $uid) {
272
            $uid_cache[$messageNumber++] = $uid;
273
        }
274
275
        $this->uid_cache = $uid_cache;
276
    }
277
278
    public function enableUidCache() {
279
        $this->enable_uid_cache = true;
280
    }
281
282
    public function disableUidCache() {
283
        $this->enable_uid_cache = false;
284
    }
285
}
286