Passed
Push — master ( a61a57...835875 )
by Malte
03:03
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 $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
     * @inheritdoc self::query($charset = 'UTF-8')
142
     */
143
    public function search($charset = 'UTF-8'){
144
        return $this->query($charset);
145
    }
146
147
    /**
148
     * @inheritdoc self::query($charset = 'UTF-8')
149
     */
150
    public function messages($charset = 'UTF-8'){
151
        return $this->query($charset);
152
    }
153
154
    /**
155
     * Determine if folder has children.
156
     *
157
     * @return bool
158
     */
159
    public function hasChildren() {
160
        return $this->has_children;
161
    }
162
163
    /**
164
     * Set children.
165
     *
166
     * @param FolderCollection|array $children
167
     *
168
     * @return self
169
     */
170
    public function setChildren($children = []) {
171
        $this->children = $children;
172
173
        return $this;
174
    }
175
176
    /**
177
     * Get a specific message by UID
178
     *
179
     * @param integer      $uid     Please note that the uid is not unique and can change
180
     * @param integer|null $msglist
181
     * @param integer|null $fetch_options
182
     * @param boolean      $fetch_body
183
     * @param boolean      $fetch_attachment
184
     * @param boolean      $fetch_flags
185
     *
186
     * @return Message|null
187
     */
188
    public function getMessage($uid, $msglist = null, $fetch_options = null, $fetch_body = false, $fetch_attachment = false, $fetch_flags = true) {
189
        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

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

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

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

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

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

368
        $status = imap_deletemailbox(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path);
Loading history...
369
        $this->client->expunge();
370
371
        return $status;
372
    }
373
374
    /**
375
     * Move or Rename the current Mailbox
376
     *
377
     * @param string $target_mailbox
378
     *
379
     * @return bool
380
     *
381
     * @throws Exceptions\ConnectionFailedException
382
     */
383
    public function move($target_mailbox) {
384
        $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

384
        $status = imap_renamemailbox(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $target_mailbox);
Loading history...
385
        $this->client->expunge();
386
387
        return $status;
388
    }
389
390
    /**
391
     * Returns status information on a mailbox
392
     *
393
     * @param integer   $options
394
     *                  SA_MESSAGES     - set $status->messages to the number of messages in the mailbox
395
     *                  SA_RECENT       - set $status->recent to the number of recent messages in the mailbox
396
     *                  SA_UNSEEN       - set $status->unseen to the number of unseen (new) messages in the mailbox
397
     *                  SA_UIDNEXT      - set $status->uidnext to the next uid to be used in the mailbox
398
     *                  SA_UIDVALIDITY  - set $status->uidvalidity to a constant that changes when uids for the mailbox may no longer be valid
399
     *                  SA_ALL          - set all of the above
400
     *
401
     * @return object
402
     */
403
    public function getStatus($options) {
404
        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

404
        return imap_status(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $options);
Loading history...
405
    }
406
407
    /**
408
     * Append a string message to the current mailbox
409
     *
410
     * @param string $message
411
     * @param string $options
412
     * @param string $internal_date
413
     *
414
     * @return bool
415
     */
416
    public function appendMessage($message, $options = null, $internal_date = null) {
417
        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

417
        return imap_append(/** @scrutinizer ignore-type */ $this->client->getConnection(), $this->path, $message, $options, $internal_date);
Loading history...
418
    }
419
420
    /**
421
     * Get the current Client instance
422
     *
423
     * @return Client
424
     */
425
    public function getClient() {
426
        return $this->client;
427
    }
428
}
429