Passed
Push — master ( 10b243...00ae18 )
by Malte
02:20
created

Folder   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 387
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 53
dl 0
loc 387
rs 10
c 0
b 0
f 0
wmc 22

16 Methods

Rating   Name   Duplication   Size   Complexity  
A decodeName() 0 3 1
A getMessage() 0 6 2
A move() 0 5 1
A setChildren() 0 4 1
A appendMessage() 0 2 1
A getStatus() 0 2 1
A searchMessages() 0 6 1
A __construct() 0 9 1
A hasChildren() 0 2 1
A delete() 0 5 1
A parseAttributes() 0 6 6
A getClient() 0 2 1
A query() 0 5 1
A getMessages() 0 5 1
A getUnseenMessages() 0 2 1
A getSimpleName() 0 4 1
1
<?php
2
/*
3
* File:     Folder.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 Webklex\IMAP\Exceptions\GetMessagesFailedException;
16
use Webklex\IMAP\Exceptions\MessageSearchValidationException;
17
use Webklex\IMAP\Query\WhereQuery;
18
use Webklex\IMAP\Support\FolderCollection;
19
use Webklex\IMAP\Support\MessageCollection;
20
21
/**
22
 * Class Folder
23
 *
24
 * @package Webklex\IMAP
25
 */
26
class Folder {
27
28
    /**
29
     * Client instance
30
     *
31
     * @var \Webklex\IMAP\Client
32
     */
33
    protected $client;
34
35
    /**
36
     * Folder full path
37
     *
38
     * @var string
39
     */
40
    public $path;
41
42
    /**
43
     * Folder name
44
     *
45
     * @var string
46
     */
47
    public $name;
48
49
    /**
50
     * Folder fullname
51
     *
52
     * @var string
53
     */
54
    public $fullName;
55
56
    /**
57
     * Children folders
58
     *
59
     * @var FolderCollection|array
60
     */
61
    public $children = [];
62
63
    /**
64
     * Delimiter for folder
65
     *
66
     * @var string
67
     */
68
    public $delimiter;
69
70
    /**
71
     * Indicates if folder can't containg any "children".
72
     * CreateFolder won't work on this folder.
73
     *
74
     * @var boolean
75
     */
76
    public $no_inferiors;
77
78
    /**
79
     * Indicates if folder is only container, not a mailbox - you can't open it.
80
     *
81
     * @var boolean
82
     */
83
    public $no_select;
84
85
    /**
86
     * Indicates if folder is marked. This means that it may contain new messages since the last time it was checked.
87
     * Not provided by all IMAP servers.
88
     *
89
     * @var boolean
90
     */
91
    public $marked;
92
93
    /**
94
     * Indicates if folder containg any "children".
95
     * Not provided by all IMAP servers.
96
     *
97
     * @var boolean
98
     */
99
    public $has_children;
100
101
    /**
102
     * Indicates if folder refers to other.
103
     * Not provided by all IMAP servers.
104
     *
105
     * @var boolean
106
     */
107
    public $referal;
108
109
    /**
110
     * Folder constructor.
111
     *
112
     * @param \Webklex\IMAP\Client $client
113
     *
114
     * @param object $folder
115
     */
116
    public function __construct(Client $client, $folder) {
117
        $this->client = $client;
118
119
        $this->delimiter = $folder->delimiter;
120
        $this->path      = $folder->name;
121
        $this->fullName  = $this->decodeName($folder->name);
122
        $this->name      = $this->getSimpleName($this->delimiter, $this->fullName);
123
124
        $this->parseAttributes($folder->attributes);
125
    }
126
127
    /**
128
     * Get a new search query instance
129
     * @param string $charset
130
     *
131
     * @return WhereQuery
132
     */
133
    public function query($charset = 'UTF-8'){
134
        $this->getClient()->checkConnection();
135
        $this->getClient()->openFolder($this);
136
137
        return new WhereQuery($this->getClient(), $charset);
138
    }
139
140
    /**
141
     * Determine if folder has children.
142
     *
143
     * @return bool
144
     */
145
    public function hasChildren() {
146
        return $this->has_children;
147
    }
148
149
    /**
150
     * Set children.
151
     *
152
     * @param FolderCollection|array $children
153
     *
154
     * @return self
155
     */
156
    public function setChildren($children = []) {
157
        $this->children = $children;
158
159
        return $this;
160
    }
161
162
    /**
163
     * Get a specific message by UID
164
     *
165
     * @param integer      $uid     Please note that the uid is not unique and can change
166
     * @param integer|null $msglist
167
     * @param integer|null $fetch_options
168
     * @param boolean      $fetch_body
169
     * @param boolean      $fetch_attachment
170
     * @param boolean      $fetch_flags
171
     *
172
     * @return Message|null
173
     */
174
    public function getMessage($uid, $msglist = null, $fetch_options = null, $fetch_body = false, $fetch_attachment = false, $fetch_flags = false) {
175
        if (imap_msgno($this->getClient()->getConnection(), $uid) > 0) {
0 ignored issues
show
Bug introduced by
It seems like $this->getClient()->getConnection() can also be of type true; 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

175
        if (imap_msgno(/** @scrutinizer ignore-type */ $this->getClient()->getConnection(), $uid) > 0) {
Loading history...
176
            return new Message($uid, $msglist, $this->getClient(), $fetch_options, $fetch_body, $fetch_attachment, $fetch_flags);
177
        }
178
179
        return null;
180
    }
181
182
    /**
183
     * Get all messages
184
     *
185
     * @param string    $criteria
186
     * @param int|null  $fetch_options
187
     * @param boolean   $fetch_body
188
     * @param boolean   $fetch_attachment
189
     * @param boolean   $fetch_flags
190
     * @param int|null  $limit
191
     * @param int       $page
192
     * @param string    $charset
193
     *
194
     * @return MessageCollection
195
     * @throws Exceptions\ConnectionFailedException
196
     * @throws GetMessagesFailedException
197
     * @throws MessageSearchValidationException
198
     */
199
    public function getMessages($criteria = 'ALL', $fetch_options = null, $fetch_body = true, $fetch_attachment = true, $fetch_flags = false, $limit = null, $page = 1, $charset = "UTF-8") {
200
201
        return $this->query($charset)->where($criteria)->setFetchOptions($fetch_options)->setFetchBody($fetch_body)
0 ignored issues
show
Bug introduced by
It seems like $fetch_options can also be of type integer; however, parameter $fetch_options of Webklex\IMAP\Query\Query::setFetchOptions() does only seem to accept boolean, 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

201
        return $this->query($charset)->where($criteria)->setFetchOptions(/** @scrutinizer ignore-type */ $fetch_options)->setFetchBody($fetch_body)
Loading history...
202
            ->setFetchAttachment($fetch_attachment)->setFetchFlags($fetch_flags)
0 ignored issues
show
Bug introduced by
$fetch_flags of type boolean is incompatible with the type integer expected by parameter $fetch_flags of Webklex\IMAP\Query\Query::setFetchFlags(). ( Ignorable by Annotation )

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

202
            ->setFetchAttachment($fetch_attachment)->setFetchFlags(/** @scrutinizer ignore-type */ $fetch_flags)
Loading history...
203
            ->limit($limit, $page)->get();
204
    }
205
206
    /**
207
     * Get all unseen messages
208
     *
209
     * @param string    $criteria
210
     * @param int|null  $fetch_options
211
     * @param boolean   $fetch_body
212
     * @param boolean   $fetch_attachment
213
     * @param boolean   $fetch_flags
214
     * @param int|null  $limit
215
     * @param int       $page
216
     * @param string    $charset
217
     *
218
     * @return MessageCollection
219
     * @throws Exceptions\ConnectionFailedException
220
     * @throws GetMessagesFailedException
221
     * @throws MessageSearchValidationException
222
     *
223
     * @deprecated 1.0.5:2.0.0 No longer needed. Use Folder::getMessages('UNSEEN') instead
224
     * @see Folder::getMessages()
225
     */
226
    public function getUnseenMessages($criteria = 'UNSEEN', $fetch_options = null, $fetch_body = true, $fetch_attachment = true, $fetch_flags = false, $limit = null, $page = 1, $charset = "UTF-8") {
227
        return $this->getMessages($criteria, $fetch_options, $fetch_body, $fetch_attachment, $fetch_flags, $limit, $page, $charset);
228
    }
229
230
    /**
231
     * Search messages by a given search criteria
232
     *
233
     * @param array   $where  Is a two dimensional array where each array represents a criteria set:
234
     *                        ---------------------------------------------------------------------------------------
235
     *                        The following sample would search for all messages received from [email protected] or
236
     *                        contain the text "Hello world!":
237
     *                        [['FROM' => '[email protected]'],[' TEXT' => 'Hello world!']]
238
     *                        ---------------------------------------------------------------------------------------
239
     *                        The following sample would search for all messages received since march 15 2018:
240
     *                        [['SINCE' => Carbon::parse('15.03.2018')]]
241
     *                        ---------------------------------------------------------------------------------------
242
     *                        The following sample would search for all flagged messages:
243
     *                        [['FLAGGED']]
244
     *                        ---------------------------------------------------------------------------------------
245
     * @param int|null  $fetch_options
246
     * @param boolean   $fetch_body
247
     * @param boolean   $fetch_attachment
248
     * @param boolean   $fetch_flags
249
     * @param int|null  $limit
250
     * @param int       $page
251
     * @param string    $charset
252
     *
253
     * @return MessageCollection
254
     *
255
     * @throws Exceptions\ConnectionFailedException
256
     * @throws GetMessagesFailedException
257
     * @throws MessageSearchValidationException
258
     *
259
     * @doc http://php.net/manual/en/function.imap-search.php
260
     *      imap_search() only supports IMAP2 search criterias, because the function mail_criteria() (from c-client lib)
261
     *      is used in ext/imap/php_imap.c for parsing the search string.
262
     *      IMAP2 search criteria is defined in RFC 1176, section "tag SEARCH search_criteria".
263
     *
264
     *      https://tools.ietf.org/html/rfc1176 - INTERACTIVE MAIL ACCESS PROTOCOL - VERSION 2
265
     *      https://tools.ietf.org/html/rfc1064 - INTERACTIVE MAIL ACCESS PROTOCOL - VERSION 2
266
     *      https://tools.ietf.org/html/rfc822  - STANDARD FOR THE FORMAT OF ARPA INTERNET TEXT MESSAGES
267
     *      Date and time example from RFC822:
268
     *      date-time   =  [ day "," ] date time        ; dd mm yy
269
     *                                                  ;  hh:mm:ss zzz
270
     *
271
     *      day         =  "Mon"  / "Tue" /  "Wed"  / "Thu" /  "Fri"  / "Sat" /  "Sun"
272
     *
273
     *      date        =  1*2DIGIT month 2DIGIT        ; day month year
274
     *                                                  ;  e.g. 20 Jun 82
275
     *
276
     *      month       =  "Jan"  /  "Feb" /  "Mar"  /  "Apr" /  "May"  /  "Jun" /  "Jul"  /  "Aug" /  "Sep"  /  "Oct" /  "Nov"  /  "Dec"
277
     *
278
     *      time        =  hour zone                    ; ANSI and Military
279
     *
280
     *      hour        =  2DIGIT ":" 2DIGIT [":" 2DIGIT] ; 00:00:00 - 23:59:59
281
     *
282
     *      zone        =  "UT"  / "GMT"         ; Universal Time
283
     *                                           ; North American : UT
284
     *                  =  "EST" / "EDT"         ;  Eastern:  - 5/ - 4
285
     *                  =  "CST" / "CDT"         ;  Central:  - 6/ - 5
286
     *                  =  "MST" / "MDT"         ;  Mountain: - 7/ - 6
287
     *                  =  "PST" / "PDT"         ;  Pacific:  - 8/ - 7
288
     *                  =  1ALPHA                ; Military: Z = UT;
289
     *                                           ;  A:-1; (J not used)
290
     *                                           ;  M:-12; N:+1; Y:+12
291
     *                  / ( ("+" / "-") 4DIGIT ) ; Local differential
292
     *                                           ;  hours+min. (HHMM)
293
     *
294
     * @deprecated 1.2.1:2.0.0 No longer needed. Use Folder::query() instead
295
     * @see Folder::query()
296
     */
297
    public function searchMessages(array $where, $fetch_options = null, $fetch_body = true,  $fetch_attachment = true, $fetch_flags = false, $limit = null, $page = 1, $charset = "UTF-8") {
298
        $this->getClient()->checkConnection();
299
300
        return $this->query($charset)->where($where)->setFetchOptions($fetch_options)->setFetchBody($fetch_body)
0 ignored issues
show
Bug introduced by
It seems like $fetch_options can also be of type integer; however, parameter $fetch_options of Webklex\IMAP\Query\Query::setFetchOptions() does only seem to accept boolean, 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

300
        return $this->query($charset)->where($where)->setFetchOptions(/** @scrutinizer ignore-type */ $fetch_options)->setFetchBody($fetch_body)
Loading history...
301
            ->setFetchAttachment($fetch_attachment)->setFetchFlags($fetch_flags)
0 ignored issues
show
Bug introduced by
$fetch_flags of type boolean is incompatible with the type integer expected by parameter $fetch_flags of Webklex\IMAP\Query\Query::setFetchFlags(). ( Ignorable by Annotation )

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

301
            ->setFetchAttachment($fetch_attachment)->setFetchFlags(/** @scrutinizer ignore-type */ $fetch_flags)
Loading history...
302
            ->limit($limit, $page)->get();
303
304
    }
305
306
    /**
307
     * Decode name.
308
     * It converts UTF7-IMAP encoding to UTF-8.
309
     *
310
     * @param $name
311
     *
312
     * @return mixed|string
313
     */
314
    protected function decodeName($name) {
315
        preg_match('#\{(.*)\}(.*)#', $name, $preg);
316
        return mb_convert_encoding($preg[2], "UTF-8", "UTF7-IMAP");
317
    }
318
319
    /**
320
     * Get simple name (without parent folders).
321
     *
322
     * @param $delimiter
323
     * @param $fullName
324
     *
325
     * @return mixed
326
     */
327
    protected function getSimpleName($delimiter, $fullName) {
328
        $arr = explode($delimiter, $fullName);
329
330
        return end($arr);
331
    }
332
333
    /**
334
     * Parse attributes and set it to object properties.
335
     *
336
     * @param $attributes
337
     */
338
    protected function parseAttributes($attributes) {
339
        $this->no_inferiors = ($attributes & LATT_NOINFERIORS) ? true : false;
340
        $this->no_select    = ($attributes & LATT_NOSELECT) ? true : false;
341
        $this->marked       = ($attributes & LATT_MARKED) ? true : false;
342
        $this->referal      = ($attributes & LATT_REFERRAL) ? true : false;
343
        $this->has_children = ($attributes & LATT_HASCHILDREN) ? true : false;
344
    }
345
346
    /**
347
     * Delete the current Mailbox
348
     *
349
     * @return bool
350
     *
351
     * @throws Exceptions\ConnectionFailedException
352
     */
353
    public function delete() {
354
        $status = imap_deletemailbox($this->client->getConnection(), $this->path);
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_deletemailbox() 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

354
        $status = imap_deletemailbox(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path);
Loading history...
355
        $this->client->expunge();
356
357
        return $status;
358
    }
359
360
    /**
361
     * Move or Rename the current Mailbox
362
     *
363
     * @param string $target_mailbox
364
     *
365
     * @return bool
366
     *
367
     * @throws Exceptions\ConnectionFailedException
368
     */
369
    public function move($target_mailbox) {
370
        $status = imap_renamemailbox($this->client->getConnection(), $this->path, $target_mailbox);
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_renamemailbox() 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

370
        $status = imap_renamemailbox(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $target_mailbox);
Loading history...
371
        $this->client->expunge();
372
373
        return $status;
374
    }
375
376
    /**
377
     * Returns status information on a mailbox
378
     *
379
     * @param integer   $options
380
     *                  SA_MESSAGES     - set $status->messages to the number of messages in the mailbox
381
     *                  SA_RECENT       - set $status->recent to the number of recent messages in the mailbox
382
     *                  SA_UNSEEN       - set $status->unseen to the number of unseen (new) messages in the mailbox
383
     *                  SA_UIDNEXT      - set $status->uidnext to the next uid to be used in the mailbox
384
     *                  SA_UIDVALIDITY  - set $status->uidvalidity to a constant that changes when uids for the mailbox may no longer be valid
385
     *                  SA_ALL          - set all of the above
386
     *
387
     * @return object
388
     */
389
    public function getStatus($options) {
390
        return imap_status($this->client->getConnection(), $this->path, $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_status() 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

390
        return imap_status(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $options);
Loading history...
391
    }
392
393
    /**
394
     * Append a string message to the current mailbox
395
     *
396
     * @param string $message
397
     * @param string $options
398
     * @param string $internal_date
399
     *
400
     * @return bool
401
     */
402
    public function appendMessage($message, $options = null, $internal_date = null) {
403
        return imap_append($this->client->getConnection(), $this->path, $message, $options, $internal_date);
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_append() 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

403
        return imap_append(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $message, $options, $internal_date);
Loading history...
404
    }
405
406
    /**
407
     * Get the current Client instance
408
     *
409
     * @return Client
410
     */
411
    public function getClient() {
412
        return $this->client;
413
    }
414
}
415