Issues (144)

src/Connection/Protocols/LegacyProtocol.php (26 issues)

1
<?php
2
/*
3
* File: LegacyProtocol.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\ClientManager;
16
use Webklex\PHPIMAP\Exceptions\AuthFailedException;
17
use Webklex\PHPIMAP\Exceptions\MethodNotSupportedException;
18
use Webklex\PHPIMAP\Exceptions\RuntimeException;
19
use Webklex\PHPIMAP\IMAP;
20
21
/**
22
 * Class LegacyProtocol
23
 *
24
 * @package Webklex\PHPIMAP\Connection\Protocols
25
 */
26
class LegacyProtocol extends Protocol {
27
28
    protected $protocol = "imap";
29
    protected $host = null;
30
    protected $port = null;
31
    protected $encryption = null;
32
33
    /**
34
     * Imap constructor.
35
     * @param bool $cert_validation set to false to skip SSL certificate validation
36
     * @param mixed $encryption Connection encryption method
37
     */
38
    public function __construct(bool $cert_validation = true, $encryption = false) {
39
        $this->setCertValidation($cert_validation);
40
        $this->encryption = $encryption;
41
    }
42
43
    /**
44
     * Public destructor
45
     */
46
    public function __destruct() {
47
        $this->logout();
48
    }
49
50
    /**
51
     * Save the information for a nw connection
52
     * @param string $host
53
     * @param null $port
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $port is correct as it would always require null to be passed?
Loading history...
54
     */
55
    public function connect(string $host, $port = null) {
56
        if ($this->encryption) {
57
            $encryption = strtolower($this->encryption);
0 ignored issues
show
It seems like $this->encryption can also be of type true; however, parameter $string of strtolower() 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

57
            $encryption = strtolower(/** @scrutinizer ignore-type */ $this->encryption);
Loading history...
58
            if ($encryption == "ssl") {
59
                $port = $port === null ? 993 : $port;
0 ignored issues
show
The condition $port === null is always true.
Loading history...
60
            }
61
        }
62
        $port = $port === null ? 143 : $port;
63
        $this->host = $host;
64
        $this->port = $port;
65
    }
66
67
    /**
68
     * Login to a new session.
69
     * @param string $user username
70
     * @param string $password password
71
     *
72
     * @return bool
73
     * @throws AuthFailedException
74
     * @throws RuntimeException
75
     */
76
    public function login(string $user, string $password): bool {
77
        try {
78
            $this->stream = \imap_open(
79
                $this->getAddress(),
80
                $user,
81
                $password,
82
                0,
83
                $attempts = 3,
84
                ClientManager::get('options.open')
85
            );
86
        } catch (\ErrorException $e) {
87
            $errors = \imap_errors();
88
            $message = $e->getMessage().'. '.implode("; ", (is_array($errors) ? $errors : array()));
0 ignored issues
show
The condition is_array($errors) is always true.
Loading history...
89
            throw new AuthFailedException($message);
90
        }
91
92
        if(!$this->stream) {
93
            $errors = \imap_errors();
94
            $message = implode("; ", (is_array($errors) ? $errors : array()));
0 ignored issues
show
The condition is_array($errors) is always true.
Loading history...
95
            throw new AuthFailedException($message);
96
        }
97
98
        $errors = \imap_errors();
99
        if(is_array($errors)) {
0 ignored issues
show
The condition is_array($errors) is always true.
Loading history...
100
            $status = $this->examineFolder();
101
            if($status['exists'] !== 0) {
102
                $message = implode("; ", (is_array($errors) ? $errors : array()));
0 ignored issues
show
The condition is_array($errors) is always true.
Loading history...
103
                throw new RuntimeException($message);
104
            }
105
        }
106
107
        return $this->stream !== false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->stream !== false returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...tocolInterface::login() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
108
    }
109
110
    /**
111
     * Authenticate your current session.
112
     * @param string $user username
113
     * @param string $token access token
114
     *
115
     * @return bool|resource
116
     * @throws AuthFailedException|RuntimeException
117
     */
118
    public function authenticate(string $user, string $token): bool {
119
        return $this->login($user, $token);
120
    }
121
122
    /**
123
     * Get full address of mailbox.
124
     *
125
     * @return string
126
     */
127
    protected function getAddress(): string {
128
        $address = "{".$this->host.":".$this->port."/".$this->protocol;
129
        if (!$this->cert_validation) {
130
            $address .= '/novalidate-cert';
131
        }
132
        if (in_array($this->encryption,['tls', 'notls', 'ssl'])) {
133
            $address .= '/'.$this->encryption;
134
        } elseif ($this->encryption === "starttls") {
135
            $address .= '/tls';
136
        }
137
138
        $address .= '}';
139
140
        return $address;
141
    }
142
143
    /**
144
     * Logout of the current session
145
     *
146
     * @return bool success
147
     */
148
    public function logout(): bool {
149
        if ($this->stream) {
150
            $result = \imap_close($this->stream, IMAP::CL_EXPUNGE);
151
            $this->stream = false;
152
            $this->uid_cache = null;
153
            return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...ocolInterface::logout() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
154
        }
155
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...ocolInterface::logout() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
156
    }
157
158
    /**
159
     * Check if the current session is connected
160
     *
161
     * @return bool
162
     */
163
    public function connected(): bool {
164
        return boolval($this->stream);
165
    }
166
167
    /**
168
     * Get an array of available capabilities
169
     *
170
     * @throws MethodNotSupportedException
171
     */
172
    public function getCapabilities(): array {
173
        throw new MethodNotSupportedException();
174
    }
175
176
    /**
177
     * Change the current folder
178
     * @param string $folder change to this folder
179
     *
180
     * @return bool|array see examineOrselect()
181
     * @throws RuntimeException
182
     */
183
    public function selectFolder(string $folder = 'INBOX') {
184
        $flags = IMAP::OP_READONLY;
185
        if (in_array($this->protocol, ["pop3", "nntp"])) {
186
            $flags = IMAP::NIL;
187
        }
188
        if ($this->stream === false) {
189
            throw new RuntimeException("failed to reopen stream.");
190
        }
191
192
        \imap_reopen($this->stream, $this->getAddress().$folder, $flags, 3);
193
        $this->uid_cache = null;
194
        return $this->examineFolder($folder);
195
    }
196
197
    /**
198
     * Examine a given folder
199
     * @param string $folder examine this folder
200
     *
201
     * @return bool|array
202
     * @throws RuntimeException
203
     */
204
    public function examineFolder(string $folder = 'INBOX') {
205
        if (strpos($folder, ".") === 0) {
206
            throw new RuntimeException("Segmentation fault prevented. Folders starts with an illegal char '.'.");
207
        }
208
        $folder = $this->getAddress().$folder;
209
        $status = \imap_status($this->stream, $folder, IMAP::SA_ALL);
210
        return [
211
            "flags" => [],
212
            "exists" => $status->messages,
213
            "recent" => $status->recent,
214
            "unseen" => $status->unseen,
215
            "uidnext" => $status->uidnext,
216
        ];
217
    }
218
219
    /**
220
     * Fetch message content
221
     * @param array|int $uids
222
     * @param string $rfc
223
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
224
     *
225
     * @return array
226
     */
227
    public function content($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array {
228
        $result = [];
229
        $uids = is_array($uids) ? $uids : [$uids];
230
        foreach ($uids as $id) {
231
            $result[$id] = \imap_fetchbody($this->stream, $id, "", $uid ? IMAP::ST_UID : IMAP::NIL);
232
        }
233
        return $result;
234
    }
235
236
    /**
237
     * Fetch message headers
238
     * @param array|int $uids
239
     * @param string $rfc
240
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
241
     *
242
     * @return array
243
     */
244
    public function headers($uids, string $rfc = "RFC822", $uid = IMAP::ST_UID): array {
245
        $result = [];
246
        $uids = is_array($uids) ? $uids : [$uids];
247
        foreach ($uids as $id) {
248
            $result[$id] = \imap_fetchheader($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL);
249
        }
250
        return $result;
251
    }
252
253
    /**
254
     * Fetch message flags
255
     * @param array|int $uids
256
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
257
     *
258
     * @return array
259
     */
260
    public function flags($uids, $uid = IMAP::ST_UID): array {
261
        $result = [];
262
        $uids = is_array($uids) ? $uids : [$uids];
263
        foreach ($uids as $id) {
264
            $raw_flags = \imap_fetch_overview($this->stream, $id, $uid ? IMAP::ST_UID : IMAP::NIL);
265
            $flags = [];
266
            if (is_array($raw_flags) && isset($raw_flags[0])) {
267
                $raw_flags = (array) $raw_flags[0];
268
                foreach($raw_flags as $flag => $value) {
269
                    if ($value === 1 && in_array($flag, ["size", "uid", "msgno", "update"]) === false){
270
                        $flags[] = "\\".ucfirst($flag);
271
                    }
272
                }
273
            }
274
            $result[$uid] = $flags;
275
        }
276
277
        return $result;
278
    }
279
280
    /**
281
     * Get uid for a given id
282
     * @param int|null $id message number
283
     *
284
     * @return array|string message number for given message or all messages as array
285
     */
286
    public function getUid($id = null) {
287
        if ($id === null) {
288
            if ($this->enable_uid_cache && $this->uid_cache) {
289
                return $this->uid_cache;
290
            }
291
292
            $overview = $this->overview("1:*");
293
            $uids = [];
294
            foreach($overview as $set){
295
                $uids[$set->msgno] = $set->uid;
296
            }
297
298
            $this->setUidCache($uids);
299
            return $uids;
300
        }
301
302
        return \imap_uid($this->stream, $id);
303
    }
304
305
    /**
306
     * Get a message number for a uid
307
     * @param string $id uid
308
     *
309
     * @return int message number
310
     */
311
    public function getMessageNumber(string $id): int {
312
        return \imap_msgno($this->stream, $id);
313
    }
314
315
    /**
316
     * Get a message overview
317
     * @param string $sequence uid sequence
318
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
319
     *
320
     * @return array
321
     */
322
    public function overview(string $sequence, $uid = IMAP::ST_UID): array {
323
        return \imap_fetch_overview($this->stream, $sequence,$uid ? IMAP::ST_UID : IMAP::NIL);
324
    }
325
326
    /**
327
     * Get a list of available folders
328
     * @param string $reference mailbox reference for list
329
     * @param string $folder mailbox name match with wildcards
330
     *
331
     * @return array folders that matched $folder as array(name => array('delimiter' => .., 'flags' => ..))
332
     * @throws RuntimeException
333
     */
334
    public function folders(string $reference = '', string $folder = '*'): array {
335
        $result = [];
336
337
        $items = \imap_getmailboxes($this->stream, $this->getAddress(), $reference.$folder);
338
        if(is_array($items)){
0 ignored issues
show
The condition is_array($items) is always true.
Loading history...
339
            foreach ($items as $item) {
340
                $name = $this->decodeFolderName($item->name);
341
                $result[$name] = ['delimiter' => $item->delimiter, 'flags' => []];
342
            }
343
        }else{
344
            throw new RuntimeException(\imap_last_error());
345
        }
346
347
        return $result;
348
    }
349
350
    /**
351
     * Manage flags
352
     * @param array $flags flags to set, add or remove - see $mode
353
     * @param int $from message for items or start message if $to !== null
354
     * @param int|null $to if null only one message ($from) is fetched, else it's the
355
     *                             last message, INF means last message available
356
     * @param string|null $mode '+' to add flags, '-' to remove flags, everything else sets the flags as given
357
     * @param bool $silent if false the return values are the new flags for the wanted messages
358
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
359
     * @param null $item unused attribute
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $item is correct as it would always require null to be passed?
Loading history...
360
     *
361
     * @return bool|array new flags if $silent is false, else true or false depending on success
362
     */
363
    public function store(array $flags, int $from, $to = null, $mode = null, bool $silent = true, $uid = IMAP::ST_UID, $item = null) {
364
        $flag = trim(is_array($flags) ? implode(" ", $flags) : $flags);
0 ignored issues
show
The condition is_array($flags) is always true.
Loading history...
365
366
        if ($mode == "+"){
367
            $status = \imap_setflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL);
368
        }else{
369
            $status = \imap_clearflag_full($this->stream, $from, $flag, $uid ? IMAP::ST_UID : IMAP::NIL);
370
        }
371
372
        if ($silent === true) {
373
            return $status;
374
        }
375
376
        return $this->flags($from);
377
    }
378
379
    /**
380
     * Append a new message to given folder
381
     * @param string $folder name of target folder
382
     * @param string $message full message content
383
     * @param array|null $flags flags for new message
384
     * @param string $date date for new message
385
     *
386
     * @return bool success
387
     */
388
    public function appendMessage(string $folder, string $message, $flags = null, $date = null): bool {
389
        if ($date != null) {
0 ignored issues
show
It seems like you are loosely comparing $date of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
390
            if ($date instanceof \Carbon\Carbon){
0 ignored issues
show
$date is never a sub-type of Carbon\Carbon.
Loading history...
391
                $date = $date->format('d-M-Y H:i:s O');
392
            }
393
            return \imap_append($this->stream, $folder, $message, $flags, $date);
0 ignored issues
show
Bug Best Practice introduced by
The expression return imap_append($this...message, $flags, $date) returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...erface::appendMessage() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
394
        }
395
396
        return \imap_append($this->stream, $folder, $message, $flags);
0 ignored issues
show
Bug Best Practice introduced by
The expression return imap_append($this...lder, $message, $flags) returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...erface::appendMessage() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
397
    }
398
399
    /**
400
     * Copy message set from current folder to other folder
401
     * @param string $folder destination folder
402
     * @param $from
403
     * @param int|null $to if null only one message ($from) is fetched, else it's the
404
     *                         last message, INF means last message available
405
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
406
     *
407
     * @return bool success
408
     */
409
    public function copyMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool {
410
        return \imap_mail_copy($this->stream, $from, $folder, $uid ? IMAP::ST_UID : IMAP::NIL);
0 ignored issues
show
Bug Best Practice introduced by
The expression return imap_mail_copy($t...klex\PHPIMAP\IMAP::NIL) returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...nterface::copyMessage() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
411
    }
412
413
    /**
414
     * Copy multiple messages to the target folder
415
     * @param array $messages List of message identifiers
416
     * @param string $folder Destination folder
417
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
418
     *
419
     * @return array|bool Tokens if operation successful, false if an error occurred
420
     */
421
    public function copyManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) {
422
        foreach($messages as $msg) {
423
            if (!$this->copyMessage($folder, $msg, null, $uid)) {
424
                return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...ace::copyManyMessages() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
425
            }
426
        }
427
428
        return $messages;
429
    }
430
431
    /**
432
     * Move a message set from current folder to another folder
433
     * @param string $folder destination folder
434
     * @param $from
435
     * @param int|null $to if null only one message ($from) is fetched, else it's the
436
     *                         last message, INF means last message available
437
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
438
     *
439
     * @return bool success
440
     */
441
    public function moveMessage(string $folder, $from, $to = null, $uid = IMAP::ST_UID): bool {
442
        return \imap_mail_move($this->stream, $from, $folder, $uid ? IMAP::ST_UID : IMAP::NIL);
0 ignored issues
show
Bug Best Practice introduced by
The expression return imap_mail_move($t...klex\PHPIMAP\IMAP::NIL) returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...nterface::moveMessage() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
443
    }
444
445
    /**
446
     * Move multiple messages to the target folder
447
     * @param array $messages List of message identifiers
448
     * @param string $folder Destination folder
449
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
450
     *
451
     * @return array|bool Tokens if operation successful, false if an error occurred
452
     */
453
    public function moveManyMessages(array $messages, string $folder, $uid = IMAP::ST_UID) {
454
        foreach($messages as $msg) {
455
            if (!$this->moveMessage($folder, $msg, null, $uid)) {
456
                return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...ace::moveManyMessages() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
457
            }
458
        }
459
460
        return $messages;
461
    }
462
463
    /**
464
     * Exchange identification information
465
     * Ref.: https://datatracker.ietf.org/doc/html/rfc2971
466
     *
467
     * @param null $ids
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $ids is correct as it would always require null to be passed?
Loading history...
468
     * @return array|bool|void|null
469
     *
470
     * @throws MethodNotSupportedException
471
     */
472
    public function ID($ids = null) {
473
        throw new MethodNotSupportedException();
474
    }
475
476
    /**
477
     * Create a new folder (and parent folders if needed)
478
     * @param string $folder folder name
479
     *
480
     * @return bool success
481
     */
482
    public function createFolder(string $folder): bool {
483
        return \imap_createmailbox($this->stream, $folder);
0 ignored issues
show
Bug Best Practice introduced by
The expression return imap_createmailbox($this->stream, $folder) returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...terface::createFolder() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
484
    }
485
486
    /**
487
     * Rename an existing folder
488
     * @param string $old old name
489
     * @param string $new new name
490
     *
491
     * @return bool success
492
     */
493
    public function renameFolder(string $old, string $new): bool {
494
        return \imap_renamemailbox($this->stream, $old, $new);
0 ignored issues
show
Bug Best Practice introduced by
The expression return imap_renamemailbo...is->stream, $old, $new) returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...terface::renameFolder() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
495
    }
496
497
    /**
498
     * Delete a folder
499
     * @param string $folder folder name
500
     *
501
     * @return bool success
502
     */
503
    public function deleteFolder(string $folder): bool {
504
        return \imap_deletemailbox($this->stream, $folder);
0 ignored issues
show
Bug Best Practice introduced by
The expression return imap_deletemailbox($this->stream, $folder) returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...terface::deleteFolder() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
505
    }
506
507
    /**
508
     * Subscribe to a folder
509
     * @param string $folder folder name
510
     *
511
     * @throws MethodNotSupportedException
512
     */
513
    public function subscribeFolder(string $folder): bool {
514
        throw new MethodNotSupportedException();
515
    }
516
517
    /**
518
     * Unsubscribe from a folder
519
     * @param string $folder folder name
520
     *
521
     * @throws MethodNotSupportedException
522
     */
523
    public function unsubscribeFolder(string $folder): bool {
524
        throw new MethodNotSupportedException();
525
    }
526
527
    /**
528
     * Apply session saved changes to the server
529
     *
530
     * @return bool success
531
     */
532
    public function expunge(): bool {
533
        return \imap_expunge($this->stream);
0 ignored issues
show
Bug Best Practice introduced by
The expression return imap_expunge($this->stream) returns the type boolean which is incompatible with the return type mandated by Webklex\PHPIMAP\Connecti...colInterface::expunge() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
534
    }
535
536
    /**
537
     * Send noop command
538
     *
539
     * @throws MethodNotSupportedException
540
     */
541
    public function noop(): bool {
542
        throw new MethodNotSupportedException();
543
    }
544
545
    /**
546
     * Send idle command
547
     *
548
     * @throws MethodNotSupportedException
549
     */
550
    public function idle() {
551
        throw new MethodNotSupportedException();
552
    }
553
554
    /**
555
     * Send done command
556
     *
557
     * @throws MethodNotSupportedException
558
     */
559
    public function done() {
560
        throw new MethodNotSupportedException();
561
    }
562
563
    /**
564
     * Search for matching messages
565
     * @param array $params
566
     * @param int $uid set to IMAP::ST_UID if you pass message unique identifiers instead of numbers.
567
     *
568
     * @return array message ids
569
     */
570
    public function search(array $params, $uid = IMAP::ST_UID): array {
571
        $result = \imap_search($this->stream, $params[0], $uid ? IMAP::ST_UID : IMAP::NIL);
572
        if ($result === false) {
573
            return [];
574
        }
575
        return $result;
576
    }
577
578
    /**
579
     * Enable the debug mode
580
     */
581
    public function enableDebug(){
582
        $this->debug = true;
583
    }
584
585
    /**
586
     * Disable the debug mode
587
     */
588
    public function disableDebug(){
589
        $this->debug = false;
590
    }
591
592
    /**
593
     * Decode name.
594
     * It converts UTF7-IMAP encoding to UTF-8.
595
     *
596
     * @param $name
597
     *
598
     * @return array|false|string|string[]|null
599
     */
600
    protected function decodeFolderName($name) {
601
        preg_match('#\{(.*)\}(.*)#', $name, $preg);
602
        return mb_convert_encoding($preg[2], "UTF-8", "UTF7-IMAP");
603
    }
604
605
    /**
606
     * @return string
607
     */
608
    public function getProtocol(): string {
609
        return $this->protocol;
610
    }
611
612
    /**
613
     * Retrieve the quota level settings, and usage statics per mailbox
614
     * @param $username
615
     *
616
     * @return array
617
     */
618
    public function getQuota($username): array {
619
        return \imap_get_quota($this->stream, 'user.'.$username);
620
    }
621
622
    /**
623
     * Retrieve the quota settings per user
624
     * @param string $quota_root
625
     *
626
     * @return array
627
     */
628
    public function getQuotaRoot(string $quota_root = 'INBOX'): array {
629
        return \imap_get_quotaroot($this->stream, $quota_root);
630
    }
631
632
    /**
633
     * @param string $protocol
634
     * @return LegacyProtocol
635
     */
636
    public function setProtocol(string $protocol): LegacyProtocol {
637
        if (($pos = strpos($protocol, "legacy")) > 0) {
638
            $protocol = substr($protocol, 0, ($pos + 2) * -1);
639
        }
640
        $this->protocol = $protocol;
641
        return $this;
642
    }
643
}
644