Completed
Push — master ( 92912a...d77b64 )
by Malte
02:03
created

Message::make()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 30
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 30
rs 9.584
cc 2
nc 2
nop 8

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
/*
3
* File:     Message.php
4
* Category: -
5
* Author:   M. Goldenbaum
6
* Created:  19.01.17 22:21
7
* Updated:  -
8
*
9
* Description:
10
*  -
11
*/
12
13
namespace Webklex\PHPIMAP;
14
15
use Carbon\Carbon;
16
use Webklex\PHPIMAP\Exceptions\InvalidMessageDateException;
17
use Webklex\PHPIMAP\Exceptions\MaskNotFoundException;
18
use Webklex\PHPIMAP\Exceptions\MessageContentFetchingException;
19
use Webklex\PHPIMAP\Exceptions\MessageFlagException;
20
use Webklex\PHPIMAP\Exceptions\MessageHeaderFetchingException;
21
use Webklex\PHPIMAP\Exceptions\MethodNotFoundException;
22
use Webklex\PHPIMAP\Support\AttachmentCollection;
23
use Webklex\PHPIMAP\Support\FlagCollection;
24
use Webklex\PHPIMAP\Support\Masks\MessageMask;
25
use Illuminate\Support\Str;
26
use Webklex\PHPIMAP\Support\MessageCollection;
27
use Webklex\PHPIMAP\Traits\HasEvents;
28
29
/**
30
 * Class Message
31
 *
32
 * @package Webklex\PHPIMAP
33
 *
34
 * @property integer msglist
35
 * @property integer uid
36
 * @property integer msgn
37
 * @property string subject
38
 * @property string message_id
39
 * @property string message_no
40
 * @property string references
41
 * @property carbon date
42
 * @property array from
43
 * @property array to
44
 * @property array cc
45
 * @property array bcc
46
 * @property array reply_to
47
 * @property array in_reply_to
48
 * @property array sender
49
 *
50
 * @method integer getMsglist()
51
 * @method integer setMsglist(integer $msglist)
52
 * @method integer getUid()
53
 * @method integer getMsgn()
54
 * @method integer getPriority()
55
 * @method integer setPriority(integer $priority)
56
 * @method string getSubject()
57
 * @method string setSubject(string $subject)
58
 * @method string getMessageId()
59
 * @method string setMessageId(string $message_id)
60
 * @method string getMessageNo()
61
 * @method string setMessageNo(string $message_no)
62
 * @method string getReferences()
63
 * @method string setReferences(string $references)
64
 * @method carbon getDate()
65
 * @method carbon setDate(carbon $date)
66
 * @method array getFrom()
67
 * @method array setFrom(array $from)
68
 * @method array getTo()
69
 * @method array setTo(array $to)
70
 * @method array getCc()
71
 * @method array setCc(array $cc)
72
 * @method array getBcc()
73
 * @method array setBcc(array $bcc)
74
 * @method array getReplyTo()
75
 * @method array setReplyTo(array $reply_to)
76
 * @method array getInReplyTo()
77
 * @method array setInReplyTo(array $in_reply_to)
78
 * @method array getSender()
79
 * @method array setSender(array $sender)
80
 */
81
class Message {
82
    use HasEvents;
83
84
    /**
85
     * Client instance
86
     *
87
     * @var Client
88
     */
89
    private $client = Client::class;
90
91
    /**
92
     * Default mask
93
     *
94
     * @var string $mask
95
     */
96
    protected $mask = MessageMask::class;
97
98
    /**
99
     * Used config
100
     *
101
     * @var array $config
102
     */
103
    protected $config = [];
104
105
    /**
106
     * Attribute holder
107
     *
108
     * @var array $attributes
109
     */
110
    protected $attributes = [
111
        'message_no' => null,
112
    ];
113
114
    /**
115
     * The message folder path
116
     *
117
     * @var string $folder_path
118
     */
119
    protected $folder_path;
120
121
    /**
122
     * Fetch body options
123
     *
124
     * @var integer
125
     */
126
    public $fetch_options = null;
127
128
    /**
129
     * @var integer
130
     */
131
    protected $sequence = IMAP::NIL;
132
133
    /**
134
     * Fetch body options
135
     *
136
     * @var bool
137
     */
138
    public $fetch_body = null;
139
140
    /**
141
     * Fetch flags options
142
     *
143
     * @var bool
144
     */
145
    public $fetch_flags = null;
146
147
    /**
148
     * @var Header $header
149
     */
150
    public $header = null;
151
152
    /**
153
     * Raw message body
154
     *
155
     * @var null|string $raw_body
156
     */
157
    public $raw_body = null;
158
159
    /**
160
     * Message structure
161
     *
162
     * @var Structure $structure
163
     */
164
    protected $structure = null;
165
166
    /**
167
     * Message body components
168
     *
169
     * @var array   $bodies
170
     * @var AttachmentCollection|array $attachments
171
     * @var FlagCollection|array       $flags
172
     */
173
    public $bodies = [];
174
    public $attachments = [];
175
    public $flags = [];
176
177
    /**
178
     * A list of all available and supported flags
179
     *
180
     * @var array $available_flags
181
     */
182
    private $available_flags = null;
183
184
    /**
185
     * Message constructor.
186
     * @param integer $uid
187
     * @param integer|null $msglist
188
     * @param Client $client
189
     * @param integer|null $fetch_options
190
     * @param boolean $fetch_body
191
     * @param boolean $fetch_flags
192
     * @param integer $sequence
193
     *
194
     * @throws Exceptions\ConnectionFailedException
195
     * @throws InvalidMessageDateException
196
     * @throws Exceptions\RuntimeException
197
     * @throws MessageHeaderFetchingException
198
     * @throws MessageContentFetchingException
199
     * @throws Exceptions\EventNotFoundException
200
     * @throws MessageFlagException
201
     */
202
    public function __construct($uid, $msglist, Client $client, $fetch_options = null, $fetch_body = false, $fetch_flags = false, $sequence = null) {
203
204
        $default_mask = $client->getDefaultMessageMask();
205
        if($default_mask != null) {
206
            $this->mask = $default_mask;
207
        }
208
        $this->events["message"] = $client->getDefaultEvents("message");
209
        $this->events["flag"] = $client->getDefaultEvents("flag");
210
211
        $this->folder_path = $client->getFolderPath();
0 ignored issues
show
Documentation Bug introduced by
It seems like $client->getFolderPath() of type Webklex\PHPIMAP\Folder is incompatible with the declared type string of property $folder_path.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
212
213
        $this->config = ClientManager::get('options');
214
        $this->available_flags = ClientManager::get('flags');
215
216
        $this->setSequence($sequence);
217
        $this->setFetchOption($fetch_options);
218
        $this->setFetchBodyOption($fetch_body);
219
        $this->setFetchFlagsOption($fetch_flags);
220
221
        $this->attachments = AttachmentCollection::make([]);
222
        $this->flags = FlagCollection::make([]);
223
224
        $this->client = $client;
225
        $this->client->openFolder($this->folder_path);
0 ignored issues
show
Bug introduced by
$this->folder_path of type Webklex\PHPIMAP\Folder is incompatible with the type string expected by parameter $folder of Webklex\PHPIMAP\Client::openFolder(). ( Ignorable by Annotation )

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

225
        $this->client->openFolder(/** @scrutinizer ignore-type */ $this->folder_path);
Loading history...
226
227
        $this->setSequenceId($uid, $msglist);
0 ignored issues
show
Bug introduced by
It seems like $msglist can also be of type integer; however, parameter $msglist of Webklex\PHPIMAP\Message::setSequenceId() does only seem to accept null, 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

227
        $this->setSequenceId($uid, /** @scrutinizer ignore-type */ $msglist);
Loading history...
228
229
        if ($this->fetch_options == IMAP::FT_PEEK) {
230
            $this->parseFlags();
231
        }
232
233
        $this->parseHeader();
234
235
        if ($this->getFetchBodyOption() === true) {
236
            $this->parseBody();
237
        }
238
239
        if ($this->getFetchFlagsOption() === true && $this->fetch_options !== IMAP::FT_PEEK) {
240
            $this->parseFlags();
241
        }
242
    }
243
244
    /**
245
     * Create a new instance without fetching the message header and providing them raw instead
246
     * @param int $uid
247
     * @param int|null $msglist
248
     * @param Client $client
249
     * @param string $raw_header
250
     * @param string $raw_body
251
     * @param string $raw_flags
252
     * @param null $fetch_options
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $fetch_options is correct as it would always require null to be passed?
Loading history...
253
     * @param null $sequence
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $sequence is correct as it would always require null to be passed?
Loading history...
254
     *
255
     * @return Message
256
     * @throws Exceptions\ConnectionFailedException
257
     * @throws Exceptions\EventNotFoundException
258
     * @throws InvalidMessageDateException
259
     * @throws MessageContentFetchingException
260
     * @throws \ReflectionException
261
     * @throws MessageFlagException
262
     * @throws Exceptions\RuntimeException
263
     */
264
    public static function make($uid, $msglist, Client $client, $raw_header, $raw_body, $raw_flags, $fetch_options = null, $sequence = null){
265
        $reflection = new \ReflectionClass(self::class);
266
        /** @var self $instance */
267
        $instance = $reflection->newInstanceWithoutConstructor();
268
269
        $default_mask = $client->getDefaultMessageMask();
270
        if($default_mask != null) {
271
            $instance->setMask($default_mask);
272
        }
273
        $instance->setEvents([
274
            "message" => $client->getDefaultEvents("message"),
275
            "flag" => $client->getDefaultEvents("flag"),
276
        ]);
277
        $instance->setFolderPath($client->getFolderPath());
278
        $instance->setConfig(ClientManager::get('options'));
279
        $instance->setAvailableFlags(ClientManager::get('flags'));
280
        $instance->setSequence($sequence);
281
        $instance->setFetchOption($fetch_options);
282
283
        $instance->setAttachments(AttachmentCollection::make([]));
284
285
        $instance->setClient($client);
286
        $instance->setSequenceId($uid, $msglist);
0 ignored issues
show
Bug introduced by
It seems like $msglist can also be of type integer; however, parameter $msglist of Webklex\PHPIMAP\Message::setSequenceId() does only seem to accept null, 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

286
        $instance->setSequenceId($uid, /** @scrutinizer ignore-type */ $msglist);
Loading history...
287
288
        $instance->parseRawHeader($raw_header);
289
        $instance->parseRawFlags($raw_flags);
290
        $instance->parseRawBody($raw_body);
291
        $instance->peek();
292
293
        return $instance;
294
    }
295
296
    /**
297
     * Call dynamic attribute setter and getter methods
298
     * @param string $method
299
     * @param array $arguments
300
     *
301
     * @return mixed
302
     * @throws MethodNotFoundException
303
     */
304
    public function __call($method, $arguments) {
305
        if(strtolower(substr($method, 0, 3)) === 'get') {
306
            $name = Str::snake(substr($method, 3));
307
            return $this->get($name);
308
        }elseif (strtolower(substr($method, 0, 3)) === 'set') {
309
            $name = Str::snake(substr($method, 3));
310
311
            if(in_array($name, array_keys($this->attributes))) {
312
                return $this->__set($name, array_pop($arguments));
313
            }
314
315
        }
316
317
        throw new MethodNotFoundException("Method ".self::class.'::'.$method.'() is not supported');
318
    }
319
320
    /**
321
     * Magic setter
322
     * @param $name
323
     * @param $value
324
     *
325
     * @return mixed
326
     */
327
    public function __set($name, $value) {
328
        $this->attributes[$name] = $value;
329
330
        return $this->attributes[$name];
331
    }
332
333
    /**
334
     * Magic getter
335
     * @param $name
336
     *
337
     * @return mixed|null
338
     */
339
    public function __get($name) {
340
        return $this->get($name);
341
    }
342
343
    /**
344
     * Get an available message or message header attribute
345
     * @param $name
346
     *
347
     * @return mixed|null
348
     */
349
    public function get($name) {
350
        if(isset($this->attributes[$name])) {
351
            return $this->attributes[$name];
352
        }
353
354
        return $this->header->get($name);
355
    }
356
357
    /**
358
     * Check if the Message has a text body
359
     *
360
     * @return bool
361
     */
362
    public function hasTextBody() {
363
        return isset($this->bodies['text']);
364
    }
365
366
    /**
367
     * Get the Message text body
368
     *
369
     * @return mixed
370
     */
371
    public function getTextBody() {
372
        if (!isset($this->bodies['text'])) {
373
            return null;
374
        }
375
376
        return $this->bodies['text'];
377
    }
378
379
    /**
380
     * Check if the Message has a html body
381
     *
382
     * @return bool
383
     */
384
    public function hasHTMLBody() {
385
        return isset($this->bodies['html']);
386
    }
387
388
    /**
389
     * Get the Message html body
390
     *
391
     * @return string|null
392
     */
393
    public function getHTMLBody() {
394
        if (!isset($this->bodies['html'])) {
395
            return null;
396
        }
397
398
        return $this->bodies['html'];
399
    }
400
401
    /**
402
     * Parse all defined headers
403
     *
404
     * @throws Exceptions\ConnectionFailedException
405
     * @throws Exceptions\RuntimeException
406
     * @throws InvalidMessageDateException
407
     * @throws MessageHeaderFetchingException
408
     */
409
    private function parseHeader() {
410
        $sequence_id = $this->getSequenceId();
411
        $headers = $this->client->getConnection()->headers([$sequence_id], "RFC822", $this->sequence === IMAP::ST_UID);
0 ignored issues
show
Bug introduced by
The method headers() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

411
        $headers = $this->client->getConnection()->/** @scrutinizer ignore-call */ headers([$sequence_id], "RFC822", $this->sequence === IMAP::ST_UID);
Loading history...
412
        if (!isset($headers[$sequence_id])) {
413
            throw new MessageHeaderFetchingException("no headers found", 0);
414
        }
415
416
        $this->parseRawHeader($headers[$sequence_id]);
417
    }
418
419
    /**
420
     * @param string $raw_header
421
     *
422
     * @throws InvalidMessageDateException
423
     */
424
    public function parseRawHeader($raw_header){
425
        $this->header = new Header($raw_header);
426
    }
427
428
    /**
429
     * Parse additional raw flags
430
     * @param $raw_flags
431
     */
432
    public function parseRawFlags($raw_flags) {
433
        $this->flags = FlagCollection::make([]);
434
435
        foreach($raw_flags as $flag) {
436
            if (strpos($flag, "\\") === 0){
437
                $flag = substr($flag, 1);
438
            }
439
            $flag_key = strtolower($flag);
440
            if (in_array($flag_key, $this->available_flags) || $this->available_flags === null) {
441
                $this->flags->put($flag_key, $flag);
442
            }
443
        }
444
    }
445
446
    /**
447
     * Parse additional flags
448
     *
449
     * @return void
450
     * @throws Exceptions\ConnectionFailedException
451
     * @throws MessageFlagException
452
     */
453
    private function parseFlags() {
454
        $this->client->openFolder($this->folder_path);
455
        $this->flags = FlagCollection::make([]);
456
457
        $sequence_id = $this->getSequenceId();
458
        try {
459
            $flags = $this->client->getConnection()->flags([$sequence_id], $this->sequence === IMAP::ST_UID);
0 ignored issues
show
Bug introduced by
The method flags() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

459
            $flags = $this->client->getConnection()->/** @scrutinizer ignore-call */ flags([$sequence_id], $this->sequence === IMAP::ST_UID);
Loading history...
460
        } catch (Exceptions\RuntimeException $e) {
461
            throw new MessageFlagException("flag could not be fetched", 0, $e);
462
        }
463
464
        if (isset($flags[$sequence_id])) {
465
            $this->parseRawFlags($flags[$sequence_id]);
466
        }
467
    }
468
469
    /**
470
     * Parse the Message body
471
     *
472
     * @return $this
473
     * @throws Exceptions\ConnectionFailedException
474
     * @throws Exceptions\MessageContentFetchingException
475
     * @throws InvalidMessageDateException
476
     * @throws Exceptions\EventNotFoundException
477
     * @throws MessageFlagException
478
     */
479
    public function parseBody() {
480
        $this->client->openFolder($this->folder_path);
481
482
        $sequence_id = $this->getSequenceId();
483
        try {
484
            $contents = $this->client->getConnection()->content([$sequence_id], "RFC822", $this->sequence === IMAP::ST_UID);
0 ignored issues
show
Bug introduced by
The method content() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

484
            $contents = $this->client->getConnection()->/** @scrutinizer ignore-call */ content([$sequence_id], "RFC822", $this->sequence === IMAP::ST_UID);
Loading history...
485
        } catch (Exceptions\RuntimeException $e) {
486
            throw new MessageContentFetchingException("failed to fetch content", 0);
487
        }
488
        if (!isset($contents[$sequence_id])) {
489
            throw new MessageContentFetchingException("no content found", 0);
490
        }
491
        $content = $contents[$sequence_id];
492
493
        $body = $this->parseRawBody($content);
494
        $this->peek();
495
496
        return $body;
497
    }
498
499
    /**
500
     * Handle auto "Seen" flag handling
501
     *
502
     * @throws Exceptions\ConnectionFailedException
503
     * @throws Exceptions\EventNotFoundException
504
     * @throws MessageFlagException
505
     */
506
    public function peek(){
507
        if ($this->fetch_options == IMAP::FT_PEEK) {
508
            if ($this->getFlags()->get("seen") == null) {
509
                $this->unsetFlag("Seen");
510
            }
511
        }elseif ($this->getFlags()->get("seen") != null) {
512
            $this->setFlag("Seen");
513
        }
514
    }
515
516
    /**
517
     * Parse a given message body
518
     * @param string $raw_body
519
     *
520
     * @return $this
521
     * @throws Exceptions\ConnectionFailedException
522
     * @throws InvalidMessageDateException
523
     * @throws MessageContentFetchingException
524
     */
525
    public function parseRawBody($raw_body) {
526
        $this->structure = new Structure($raw_body, $this->header);
527
        $this->fetchStructure($this->structure);
528
529
        return $this;
530
    }
531
532
    /**
533
     * Fetch the Message structure
534
     * @param $structure
535
     *
536
     * @throws Exceptions\ConnectionFailedException
537
     */
538
    private function fetchStructure($structure) {
539
        $this->client->openFolder($this->folder_path);
540
541
        foreach ($structure->parts as $part) {
542
            $this->fetchPart($part);
543
        }
544
    }
545
546
    /**
547
     * Fetch a given part
548
     * @param Part $part
549
     */
550
    private function fetchPart(Part $part) {
551
        if ($part->isAttachment()) {
552
            $this->fetchAttachment($part);
553
        }else{
554
            $encoding = $this->getEncoding($part);
555
556
            $content = $this->decodeString($part->content, $part->encoding);
557
558
            // We don't need to do convertEncoding() if charset is ASCII (us-ascii):
559
            //     ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded
560
            //     https://stackoverflow.com/a/11303410
561
            //
562
            // us-ascii is the same as ASCII:
563
            //     ASCII is the traditional name for the encoding system; the Internet Assigned Numbers Authority (IANA)
564
            //     prefers the updated name US-ASCII, which clarifies that this system was developed in the US and
565
            //     based on the typographical symbols predominantly in use there.
566
            //     https://en.wikipedia.org/wiki/ASCII
567
            //
568
            // convertEncoding() function basically means convertToUtf8(), so when we convert ASCII string into UTF-8 it gets broken.
569
            if ($encoding != 'us-ascii') {
570
                $content = $this->convertEncoding($content, $encoding);
571
            }
572
573
            $subtype = strtolower($part->subtype);
574
            $subtype = $subtype == "plain" || $subtype == "" ? "text" : $subtype;
575
576
            $this->bodies[$subtype] = $content;
577
        }
578
    }
579
580
    /**
581
     * Fetch the Message attachment
582
     * @param Part $part
583
     */
584
    protected function fetchAttachment($part) {
585
        $oAttachment = new Attachment($this, $part);
586
587
        if ($oAttachment->getName() !== null && $oAttachment->getSize() > 0) {
588
            if ($oAttachment->getId() !== null) {
0 ignored issues
show
introduced by
The condition $oAttachment->getId() !== null is always true.
Loading history...
589
                $this->attachments->put($oAttachment->getId(), $oAttachment);
590
            } else {
591
                $this->attachments->push($oAttachment);
592
            }
593
        }
594
    }
595
596
    /**
597
     * Fail proof setter for $fetch_option
598
     * @param $option
599
     *
600
     * @return $this
601
     */
602
    public function setFetchOption($option) {
603
        if (is_long($option) === true) {
604
            $this->fetch_options = $option;
605
        } elseif (is_null($option) === true) {
606
            $config = ClientManager::get('options.fetch', IMAP::FT_UID);
607
            $this->fetch_options = is_long($config) ? $config : 1;
608
        }
609
610
        return $this;
611
    }
612
613
    /**
614
     * Set the sequence type
615
     * @param int $sequence
616
     *
617
     * @return $this
618
     */
619
    public function setSequence($sequence) {
620
        if (is_long($sequence)) {
0 ignored issues
show
introduced by
The condition is_long($sequence) is always true.
Loading history...
621
            $this->sequence = $sequence;
622
        } elseif (is_null($sequence)) {
623
            $config = ClientManager::get('options.sequence', IMAP::ST_MSGN);
624
            $this->sequence = is_long($config) ? $config : IMAP::ST_MSGN;
625
        }
626
627
        return $this;
628
    }
629
630
    /**
631
     * Fail proof setter for $fetch_body
632
     * @param $option
633
     *
634
     * @return $this
635
     */
636
    public function setFetchBodyOption($option) {
637
        if (is_bool($option)) {
638
            $this->fetch_body = $option;
639
        } elseif (is_null($option)) {
640
            $config = ClientManager::get('options.fetch_body', true);
641
            $this->fetch_body = is_bool($config) ? $config : true;
642
        }
643
644
        return $this;
645
    }
646
647
    /**
648
     * Fail proof setter for $fetch_flags
649
     * @param $option
650
     *
651
     * @return $this
652
     */
653
    public function setFetchFlagsOption($option) {
654
        if (is_bool($option)) {
655
            $this->fetch_flags = $option;
656
        } elseif (is_null($option)) {
657
            $config = ClientManager::get('options.fetch_flags', true);
658
            $this->fetch_flags = is_bool($config) ? $config : true;
659
        }
660
661
        return $this;
662
    }
663
664
    /**
665
     * Decode a given string
666
     * @param $string
667
     * @param $encoding
668
     *
669
     * @return string
670
     */
671
    public function decodeString($string, $encoding) {
672
        switch ($encoding) {
673
            case IMAP::MESSAGE_ENC_BINARY:
674
                if (extension_loaded('imap')) {
675
                    return base64_decode(\imap_binary($string));
676
                }
677
                return base64_decode($string);
678
            case IMAP::MESSAGE_ENC_BASE64:
679
                return base64_decode($string);
680
            case IMAP::MESSAGE_ENC_8BIT:
681
            case IMAP::MESSAGE_ENC_QUOTED_PRINTABLE:
682
                return quoted_printable_decode($string);
683
            case IMAP::MESSAGE_ENC_7BIT:
684
            case IMAP::MESSAGE_ENC_OTHER:
685
            default:
686
                return $string;
687
        }
688
    }
689
690
    /**
691
     * Convert the encoding
692
     * @param $str
693
     * @param string $from
694
     * @param string $to
695
     *
696
     * @return mixed|string
697
     */
698
    public function convertEncoding($str, $from = "ISO-8859-2", $to = "UTF-8") {
699
700
        $from = EncodingAliases::get($from);
701
        $to = EncodingAliases::get($to);
702
703
        if ($from === $to) {
704
            return $str;
705
        }
706
707
        // We don't need to do convertEncoding() if charset is ASCII (us-ascii):
708
        //     ASCII is a subset of UTF-8, so all ASCII files are already UTF-8 encoded
709
        //     https://stackoverflow.com/a/11303410
710
        //
711
        // us-ascii is the same as ASCII:
712
        //     ASCII is the traditional name for the encoding system; the Internet Assigned Numbers Authority (IANA)
713
        //     prefers the updated name US-ASCII, which clarifies that this system was developed in the US and
714
        //     based on the typographical symbols predominantly in use there.
715
        //     https://en.wikipedia.org/wiki/ASCII
716
        //
717
        // convertEncoding() function basically means convertToUtf8(), so when we convert ASCII string into UTF-8 it gets broken.
718
        if (strtolower($from) == 'us-ascii' && $to == 'UTF-8') {
719
            return $str;
720
        }
721
722
        if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') {
723
            return @iconv($from, $to.'//IGNORE', $str);
724
        } else {
725
            if (!$from) {
726
                return mb_convert_encoding($str, $to);
727
            }
728
            return mb_convert_encoding($str, $to, $from);
729
        }
730
    }
731
732
    /**
733
     * Get the encoding of a given abject
734
     * @param object|string $structure
735
     *
736
     * @return string
737
     */
738
    public function getEncoding($structure) {
739
        if (property_exists($structure, 'parameters')) {
740
            foreach ($structure->parameters as $parameter) {
741
                if (strtolower($parameter->attribute) == "charset") {
742
                    return EncodingAliases::get($parameter->value);
743
                }
744
            }
745
        }elseif (property_exists($structure, 'charset')){
746
            return EncodingAliases::get($structure->charset);
747
        }elseif (is_string($structure) === true){
748
            return mb_detect_encoding($structure);
749
        }
750
751
        return 'UTF-8';
752
    }
753
754
    /**
755
     * Get the messages folder
756
     *
757
     * @return mixed
758
     * @throws Exceptions\ConnectionFailedException
759
     * @throws Exceptions\FolderFetchingException
760
     */
761
    public function getFolder(){
762
        return $this->client->getFolder($this->folder_path);
763
    }
764
765
    /**
766
     * Create a message thread based on the current message
767
     * @param Folder|null $sent_folder
768
     * @param MessageCollection|null $thread
769
     * @param Folder|null $folder
770
     *
771
     * @return MessageCollection|null
772
     * @throws Exceptions\ConnectionFailedException
773
     * @throws Exceptions\FolderFetchingException
774
     * @throws Exceptions\GetMessagesFailedException
775
     */
776
    public function thread($sent_folder = null, &$thread = null, $folder = null){
777
        $thread = $thread ? $thread : MessageCollection::make([]);
778
        $folder = $folder ? $folder :  $this->getFolder();
779
        $sent_folder = $sent_folder ? $sent_folder : $this->client->getFolder(ClientManager::get("options.common_folders.sent", "INBOX/Sent"));
780
781
        /** @var Message $message */
782
        foreach($thread as $message) {
783
            if ($message->message_id == $this->message_id) {
784
                return $thread;
785
            }
786
        }
787
        $thread->push($this);
788
789
        $this->fetchThreadByInReplyTo($thread, $this->message_id, $folder, $folder, $sent_folder);
790
        $this->fetchThreadByInReplyTo($thread, $this->message_id, $sent_folder, $folder, $sent_folder);
791
792
        if (is_array($this->in_reply_to)) {
0 ignored issues
show
introduced by
The condition is_array($this->in_reply_to) is always true.
Loading history...
793
            foreach($this->in_reply_to as $in_reply_to) {
794
                $this->fetchThreadByMessageId($thread, $in_reply_to, $folder, $folder, $sent_folder);
795
                $this->fetchThreadByMessageId($thread, $in_reply_to, $sent_folder, $folder, $sent_folder);
796
            }
797
        }
798
799
        return $thread;
800
    }
801
802
    /**
803
     * Fetch a partial thread by message id
804
     * @param MessageCollection $thread
805
     * @param string $in_reply_to
806
     * @param Folder $primary_folder
807
     * @param Folder $secondary_folder
808
     * @param Folder $sent_folder
809
     *
810
     * @throws Exceptions\ConnectionFailedException
811
     * @throws Exceptions\GetMessagesFailedException
812
     */
813
    protected function fetchThreadByInReplyTo(&$thread, $in_reply_to, $primary_folder, $secondary_folder, $sent_folder){
814
        $primary_folder->query()->inReplyTo($in_reply_to)
815
        ->setFetchBody($this->getFetchBodyOption())
816
        ->leaveUnread()->get()->each(function($message) use(&$thread, $secondary_folder, $sent_folder){
817
            /** @var Message $message */
818
            $message->thread($sent_folder, $thread, $secondary_folder);
819
        });
820
    }
821
822
    /**
823
     * Fetch a partial thread by message id
824
     * @param MessageCollection $thread
825
     * @param string $message_id
826
     * @param Folder $primary_folder
827
     * @param Folder $secondary_folder
828
     * @param Folder $sent_folder
829
     *
830
     * @throws Exceptions\ConnectionFailedException
831
     * @throws Exceptions\GetMessagesFailedException
832
     */
833
    protected function fetchThreadByMessageId(&$thread, $message_id, $primary_folder, $secondary_folder, $sent_folder){
834
        $primary_folder->query()->messageId($message_id)
835
        ->setFetchBody($this->getFetchBodyOption())
836
        ->leaveUnread()->get()->each(function($message) use(&$thread, $secondary_folder, $sent_folder){
837
            /** @var Message $message */
838
            $message->thread($sent_folder, $thread, $secondary_folder);
839
        });
840
    }
841
842
    /**
843
     * Copy the current Messages to a mailbox
844
     * @param string $folder_path
845
     * @param boolean $expunge
846
     *
847
     * @return null|Message
848
     * @throws Exceptions\ConnectionFailedException
849
     * @throws Exceptions\FolderFetchingException
850
     * @throws Exceptions\RuntimeException
851
     * @throws InvalidMessageDateException
852
     * @throws MessageContentFetchingException
853
     * @throws MessageHeaderFetchingException
854
     * @throws Exceptions\EventNotFoundException
855
     * @throws MessageFlagException
856
     */
857
    public function copy($folder_path, $expunge = false) {
858
        $this->client->openFolder($folder_path);
859
        $status = $this->client->getConnection()->examineFolder($folder_path);
0 ignored issues
show
Bug introduced by
The method examineFolder() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

859
        $status = $this->client->getConnection()->/** @scrutinizer ignore-call */ examineFolder($folder_path);
Loading history...
860
861
        if (isset($status["uidnext"])) {
862
            $next_uid = $status["uidnext"];
863
864
            /** @var Folder $folder */
865
            $folder = $this->client->getFolder($folder_path);
866
867
            $this->client->openFolder($this->folder_path);
868
            if ($this->client->getConnection()->copyMessage($folder->path, $this->getSequenceId(), null, $this->sequence === IMAP::ST_UID) == true) {
0 ignored issues
show
Bug introduced by
The method copyMessage() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

868
            if ($this->client->getConnection()->/** @scrutinizer ignore-call */ copyMessage($folder->path, $this->getSequenceId(), null, $this->sequence === IMAP::ST_UID) == true) {
Loading history...
869
                return $this->fetchNewMail($folder, $next_uid, "copied", $expunge);
870
            }
871
        }
872
873
        return null;
874
    }
875
876
    /**
877
     * Move the current Messages to a mailbox
878
     * @param string $folder_path
879
     * @param boolean $expunge
880
     *
881
     * @return Message|null
882
     * @throws Exceptions\ConnectionFailedException
883
     * @throws Exceptions\FolderFetchingException
884
     * @throws Exceptions\RuntimeException
885
     * @throws InvalidMessageDateException
886
     * @throws MessageContentFetchingException
887
     * @throws MessageHeaderFetchingException
888
     * @throws Exceptions\EventNotFoundException
889
     * @throws MessageFlagException
890
     */
891
    public function move($folder_path, $expunge = false) {
892
        $this->client->openFolder($folder_path);
893
        $status = $this->client->getConnection()->examineFolder($folder_path);
894
895
        if (isset($status["uidnext"])) {
896
            $next_uid = $status["uidnext"];
897
898
            /** @var Folder $folder */
899
            $folder = $this->client->getFolder($folder_path);
900
901
            $this->client->openFolder($this->folder_path);
902
            if ($this->client->getConnection()->moveMessage($folder->path, $this->getSequenceId(), null, $this->sequence === IMAP::ST_UID) == true) {
0 ignored issues
show
Bug introduced by
The method moveMessage() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

902
            if ($this->client->getConnection()->/** @scrutinizer ignore-call */ moveMessage($folder->path, $this->getSequenceId(), null, $this->sequence === IMAP::ST_UID) == true) {
Loading history...
903
                return $this->fetchNewMail($folder, $next_uid, "moved", $expunge);
904
            }
905
        }
906
907
        return null;
908
    }
909
910
    /**
911
     * Fetch a new message and fire a given event
912
     * @param Folder $folder
913
     * @param int $next_uid
914
     * @param string $event
915
     * @param boolean $expunge
916
     *
917
     * @return mixed
918
     * @throws Exceptions\ConnectionFailedException
919
     * @throws Exceptions\EventNotFoundException
920
     * @throws Exceptions\RuntimeException
921
     * @throws InvalidMessageDateException
922
     * @throws MessageContentFetchingException
923
     * @throws MessageFlagException
924
     * @throws MessageHeaderFetchingException
925
     */
926
    protected function fetchNewMail($folder, $next_uid, $event, $expunge){
927
        if($expunge) $this->client->expunge();
928
929
        $this->client->openFolder($folder->path);
930
931
        if ($this->sequence === IMAP::ST_UID) {
932
            $sequence_id = $next_uid;
933
        }else{
934
            $sequence_id = $this->client->getConnection()->getMessageNumber($next_uid);
0 ignored issues
show
Bug introduced by
The method getMessageNumber() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

934
            $sequence_id = $this->client->getConnection()->/** @scrutinizer ignore-call */ getMessageNumber($next_uid);
Loading history...
935
        }
936
937
        $message = $folder->query()->getMessage($sequence_id, null, $this->sequence);
938
        $event = $this->getEvent("message", $event);
939
        $event::dispatch($this, $message);
940
941
        return $message;
942
    }
943
944
    /**
945
     * Delete the current Message
946
     * @param bool $expunge
947
     *
948
     * @return bool
949
     * @throws Exceptions\ConnectionFailedException
950
     * @throws Exceptions\EventNotFoundException
951
     * @throws MessageFlagException
952
     */
953
    public function delete($expunge = true) {
954
        $status = $this->setFlag("Deleted");
955
        if($expunge) $this->client->expunge();
956
957
        $event = $this->getEvent("message", "deleted");
958
        $event::dispatch($this);
959
960
        return $status;
961
    }
962
963
    /**
964
     * Restore a deleted Message
965
     * @param boolean $expunge
966
     *
967
     * @return bool
968
     * @throws Exceptions\ConnectionFailedException
969
     * @throws Exceptions\EventNotFoundException
970
     * @throws MessageFlagException
971
     */
972
    public function restore($expunge = true) {
973
        $status = $this->unsetFlag("Deleted");
974
        if($expunge) $this->client->expunge();
975
976
        $event = $this->getEvent("message", "restored");
977
        $event::dispatch($this);
978
979
        return $status;
980
    }
981
982
    /**
983
     * Set a given flag
984
     * @param string|array $flag
985
     *
986
     * @return bool
987
     * @throws Exceptions\ConnectionFailedException
988
     * @throws MessageFlagException
989
     * @throws Exceptions\EventNotFoundException
990
     */
991
    public function setFlag($flag) {
992
        $this->client->openFolder($this->folder_path);
993
        $flag = "\\".trim(is_array($flag) ? implode(" \\", $flag) : $flag);
994
        $sequence_id = $this->getSequenceId();
995
        try {
996
            $status = $this->client->getConnection()->store([$flag], $sequence_id, $sequence_id, "+", true, $this->sequence === IMAP::ST_UID);
0 ignored issues
show
Bug introduced by
The method store() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

996
            $status = $this->client->getConnection()->/** @scrutinizer ignore-call */ store([$flag], $sequence_id, $sequence_id, "+", true, $this->sequence === IMAP::ST_UID);
Loading history...
997
        } catch (Exceptions\RuntimeException $e) {
998
            throw new MessageFlagException("flag could not be set", 0, $e);
999
        }
1000
        $this->parseFlags();
1001
1002
        $event = $this->getEvent("flag", "new");
1003
        $event::dispatch($this, $flag);
1004
1005
        return $status;
1006
    }
1007
1008
    /**
1009
     * Unset a given flag
1010
     * @param string|array $flag
1011
     *
1012
     * @return bool
1013
     * @throws Exceptions\ConnectionFailedException
1014
     * @throws Exceptions\EventNotFoundException
1015
     * @throws MessageFlagException
1016
     */
1017
    public function unsetFlag($flag) {
1018
        $this->client->openFolder($this->folder_path);
1019
1020
        $flag = "\\".trim(is_array($flag) ? implode(" \\", $flag) : $flag);
1021
        $sequence_id = $this->getSequenceId();
1022
        try {
1023
            $status = $this->client->getConnection()->store([$flag], $sequence_id, $sequence_id, "-", true, $this->sequence === IMAP::ST_UID);
1024
        } catch (Exceptions\RuntimeException $e) {
1025
            throw new MessageFlagException("flag could not be removed", 0, $e);
1026
        }
1027
        $this->parseFlags();
1028
1029
        $event = $this->getEvent("flag", "deleted");
1030
        $event::dispatch($this, $flag);
1031
1032
        return $status;
1033
    }
1034
1035
    /**
1036
     * Set a given flag
1037
     * @param string|array $flag
1038
     *
1039
     * @return bool
1040
     * @throws Exceptions\ConnectionFailedException
1041
     * @throws MessageFlagException
1042
     * @throws Exceptions\EventNotFoundException
1043
     */
1044
    public function addFlag($flag) {
1045
        return $this->setFlag($flag);
1046
    }
1047
1048
    /**
1049
     * Unset a given flag
1050
     * @param string|array $flag
1051
     *
1052
     * @return bool
1053
     * @throws Exceptions\ConnectionFailedException
1054
     * @throws Exceptions\EventNotFoundException
1055
     * @throws MessageFlagException
1056
     */
1057
    public function removeFlag($flag) {
1058
        return $this->unsetFlag($flag);
1059
    }
1060
1061
    /**
1062
     * Get all message attachments.
1063
     *
1064
     * @return AttachmentCollection
1065
     */
1066
    public function getAttachments() {
1067
        return $this->attachments;
1068
    }
1069
1070
    /**
1071
     * Get all message attachments.
1072
     *
1073
     * @return AttachmentCollection
1074
     */
1075
    public function attachments(){
1076
        return $this->getAttachments();
1077
    }
1078
1079
    /**
1080
     * Checks if there are any attachments present
1081
     *
1082
     * @return boolean
1083
     */
1084
    public function hasAttachments() {
1085
        return $this->attachments->isEmpty() === false;
1086
    }
1087
1088
    /**
1089
     * Get the raw body
1090
     *
1091
     * @return string
1092
     * @throws Exceptions\ConnectionFailedException
1093
     */
1094
    public function getRawBody() {
1095
        if ($this->raw_body === null) {
1096
            $this->client->openFolder($this->folder_path);
1097
1098
            $this->raw_body = $this->structure->raw;
1099
        }
1100
1101
        return $this->raw_body;
1102
    }
1103
1104
    /**
1105
     * Get the message header
1106
     *
1107
     * @return Header
1108
     */
1109
    public function getHeader() {
1110
        return $this->header;
1111
    }
1112
1113
    /**
1114
     * Get the current client
1115
     *
1116
     * @return Client
1117
     */
1118
    public function getClient() {
1119
        return $this->client;
1120
    }
1121
1122
    /**
1123
     * Get the used fetch option
1124
     *
1125
     * @return integer
1126
     */
1127
    public function getFetchOptions() {
1128
        return $this->fetch_options;
1129
    }
1130
1131
    /**
1132
     * Get the used fetch body option
1133
     *
1134
     * @return boolean
1135
     */
1136
    public function getFetchBodyOption() {
1137
        return $this->fetch_body;
1138
    }
1139
1140
    /**
1141
     * Get the used fetch flags option
1142
     *
1143
     * @return boolean
1144
     */
1145
    public function getFetchFlagsOption() {
1146
        return $this->fetch_flags;
1147
    }
1148
1149
    /**
1150
     * Get all available bodies
1151
     *
1152
     * @return array
1153
     */
1154
    public function getBodies() {
1155
        return $this->bodies;
1156
    }
1157
1158
    /**
1159
     * Get all set flags
1160
     *
1161
     * @return FlagCollection
1162
     */
1163
    public function getFlags() {
1164
        return $this->flags;
1165
    }
1166
1167
    /**
1168
     * Get all set flags
1169
     *
1170
     * @return FlagCollection
1171
     */
1172
    public function flags(){
1173
        return $this->getFlags();
1174
    }
1175
1176
    /**
1177
     * Get the fetched structure
1178
     *
1179
     * @return Structure|null
1180
     */
1181
    public function getStructure(){
1182
        return $this->structure;
1183
    }
1184
1185
    /**
1186
     * Check if a message matches an other by comparing basic attributes
1187
     *
1188
     * @param  null|Message $message
1189
     * @return boolean
1190
     */
1191
    public function is(Message $message = null) {
1192
        if (is_null($message)) {
1193
            return false;
1194
        }
1195
1196
        return $this->uid == $message->uid
1197
            && $this->message_id == $message->message_id
1198
            && $this->subject == $message->subject
1199
            && $this->date->eq($message->date);
1200
    }
1201
1202
    /**
1203
     * Get all message attributes
1204
     *
1205
     * @return array
1206
     */
1207
    public function getAttributes(){
1208
        return array_merge($this->attributes, $this->header->getAttributes());
1209
    }
1210
1211
    /**
1212
     * Set the message mask
1213
     * @param $mask
1214
     *
1215
     * @return $this
1216
     */
1217
    public function setMask($mask){
1218
        if(class_exists($mask)){
1219
            $this->mask = $mask;
1220
        }
1221
1222
        return $this;
1223
    }
1224
1225
    /**
1226
     * Get the used message mask
1227
     *
1228
     * @return string
1229
     */
1230
    public function getMask(){
1231
        return $this->mask;
1232
    }
1233
1234
    /**
1235
     * Get a masked instance by providing a mask name
1236
     * @param string|null $mask
1237
     *
1238
     * @return mixed
1239
     * @throws MaskNotFoundException
1240
     */
1241
    public function mask($mask = null){
1242
        $mask = $mask !== null ? $mask : $this->mask;
1243
        if(class_exists($mask)){
1244
            return new $mask($this);
1245
        }
1246
1247
        throw new MaskNotFoundException("Unknown mask provided: ".$mask);
1248
    }
1249
1250
    /**
1251
     * Set the message path aka folder path
1252
     * @param $folder_path
1253
     *
1254
     * @return $this
1255
     */
1256
    public function setFolderPath($folder_path){
1257
        $this->folder_path = $folder_path;
1258
1259
        return $this;
1260
    }
1261
1262
    /**
1263
     * Set the config
1264
     * @param $config
1265
     *
1266
     * @return $this
1267
     */
1268
    public function setConfig($config){
1269
        $this->config = $config;
1270
1271
        return $this;
1272
    }
1273
1274
    /**
1275
     * Set the available flags
1276
     * @param $available_flags
1277
     *
1278
     * @return $this
1279
     */
1280
    public function setAvailableFlags($available_flags){
1281
        $this->available_flags = $available_flags;
1282
1283
        return $this;
1284
    }
1285
1286
    /**
1287
     * Set the attachment collection
1288
     * @param $attachments
1289
     *
1290
     * @return $this
1291
     */
1292
    public function setAttachments($attachments){
1293
        $this->attachments = $attachments;
1294
1295
        return $this;
1296
    }
1297
1298
    /**
1299
     * Set the flag collection
1300
     * @param $flags
1301
     *
1302
     * @return $this
1303
     */
1304
    public function setFlags($flags){
1305
        $this->flags = $flags;
1306
1307
        return $this;
1308
    }
1309
1310
    /**
1311
     * Set the client
1312
     * @param $client
1313
     *
1314
     * @throws Exceptions\ConnectionFailedException
1315
     * @return $this
1316
     */
1317
    public function setClient($client){
1318
        $this->client = $client;
1319
        $this->client->openFolder($this->folder_path);
1320
1321
        return $this;
1322
    }
1323
1324
    /**
1325
     * Set the message number
1326
     * @param int $uid
1327
     *
1328
     * @throws Exceptions\ConnectionFailedException
1329
     * @throws Exceptions\RuntimeException
1330
     * @return $this
1331
     */
1332
    public function setUid($uid){
1333
        $this->uid = $uid;
1334
        $this->msgn = $this->client->getConnection()->getMessageNumber($this->uid);
1335
        $this->msglist = null;
1336
1337
        return $this;
1338
    }
1339
1340
    /**
1341
     * Set the message number
1342
     * @param $msgn
1343
     * @param null $msglist
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $msglist is correct as it would always require null to be passed?
Loading history...
1344
     *
1345
     * @throws Exceptions\ConnectionFailedException
1346
     * @throws Exceptions\RuntimeException
1347
     * @return $this
1348
     */
1349
    public function setMsgn($msgn, $msglist = null){
1350
        $this->msgn = $msgn;
1351
        $this->msglist = $msglist;
1352
        $this->uid = $this->client->getConnection()->getUid($this->msgn);
0 ignored issues
show
Bug introduced by
The method getUid() does not exist on Webklex\PHPIMAP\Connection\Protocols\Protocol. Since it exists in all sub-types, consider adding an abstract or default implementation to Webklex\PHPIMAP\Connection\Protocols\Protocol. ( Ignorable by Annotation )

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

1352
        $this->uid = $this->client->getConnection()->/** @scrutinizer ignore-call */ getUid($this->msgn);
Loading history...
1353
1354
        return $this;
1355
    }
1356
1357
    /**
1358
     * Get the current sequence type
1359
     *
1360
     * @return int
1361
     */
1362
    public function getSequence(){
1363
        return $this->sequence;
1364
    }
1365
1366
    /**
1367
     * Set the sequence type
1368
     *
1369
     * @return int
1370
     */
1371
    public function getSequenceId(){
1372
        return $this->sequence === IMAP::ST_UID ? $this->uid : $this->msgn;
1373
    }
1374
1375
    /**
1376
     * Set the sequence id
1377
     * @param $uid
1378
     * @param null $msglist
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $msglist is correct as it would always require null to be passed?
Loading history...
1379
     *
1380
     * @throws Exceptions\ConnectionFailedException
1381
     * @throws Exceptions\RuntimeException
1382
     */
1383
    public function setSequenceId($uid, $msglist = null){
1384
        if ($this->getSequence() === IMAP::ST_UID) {
1385
            $this->setUid($uid);
1386
            $this->setMsglist($msglist);
1387
        }else{
1388
            $this->setMsgn($uid, $msglist);
1389
        }
1390
    }
1391
}
1392