Completed
Push — master ( 1a7973...74fe4d )
by Malte
05:24 queued 02:30
created

Message::is()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 6
nc 5
nop 1
dl 0
loc 10
rs 8.8571
c 0
b 0
f 0
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\IMAP;
14
15
use Carbon\Carbon;
16
use Webklex\IMAP\Support\AttachmentCollection;
17
18
/**
19
 * Class Message
20
 *
21
 * @package Webklex\IMAP
22
 */
23
class Message {
24
25
    /**
26
     * Client instance
27
     *
28
     * @var Client
29
     */
30
    private $client = Client::class;
31
32
    /**
33
     * U ID
34
     *
35
     * @var integer
36
     */
37
    public $uid = '';
38
39
    /**
40
     * Fetch body options
41
     *
42
     * @var integer
43
     */
44
    public $fetch_options = null;
45
46
    /**
47
     * Fetch body options
48
     *
49
     * @var bool
50
     */
51
    public $fetch_body = null;
52
53
    /**
54
     * Fetch attachments options
55
     *
56
     * @var bool
57
     */
58
    public $fetch_attachment = null;
59
60
    /**
61
     * @var int $msglist
62
     */
63
    public $msglist = 1;
64
65
    /**
66
     * @var string $header
67
     */
68
    public $header = null;
69
70
    /**
71
     * @var null|object $header_info
72
     */
73
    public $header_info = null;
74
75
    /** @var null|string $raw_body */
76
    public $raw_body = null;
77
78
    /**
79
     * Message header components
80
     *
81
     * @var string  $message_id
82
     * @var mixed   $message_no
83
     * @var string  $subject
84
     * @var mixed   $references
85
     * @var mixed   $date
86
     * @var array   $from
87
     * @var array   $to
88
     * @var array   $cc
89
     * @var array   $bcc
90
     * @var array   $reply_to
91
     * @var string  $in_reply_to
92
     * @var array   $sender
93
     */
94
    public $message_id = '';
95
    public $message_no = null;
96
    public $subject = '';
97
    public $references = null;
98
    public $date = null;
99
    public $from = [];
100
    public $to = [];
101
    public $cc = [];
102
    public $bcc = [];
103
    public $reply_to = [];
104
    public $in_reply_to = '';
105
    public $sender = [];
106
107
    /**
108
     * Message body components
109
     *
110
     * @var array   $bodies
111
     * @var AttachmentCollection|array  $attachments
112
     */
113
    public $bodies = [];
114
    public $attachments = [];
115
116
    /**
117
     * Message const
118
     *
119
     * @const integer   TYPE_TEXT
120
     * @const integer   TYPE_MULTIPART
121
     *
122
     * @const integer   ENC_7BIT
123
     * @const integer   ENC_8BIT
124
     * @const integer   ENC_BINARY
125
     * @const integer   ENC_BASE64
126
     * @const integer   ENC_QUOTED_PRINTABLE
127
     * @const integer   ENC_OTHER
128
     */
129
    const TYPE_TEXT = 0;
130
    const TYPE_MULTIPART = 1;
131
132
    const ENC_7BIT = 0;
133
    const ENC_8BIT = 1;
134
    const ENC_BINARY = 2;
135
    const ENC_BASE64 = 3;
136
    const ENC_QUOTED_PRINTABLE = 4;
137
    const ENC_OTHER = 5;
138
139
    /**
140
     * Message constructor.
141
     *
142
     * @param integer       $uid
143
     * @param integer|null  $msglist
144
     * @param Client        $client
145
     * @param integer|null  $fetch_options
146
     * @param boolean       $fetch_body
147
     * @param boolean       $fetch_attachment
148
     */
149
    public function __construct($uid, $msglist, Client $client, $fetch_options = null, $fetch_body = false, $fetch_attachment = false) {
150
        $this->setFetchOption($fetch_options);
151
        $this->setFetchBodyOption($fetch_body);
152
        $this->setFetchAttachmentOption($fetch_attachment);
153
154
        $this->attachments = AttachmentCollection::make([]);
155
        
156
        $this->msglist = $msglist;
157
        $this->client = $client;
158
        $this->uid = ($this->fetch_options == FT_UID) ? $uid : imap_msgno($this->client->getConnection(), $uid);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_msgno() does only seem to accept resource, 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

158
        $this->uid = ($this->fetch_options == FT_UID) ? $uid : imap_msgno(/** @scrutinizer ignore-type */ $this->client->getConnection(), $uid);
Loading history...
159
        
160
        $this->parseHeader();
161
162
        if ($this->getFetchBodyOption() === true) {
163
            $this->parseBody();
164
        }
165
    }
166
167
    /**
168
     * Copy the current Messages to a mailbox
169
     *
170
     * @param $mailbox
171
     * @param int $options
172
     *
173
     * @return bool
174
     */
175
    public function copy($mailbox, $options = 0) {
176
        return imap_mail_copy($this->client->getConnection(), $this->msglist, $mailbox, $options);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_mail_copy() does only seem to accept resource, 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

176
        return imap_mail_copy(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->msglist, $mailbox, $options);
Loading history...
177
    }
178
179
    /**
180
     * Move the current Messages to a mailbox
181
     *
182
     * @param $mailbox
183
     * @param int $options
184
     *
185
     * @return bool
186
     */
187
    public function move($mailbox, $options = 0) {
188
        return imap_mail_move($this->client->getConnection(), $this->msglist, $mailbox, $options);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_mail_move() does only seem to accept resource, 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

188
        return imap_mail_move(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->msglist, $mailbox, $options);
Loading history...
189
    }
190
191
    /**
192
     * Check if the Message has a text body
193
     *
194
     * @return bool
195
     */
196
    public function hasTextBody() {
197
        return isset($this->bodies['text']);
198
    }
199
200
    /**
201
     * Get the Message text body
202
     *
203
     * @return mixed
204
     */
205
    public function getTextBody() {
206
        if (!isset($this->bodies['text'])) {
207
            return false;
208
        }
209
210
        return $this->bodies['text']->content;
211
    }
212
213
    /**
214
     * Check if the Message has a html body
215
     *
216
     * @return bool
217
     */
218
    public function hasHTMLBody() {
219
        return isset($this->bodies['html']);
220
    }
221
222
    /**
223
     * Get the Message html body
224
     *
225
     * @var bool $replaceImages
226
     *
227
     * @return mixed
228
     */
229
    public function getHTMLBody($replaceImages = false) {
230
        if (!isset($this->bodies['html'])) {
231
            return false;
232
        }
233
234
        $body = $this->bodies['html']->content;
235
        if ($replaceImages) {
236
            $this->attachments->each(function($oAttachment) use(&$body){
237
                if ($oAttachment->id && isset($oAttachment->img_src)) {
238
                    $body = str_replace('cid:'.$oAttachment->id, $oAttachment->img_src, $body);
239
                }
240
            });
241
        }
242
243
        return $body;
244
    }
245
246
    /**
247
     * Parse all defined headers
248
     *
249
     * @return void
250
     */
251
    private function parseHeader() {
252
        $this->header = $header = imap_fetchheader($this->client->getConnection(), $this->uid, $this->fetch_options);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_fetchheader() does only seem to accept resource, 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

252
        $this->header = $header = imap_fetchheader(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->uid, $this->fetch_options);
Loading history...
253
        if ($this->header) {
254
            $header = imap_rfc822_parse_headers($this->header);
255
        }
256
257
        if (property_exists($header, 'subject')) {
258
            $this->subject = imap_utf8($header->subject);
259
        }
260
        if (property_exists($header, 'date')) {
261
            $date = $header->date;
262
263
            /**
264
             * Exception handling for invalid dates
265
             * Will be extended in the future
266
             *
267
             * Currently known invalid formats:
268
             * ^ Datetime                                   ^ Problem                           ^ Cause                 
269
             * | Mon, 20 Nov 2017 20:31:31 +0800 (GMT+8:00) | Double timezone specification     | A Windows feature
270
             * |                                            | and invalid timezone (max 6 char) |
271
             * | 04 Jan 2018 10:12:47 UT                    | Missing letter "C"                | Unknown
272
             *
273
             * Please report any new invalid timestamps to [#45](https://github.com/Webklex/laravel-imap/issues/45)
274
             */
275
            try {
276
                $this->date = Carbon::parse($date);
277
            } catch (\Exception $e) {
278
                switch (true) {
279
                    case preg_match('/([A-Z]{2,3}\,\ [0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ \+[0-9]{4}\ \([A-Z]{2,3}\+[0-9]{1,2}\:[0-9]{1,2})\)+$/i', $date) > 0:
280
                        $array = explode('(', $date);
281
                        $array = array_reverse($array);
282
                        $date = trim(array_pop($array));
283
                        break;
284
                    case preg_match('/([0-9]{1,2}\ [A-Z]{2,3}\ [0-9]{4}\ [0-9]{1,2}\:[0-9]{1,2}\:[0-9]{1,2}\ UT)+$/i', $date) > 0:
285
                        $date .= 'C';
286
                        break;
287
                }
288
                $this->date = Carbon::parse($date);
289
            }
290
        }
291
292
        if (property_exists($header, 'from')) {
293
            $this->from = $this->parseAddresses($header->from);
294
        }
295
        if (property_exists($header, 'to')) {
296
            $this->to = $this->parseAddresses($header->to);
297
        }
298
        if (property_exists($header, 'cc')) {
299
            $this->cc = $this->parseAddresses($header->cc);
300
        }
301
        if (property_exists($header, 'bcc')) {
302
            $this->bcc = $this->parseAddresses($header->bcc);
303
        }
304
        if (property_exists($header, 'references')) {
305
            $this->references = $header->references;
306
        }
307
308
        if (property_exists($header, 'reply_to')) {
309
            $this->reply_to = $this->parseAddresses($header->reply_to);
310
        }
311
        if (property_exists($header, 'in_reply_to')) {
312
            $this->in_reply_to = str_replace(['<', '>'], '', $header->in_reply_to);
313
        }
314
        if (property_exists($header, 'sender')) {
315
            $this->sender = $this->parseAddresses($header->sender);
316
        }
317
318
        if (property_exists($header, 'message_id')) {
319
            $this->message_id = str_replace(['<', '>'], '', $header->message_id);
320
        }
321
        if (property_exists($header, 'Msgno')) {
322
            $messageNo = (int) trim($header->Msgno);
323
            $this->message_no = ($this->fetch_options == FT_UID) ? $messageNo : imap_msgno($this->client->getConnection(), $messageNo);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_msgno() does only seem to accept resource, 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

323
            $this->message_no = ($this->fetch_options == FT_UID) ? $messageNo : imap_msgno(/** @scrutinizer ignore-type */ $this->client->getConnection(), $messageNo);
Loading history...
324
        } else {
325
            $this->message_no = imap_msgno($this->client->getConnection(), $this->getUid());
326
        }
327
    }
328
329
    /**
330
     * Get the current Message header info
331
     *
332
     * @return object
333
     */
334
    public function getHeaderInfo() {
335
        if ($this->header_info == null) {
336
            $this->header_info =
337
            $this->header_info = imap_headerinfo($this->client->getConnection(), $this->getMessageNo()); ;
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $stream_id of imap_headerinfo() does only seem to accept resource, 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

337
            $this->header_info = imap_headerinfo(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->getMessageNo()); ;
Loading history...
338
        }
339
340
        return $this->header_info;
341
    }
342
343
    /**
344
     * Parse Addresses
345
     *
346
     * @param $list
347
     *
348
     * @return array
349
     */
350
    private function parseAddresses($list) {
351
        $addresses = [];
352
353
        foreach ($list as $item) {
354
            $address = (object) $item;
355
356
            if (!property_exists($address, 'mailbox')) {
357
                $address->mailbox = false;
358
            }
359
            if (!property_exists($address, 'host')) {
360
                $address->host = false;
361
            }
362
            if (!property_exists($address, 'personal')) {
363
                $address->personal = false;
364
            }
365
366
            $address->personal = imap_utf8($address->personal);
367
368
            $address->mail = ($address->mailbox && $address->host) ? $address->mailbox.'@'.$address->host : false;
369
            $address->full = ($address->personal) ? $address->personal.' <'.$address->mail.'>' : $address->mail;
0 ignored issues
show
Bug introduced by
Are you sure $address->mail of type false|string can be used in concatenation? ( Ignorable by Annotation )

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

369
            $address->full = ($address->personal) ? $address->personal.' <'./** @scrutinizer ignore-type */ $address->mail.'>' : $address->mail;
Loading history...
370
371
            $addresses[] = $address;
372
        }
373
374
        return $addresses;
375
    }
376
377
    /**
378
     * Parse the Message body
379
     *
380
     * @return $this
381
     */
382
    public function parseBody() {
383
        $structure = imap_fetchstructure($this->client->getConnection(), $this->uid, $this->fetch_options);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_fetchstructure() does only seem to accept resource, 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

383
        $structure = imap_fetchstructure(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->uid, $this->fetch_options);
Loading history...
384
385
        $this->fetchStructure($structure);
386
387
        return $this;
388
    }
389
390
    /**
391
     * Fetch the Message structure
392
     *
393
     * @param $structure
394
     * @param mixed $partNumber
395
     */
396
    private function fetchStructure($structure, $partNumber = null) {
397
        if ($structure->type == self::TYPE_TEXT &&
398
            ($structure->ifdisposition == 0 ||
399
                ($structure->ifdisposition == 1 && !isset($structure->parts) && $partNumber == null)
400
            )
401
        ) {
402
            if ($structure->subtype == "PLAIN") {
403
                if (!$partNumber) {
404
                    $partNumber = 1;
405
                }
406
407
                $encoding = $this->getEncoding($structure);
408
409
                $content = imap_fetchbody($this->client->getConnection(), $this->uid, $partNumber, $this->fetch_options);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_fetchbody() does only seem to accept resource, 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

409
                $content = imap_fetchbody(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->uid, $partNumber, $this->fetch_options);
Loading history...
410
                $content = $this->decodeString($content, $structure->encoding);
411
                $content = $this->convertEncoding($content, $encoding);
412
413
                $body = new \stdClass;
414
                $body->type = "text";
415
                $body->content = $content;
416
417
                $this->bodies['text'] = $body;
418
419
                $this->fetchAttachment($structure, $partNumber);
420
421
            } elseif ($structure->subtype == "HTML") {
422
                if (!$partNumber) {
423
                    $partNumber = 1;
424
                }
425
426
                $encoding = $this->getEncoding($structure);
427
428
                $content = imap_fetchbody($this->client->getConnection(), $this->uid, $partNumber, $this->fetch_options);
429
                $content = $this->decodeString($content, $structure->encoding);
430
                $content = $this->convertEncoding($content, $encoding);
431
432
                $body = new \stdClass;
433
                $body->type = "html";
434
                $body->content = $content;
435
436
                $this->bodies['html'] = $body;
437
            }
438
        } elseif ($structure->type == self::TYPE_MULTIPART) {
439
            foreach ($structure->parts as $index => $subStruct) {
440
                $prefix = "";
441
                if ($partNumber) {
442
                    $prefix = $partNumber.".";
443
                }
444
                $this->fetchStructure($subStruct, $prefix.($index + 1));
445
            }
446
        } else {
447
            if ($this->getFetchAttachmentOption() === true) {
448
                $this->fetchAttachment($structure, $partNumber);
449
            }
450
        }
451
    }
452
453
    /**
454
     * Fetch the Message attachment
455
     *
456
     * @param object $structure
457
     * @param mixed  $partNumber
458
     */
459
    protected function fetchAttachment($structure, $partNumber) {
460
461
        $oAttachment = new Attachment($this, $structure, $partNumber);
462
463
        if ($oAttachment->getName() !== null) {
464
            if ($oAttachment->getId() !== null) {
465
                $this->attachments->put($oAttachment->getId(), $oAttachment);
466
            } else {
467
                $this->attachments->push($oAttachment);
468
            }
469
        }
470
    }
471
472
    /**
473
     * Fail proof setter for $fetch_option
474
     *
475
     * @param $option
476
     *
477
     * @return $this
478
     */
479
    public function setFetchOption($option) {
480
        if (is_long($option) === true) {
481
            $this->fetch_options = $option;
482
        } elseif (is_null($option) === true) {
483
            $config = config('imap.options.fetch', FT_UID);
484
            $this->fetch_options = is_long($config) ? $config : 1;
485
        }
486
487
        return $this;
488
    }
489
490
    /**
491
     * Fail proof setter for $fetch_body
492
     *
493
     * @param $option
494
     *
495
     * @return $this
496
     */
497
    public function setFetchBodyOption($option) {
498
        if (is_bool($option)) {
499
            $this->fetch_body = $option;
500
        } elseif (is_null($option)) {
501
            $config = config('imap.options.fetch_body', true);
502
            $this->fetch_body = is_bool($config) ? $config : true;
503
        }
504
505
        return $this;
506
    }
507
508
    /**
509
     * Fail proof setter for $fetch_attachment
510
     *
511
     * @param $option
512
     *
513
     * @return $this
514
     */
515
    public function setFetchAttachmentOption($option) {
516
        if (is_bool($option)) {
517
            $this->fetch_attachment = $option;
518
        } elseif (is_null($option)) {
519
            $config = config('imap.options.fetch_attachment', true);
520
            $this->fetch_attachment = is_bool($config) ? $config : true;
521
        }
522
523
        return $this;
524
    }
525
526
    /**
527
     * Decode a given string
528
     *
529
     * @param $string
530
     * @param $encoding
531
     *
532
     * @return string
533
     */
534
    public function decodeString($string, $encoding) {
535
        switch ($encoding) {
536
            case self::ENC_7BIT:
537
                return $string;
538
            case self::ENC_8BIT:
539
                return quoted_printable_decode(imap_8bit($string));
540
            case self::ENC_BINARY:
541
                return imap_binary($string);
542
            case self::ENC_BASE64:
543
                return imap_base64($string);
544
            case self::ENC_QUOTED_PRINTABLE:
545
                return quoted_printable_decode($string);
546
            case self::ENC_OTHER:
547
                return $string;
548
            default:
549
                return $string;
550
        }
551
    }
552
553
    /**
554
     * Convert the encoding
555
     *
556
     * @param $str
557
     * @param string $from
558
     * @param string $to
559
     *
560
     * @return mixed|string
561
     */
562
    private function convertEncoding($str, $from = "ISO-8859-2", $to = "UTF-8") {
563
        if (function_exists('iconv') && $from != 'UTF-7' && $to != 'UTF-7') {
564
            return iconv($from, $to.'//IGNORE', $str);
565
        } else {
566
            if (!$from) {
567
                return mb_convert_encoding($str, $to);
568
            }
569
            return mb_convert_encoding($str, $to, $from);
570
        }
571
    }
572
573
    /**
574
     * Get the encoding of a given abject
575
     *
576
     * @param object $structure
577
     *
578
     * @return null|string
579
     */
580
    private function getEncoding($structure) {
581
        if (property_exists($structure, 'parameters')) {
582
            foreach ($structure->parameters as $parameter) {
583
                if (strtolower($parameter->attribute) == "charset") {
584
                    return strtoupper($parameter->value);
585
                }
586
            }
587
        }
588
        return null;
589
    }
590
591
    /**
592
     * Find the folder containing this message.
593
     *
594
     * @param null|Folder $folder where to start searching from (top-level inbox by default)
595
     * @return null|Folder
596
     */
597
    public function getContainingFolder(Folder $folder = null)
598
    {
599
        $folder = $folder ?: $this->client->getFolders()->first();
600
        $this->client->checkConnection();
601
602
        // Try finding the message by uid in the current folder
603
        $client = new Client;
604
        $client->openFolder($folder);
605
        $uidMatches = imap_fetch_overview($client->getConnection(), $this->uid, $this->fetch_options);
0 ignored issues
show
Bug introduced by
It seems like $client->getConnection() can also be of type true; however, parameter $imap_stream of imap_fetch_overview() does only seem to accept resource, 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

605
        $uidMatches = imap_fetch_overview(/** @scrutinizer ignore-type */ $client->getConnection(), $this->uid, $this->fetch_options);
Loading history...
606
        $uidMatch = count($uidMatches)
607
            ? new Message($uidMatches[0]->uid, $uidMatches[0]->msgno, $client)
608
            : null;
609
        $client->disconnect();
610
611
        // imap_fetch_overview() on a parent folder will return the matching message
612
        // even when the message is in a child folder so we need to recursively
613
        // search the children
614
        foreach ($folder->children as $child) {
615
            $childFolder = $this->getContainingFolder($child);
616
617
            if ($childFolder) {
618
                return $childFolder;
619
            }
620
        }
621
622
        // before returning the parent
623
        if ($this->is($uidMatch)) {
624
            return $folder;
625
        }
626
627
        // or signalling that the message was not found in any folder
628
        return null;
629
    }
630
631
    /**
632
     * Move the Message into an other Folder
633
     *
634
     * @param string  $mailbox
635
     * @param integer $options [optional]
636
     *
637
     * @return bool
638
     */
639
    public function moveToFolder($mailbox = 'INBOX', $options = 0) {
640
        $this->client->createFolder($mailbox);
641
642
        return imap_mail_move($this->client->getConnection(), $this->msglist, $mailbox, $options);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type true; however, parameter $imap_stream of imap_mail_move() does only seem to accept resource, 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

642
        return imap_mail_move(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->msglist, $mailbox, $options);
Loading history...
643
    }
644
645
    /**
646
     * Delete the current Message
647
     *
648
     * @return bool
649
     */
650
    public function delete() {
651
        $status = imap_delete($this->client->getConnection(), $this->uid, $this->fetch_options);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_delete() does only seem to accept resource, 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

651
        $status = imap_delete(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->uid, $this->fetch_options);
Loading history...
652
        $this->client->expunge();
653
654
        return $status;
655
    }
656
657
    /**
658
     * Restore a deleted Message
659
     *
660
     * @return bool
661
     */
662
    public function restore() {
663
        return imap_undelete($this->client->getConnection(), $this->message_no);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_undelete() does only seem to accept resource, 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

663
        return imap_undelete(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->message_no);
Loading history...
664
    }
665
666
    /**
667
     * Get all message attachments.
668
     *
669
     * @return AttachmentCollection
670
     */
671
    public function getAttachments() {
672
        return $this->attachments;
673
    }
674
675
    /**
676
     * Checks if there are any attachments present
677
     *
678
     * @return boolean
679
     */
680
    public function hasAttachments() {
681
        return $this->attachments->isEmpty() === false;
682
    }
683
684
    /**
685
     * Set a given flag
686
     * @param string|array $flag
687
     *
688
     * @return bool
689
     */
690
    public function setFlag($flag) {
691
        $flag = "\\".trim(is_array($flag) ? implode(" \\", $flag) : $flag);
692
        return imap_setflag_full($this->client->getConnection(), $this->getUid(), $flag, SE_UID);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_setflag_full() does only seem to accept resource, 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

692
        return imap_setflag_full(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->getUid(), $flag, SE_UID);
Loading history...
693
    }
694
695
    /**
696
     * Unset a given flag
697
     * @param string|array $flag
698
     *
699
     * @return bool
700
     */
701
    public function unsetFlag($flag) {
702
        $flag = "\\".trim(is_array($flag) ? implode(" \\", $flag) : $flag);
703
        return imap_clearflag_full($this->client->getConnection(), $this->getUid(), "\\$flag", SE_UID);
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_clearflag_full() does only seem to accept resource, 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

703
        return imap_clearflag_full(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->getUid(), "\\$flag", SE_UID);
Loading history...
704
    }
705
706
    /**
707
     * @return null|object|string
708
     */
709
    public function getRawBody() {
710
        if ($this->raw_body === null) {
711
            $this->raw_body = imap_fetchbody($this->client->getConnection(), $this->getMessageNo(), '');
0 ignored issues
show
Bug introduced by
It seems like $this->client->getConnection() can also be of type boolean; however, parameter $imap_stream of imap_fetchbody() does only seem to accept resource, 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

711
            $this->raw_body = imap_fetchbody(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->getMessageNo(), '');
Loading history...
712
        }
713
714
        return $this->raw_body;
715
    }
716
717
    /**
718
     * @return string
719
     */
720
    public function getHeader() {
721
        return $this->header;
722
    }
723
724
    /**
725
     * @return Client
726
     */
727
    public function getClient() {
728
        return $this->client;
729
    }
730
731
    /**
732
     * @return integer
733
     */
734
    public function getUid() {
735
        return $this->uid;
736
    }
737
738
    /**
739
     * @return integer
740
     */
741
    public function getFetchOptions() {
742
        return $this->fetch_options;
743
    }
744
745
    /**
746
     * @return boolean
747
     */
748
    public function getFetchBodyOption() {
749
        return $this->fetch_body;
750
    }
751
752
    /**
753
     * @return boolean
754
     */
755
    public function getFetchAttachmentOption() {
756
        return $this->fetch_attachment;
757
    }
758
759
    /**
760
     * @return int
761
     */
762
    public function getMsglist() {
763
        return $this->msglist;
764
    }
765
766
    /**
767
     * @return mixed
768
     */
769
    public function getMessageId() {
770
        return $this->message_id;
771
    }
772
773
    /**
774
     * @return int
775
     */
776
    public function getMessageNo() {
777
        return $this->message_no;
778
    }
779
780
    /**
781
     * @return string
782
     */
783
    public function getSubject() {
784
        return $this->subject;
785
    }
786
787
    /**
788
     * @return mixed
789
     */
790
    public function getReferences() {
791
        return $this->references;
792
    }
793
794
    /**
795
     * @return Carbon|null
796
     */
797
    public function getDate() {
798
        return $this->date;
799
    }
800
801
    /**
802
     * @return array
803
     */
804
    public function getFrom() {
805
        return $this->from;
806
    }
807
808
    /**
809
     * @return array
810
     */
811
    public function getTo() {
812
        return $this->to;
813
    }
814
815
    /**
816
     * @return array
817
     */
818
    public function getCc() {
819
        return $this->cc;
820
    }
821
822
    /**
823
     * @return array
824
     */
825
    public function getBcc() {
826
        return $this->bcc;
827
    }
828
829
    /**
830
     * @return array
831
     */
832
    public function getReplyTo() {
833
        return $this->reply_to;
834
    }
835
    
836
    /**
837
     * @return string
838
     */
839
    public function getInReplyTo() {
840
        return $this->in_reply_to;
841
    }
842
843
    /**
844
     * @return array
845
     */
846
    public function getSender() {
847
        return $this->sender;
848
    }
849
850
    /**
851
     * @return mixed
852
     */
853
    public function getBodies() {
854
        return $this->bodies;
855
    }
856
857
    /**
858
     * Does this message match another one?
859
     *
860
     * A match means same uid, message id, subject and date/time.
861
     *
862
     * @param  null|static $message
863
     * @return boolean
864
     */
865
    public function is(Message $message = null)
866
    {
867
        if (is_null($message)) {
868
            return false;
869
        }
870
871
        return $this->uid == $message->uid
872
            && $this->message_id == $message->message_id
873
            && $this->subject == $message->subject
874
            && $this->date->eq($message->date);
875
    }
876
}
877