Passed
Push — master ( b29af0...6d200b )
by Malte
03:13
created

Folder::searchMessages()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 8
dl 0
loc 6
rs 10
c 0
b 0
f 0

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:     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 $structure
115
     */
116
    public function __construct(Client $client, $structure) {
117
        $this->client = $client;
118
119
        $this->setDelimiter($structure->delimiter);
120
        $this->path      = $structure->name;
121
        $this->fullName  = $this->decodeName($structure->name);
122
        $this->name      = $this->getSimpleName($this->delimiter, $this->fullName);
123
124
        $this->parseAttributes($structure->attributes);
125
    }
126
127
    /**
128
     * Get a new search query instance
129
     * @param string $charset
130
     *
131
     * @return WhereQuery
132
     * @throws Exceptions\ConnectionFailedException
133
     */
134
    public function query($charset = 'UTF-8'){
135
        $this->getClient()->checkConnection();
136
        $this->getClient()->openFolder($this);
137
138
        return new WhereQuery($this->getClient(), $charset);
139
    }
140
141
    /**
142
     * @inheritdoc self::query($charset = 'UTF-8')
143
     * @throws Exceptions\ConnectionFailedException
144
     */
145
    public function search($charset = 'UTF-8'){
146
        return $this->query($charset);
147
    }
148
149
    /**
150
     * @inheritdoc self::query($charset = 'UTF-8')
151
     * @throws Exceptions\ConnectionFailedException
152
     */
153
    public function messages($charset = 'UTF-8'){
154
        return $this->query($charset);
155
    }
156
157
    /**
158
     * Determine if folder has children.
159
     *
160
     * @return bool
161
     */
162
    public function hasChildren() {
163
        return $this->has_children;
164
    }
165
166
    /**
167
     * Set children.
168
     *
169
     * @param FolderCollection|array $children
170
     *
171
     * @return self
172
     */
173
    public function setChildren($children = []) {
174
        $this->children = $children;
175
176
        return $this;
177
    }
178
179
    /**
180
     * Get a specific message by UID
181
     *
182
     * @param integer      $uid     Please note that the uid is not unique and can change
183
     * @param integer|null $msglist
184
     * @param integer|null $fetch_options
185
     * @param boolean      $fetch_body
186
     * @param boolean      $fetch_attachment
187
     * @param boolean      $fetch_flags
188
     *
189
     * @return Message|null
190
     *
191
     * @throws Exceptions\ConnectionFailedException
192
     * @throws Exceptions\InvalidWhereQueryCriteriaException
193
     * @throws GetMessagesFailedException
194
     * @throws MessageSearchValidationException
195
     */
196
    public function getMessage($uid, $msglist = null, $fetch_options = null, $fetch_body = false, $fetch_attachment = false, $fetch_flags = true) {
197
        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

197
        if (imap_msgno(/** @scrutinizer ignore-type */ $this->getClient()->getConnection(), $uid) > 0) {
Loading history...
198
            return new Message($uid, $msglist, $this->getClient(), $fetch_options, $fetch_body, $fetch_attachment, $fetch_flags);
199
        }
200
201
        return null;
202
    }
203
204
    /**
205
     * Get all messages
206
     *
207
     * @param string    $criteria
208
     * @param int|null  $fetch_options
209
     * @param boolean   $fetch_body
210
     * @param boolean   $fetch_attachment
211
     * @param boolean   $fetch_flags
212
     * @param int|null  $limit
213
     * @param int       $page
214
     * @param string    $charset
215
     *
216
     * @return MessageCollection
217
     * @throws Exceptions\ConnectionFailedException
218
     * @throws Exceptions\InvalidWhereQueryCriteriaException
219
     * @throws GetMessagesFailedException
220
     */
221
    public function getMessages($criteria = 'ALL', $fetch_options = null, $fetch_body = true, $fetch_attachment = true, $fetch_flags = true, $limit = null, $page = 1, $charset = "UTF-8") {
222
223
        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

223
        return $this->query($charset)->where($criteria)->setFetchOptions(/** @scrutinizer ignore-type */ $fetch_options)->setFetchBody($fetch_body)
Loading history...
224
            ->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

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

323
        return $this->query($charset)->where($where)->setFetchOptions(/** @scrutinizer ignore-type */ $fetch_options)->setFetchBody($fetch_body)
Loading history...
324
            ->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

324
            ->setFetchAttachment($fetch_attachment)->setFetchFlags(/** @scrutinizer ignore-type */ $fetch_flags)
Loading history...
325
            ->limit($limit, $page)->get();
326
327
    }
328
329
    /**
330
     * Decode name.
331
     * It converts UTF7-IMAP encoding to UTF-8.
332
     *
333
     * @param $name
334
     *
335
     * @return mixed|string
336
     */
337
    protected function decodeName($name) {
338
        preg_match('#\{(.*)\}(.*)#', $name, $preg);
339
        return mb_convert_encoding($preg[2], "UTF-8", "UTF7-IMAP");
340
    }
341
342
    /**
343
     * Get simple name (without parent folders).
344
     *
345
     * @param $delimiter
346
     * @param $fullName
347
     *
348
     * @return mixed
349
     */
350
    protected function getSimpleName($delimiter, $fullName) {
351
        $arr = explode($delimiter, $fullName);
352
353
        return end($arr);
354
    }
355
356
    /**
357
     * Parse attributes and set it to object properties.
358
     *
359
     * @param $attributes
360
     */
361
    protected function parseAttributes($attributes) {
362
        $this->no_inferiors = ($attributes & LATT_NOINFERIORS) ? true : false;
363
        $this->no_select    = ($attributes & LATT_NOSELECT) ? true : false;
364
        $this->marked       = ($attributes & LATT_MARKED) ? true : false;
365
        $this->referal      = ($attributes & LATT_REFERRAL) ? true : false;
366
        $this->has_children = ($attributes & LATT_HASCHILDREN) ? true : false;
367
    }
368
369
    /**
370
     * Delete the current Mailbox
371
     * @param boolean $expunge
372
     *
373
     * @return bool
374
     *
375
     * @throws Exceptions\ConnectionFailedException
376
     */
377
    public function delete($expunge = true) {
378
        $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

378
        $status = imap_deletemailbox(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path);
Loading history...
379
        if($expunge) $this->client->expunge();
380
381
        return $status;
382
    }
383
384
    /**
385
     * Move or Rename the current Mailbox
386
     *
387
     * @param string $target_mailbox
388
     * @param boolean $expunge
389
     *
390
     * @return bool
391
     *
392
     * @throws Exceptions\ConnectionFailedException
393
     */
394
    public function move($target_mailbox, $expunge = true) {
395
        $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

395
        $status = imap_renamemailbox(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $target_mailbox);
Loading history...
396
        if($expunge) $this->client->expunge();
397
398
        return $status;
399
    }
400
401
    /**
402
     * Returns status information on a mailbox
403
     *
404
     * @param integer   $options
405
     *                  SA_MESSAGES     - set $status->messages to the number of messages in the mailbox
406
     *                  SA_RECENT       - set $status->recent to the number of recent messages in the mailbox
407
     *                  SA_UNSEEN       - set $status->unseen to the number of unseen (new) messages in the mailbox
408
     *                  SA_UIDNEXT      - set $status->uidnext to the next uid to be used in the mailbox
409
     *                  SA_UIDVALIDITY  - set $status->uidvalidity to a constant that changes when uids for the mailbox may no longer be valid
410
     *                  SA_ALL          - set all of the above
411
     *
412
     * @return object
413
     * @throws Exceptions\ConnectionFailedException
414
     */
415
    public function getStatus($options) {
416
        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

416
        return imap_status(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $options);
Loading history...
417
    }
418
419
    /**
420
     * Append a string message to the current mailbox
421
     *
422
     * @param string $message
423
     * @param string $options
424
     * @param string $internal_date
425
     *
426
     * @return bool
427
     * @throws Exceptions\ConnectionFailedException
428
     */
429
    public function appendMessage($message, $options = null, $internal_date = null) {
430
        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

430
        return imap_append(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $message, $options, $internal_date);
Loading history...
431
    }
432
433
    /**
434
     * Get the current Client instance
435
     *
436
     * @return Client
437
     */
438
    public function getClient() {
439
        return $this->client;
440
    }
441
442
    /**
443
     * @param $delimiter
444
     */
445
    public function setDelimiter($delimiter){
446
        if(in_array($delimiter, [null, '', ' ', false]) === true) {
447
            $delimiter = config('imap.options.delimiter', '/');
448
        }
449
450
        $this->delimiter = $delimiter;
451
    }
452
}
453