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

Query::getQuery()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
/*
3
* File:     Query.php
4
* Category: -
5
* Author:   M. Goldenbaum
6
* Created:  21.07.18 18:54
7
* Updated:  -
8
*
9
* Description:
10
*  -
11
*/
12
13
namespace Webklex\IMAP\Query;
14
15
use Carbon\Carbon;
16
use Webklex\IMAP\Client;
17
use Webklex\IMAP\Exceptions\GetMessagesFailedException;
18
use Webklex\IMAP\Exceptions\MessageSearchValidationException;
19
use Webklex\IMAP\Message;
20
use Webklex\IMAP\Support\MessageCollection;
21
22
/**
23
 * Class Query
24
 *
25
 * @package Webklex\IMAP\Query
26
 */
27
class Query {
28
29
    /** @var array $query */
30
    protected $query;
31
32
    /** @var string $raw_query  */
33
    protected $raw_query;
34
35
    /** @var string $charset */
36
    protected $charset;
37
38
    /** @var Client $oClient */
39
    protected $oClient;
40
41
    /** @var int $limit */
42
    protected $limit = null;
43
44
    /** @var int $page */
45
    protected $page = 1;
46
47
    /** @var int $fetch_options */
48
    protected $fetch_options = null;
49
50
    /** @var int $fetch_body */
51
    protected $fetch_body = true;
52
53
    /** @var int $fetch_attachment */
54
    protected $fetch_attachment = true;
55
56
    /** @var int $fetch_flags */
57
    protected $fetch_flags = true;
58
59
    /**
60
     * Query constructor.
61
     * @param Client $oClient
62
     * @param string $charset
63
     */
64
    public function __construct(Client $oClient, $charset = 'UTF-8') {
65
        $this->oClient = $oClient;
66
        $this->charset = $charset;
67
        $this->query = collect();
0 ignored issues
show
Documentation Bug introduced by
It seems like collect() of type Illuminate\Support\Collection is incompatible with the declared type array of property $query.

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

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

Loading history...
68
        $this->boot();
69
    }
70
71
    /**
72
     * Instance boot method for additional functionality
73
     */
74
    protected function boot(){}
75
76
    /**
77
     * Parse a given value
78
     * @param mixed $value
79
     *
80
     * @return string
81
     */
82
    protected function parse_value($value){
83
        switch(true){
84
            case $value instanceof \Carbon\Carbon:
85
                $value = $value->format('d M y');
86
                break;
87
        }
88
89
        return (string) $value;
90
    }
91
92
    /**
93
     * Check if a given date is a valid carbon object and if not try to convert it
94
     * @param $date
95
     *
96
     * @return Carbon
97
     * @throws MessageSearchValidationException
98
     */
99
    protected function parse_date($date){
100
        if($date instanceof \Carbon\Carbon) return $date;
101
102
        try {
103
            $date = Carbon::parse($date);
104
        } catch (\Exception $e) {
105
            throw new MessageSearchValidationException();
106
        }
107
108
        return $date;
109
    }
110
111
    /**
112
     * Fetch the current query and return all found messages
113
     *
114
     * @return MessageCollection
115
     * @throws GetMessagesFailedException
116
     */
117
    public function get(){
118
        $messages = MessageCollection::make([]);
119
120
        try {
121
            $this->generate_query();
122
            $available_messages = imap_search($this->getClient()->getConnection(), $this->getRawQuery(), SE_UID, $this->getCharset());
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_search() 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

122
            $available_messages = imap_search(/** @scrutinizer ignore-type */ $this->getClient()->getConnection(), $this->getRawQuery(), SE_UID, $this->getCharset());
Loading history...
123
124
            if ($available_messages !== false) {
125
126
                $available_messages = collect($available_messages);
127
                $options = config('imap.options');
128
129
                if(strtolower($options['fetch_order']) === 'desc'){
130
                    $available_messages = $available_messages->reverse();
131
                }
132
133
                $available_messages->forPage($this->page, $this->limit)->each(function($msgno, $msglist) use(&$messages, $options) {
134
                    $oMessage = new Message($msgno, $msglist, $this->getClient(), $this->getFetchOptions(), $this->getFetchBody(), $this->getFetchAttachment());
135
                    switch ($options['message_key']){
136
                        case 'number':
137
                            $message_key = $oMessage->getMessageNo();
138
                            break;
139
                        case 'list':
140
                            $message_key = $msglist;
141
                            break;
142
                        default:
143
                            $message_key = $oMessage->getMessageId();
144
                            break;
145
146
                    }
147
                    $messages->put($message_key, $oMessage);
148
                });
149
            }
150
151
            return $messages;
152
        } catch (\Exception $e) {
153
            $message = $e->getMessage();
154
155
            throw new GetMessagesFailedException($message);
156
        }
157
    }
158
159
    /**
160
     * Get the raw IMAP search query
161
     *
162
     * @return string
163
     */
164
    public function generate_query(){
165
        $query = '';
166
        $this->query->each(function($statement) use(&$query) {
167
            if (count($statement) == 1) {
168
                $query .= $statement[0];
169
            } else {
170
                if($statement[1] === null){
171
                    $query .= $statement[0];
172
                }else{
173
                    $query .= $statement[0].' "'.$statement[1].'"';
174
                }
175
            }
176
            $query .= ' ';
177
178
        });
179
180
        $this->raw_query = trim($query);
181
182
        return $this->raw_query;
183
    }
184
185
    /**
186
     * @return Client
187
     */
188
    public function getClient(){
189
        $this->oClient->checkConnection();
190
        return $this->oClient;
191
    }
192
193
    /**
194
     * Set the limit and page for the current query
195
     * @param int $limit
196
     * @param int $page
197
     *
198
     * @return $this
199
     */
200
    public function limit($limit, $page = 1){
201
        if($page >= 1) $this->page = $page;
202
        $this->limit = $limit;
203
204
        return $this;
205
    }
206
207
    /**
208
     * @return array
209
     */
210
    public function getQuery() {
211
        return $this->query;
212
    }
213
214
    /**
215
     * @param array $query
216
     * @return Query
217
     */
218
    public function setQuery($query) {
219
        $this->query = $query;
220
        return $this;
221
    }
222
223
    /**
224
     * @return string
225
     */
226
    public function getRawQuery() {
227
        return $this->raw_query;
228
    }
229
230
    /**
231
     * @param string $raw_query
232
     * @return Query
233
     */
234
    public function setRawQuery($raw_query) {
235
        $this->raw_query = $raw_query;
236
        return $this;
237
    }
238
239
    /**
240
     * @return string
241
     */
242
    public function getCharset() {
243
        return $this->charset;
244
    }
245
246
    /**
247
     * @param string $charset
248
     * @return Query
249
     */
250
    public function setCharset($charset) {
251
        $this->charset = $charset;
252
        return $this;
253
    }
254
255
    /**
256
     * @return Client
257
     */
258
    public function getOClient() {
259
        return $this->oClient;
260
    }
261
262
    /**
263
     * @param Client $oClient
264
     * @return Query
265
     */
266
    public function setOClient($oClient) {
267
        $this->oClient = $oClient;
268
        return $this;
269
    }
270
271
    /**
272
     * @return int
273
     */
274
    public function getLimit() {
275
        return $this->limit;
276
    }
277
278
    /**
279
     * @param int $limit
280
     * @return Query
281
     */
282
    public function setLimit($limit) {
283
        $this->limit = $limit <= 0 ? null : $limit;
284
        return $this;
285
    }
286
287
    /**
288
     * @return int
289
     */
290
    public function getPage() {
291
        return $this->page;
292
    }
293
294
    /**
295
     * @param int $page
296
     * @return Query
297
     */
298
    public function setPage($page) {
299
        $this->page = $page;
300
        return $this;
301
    }
302
303
    /**
304
     * @param boolean $fetch_options
305
     * @return Query
306
     */
307
    public function setFetchOptions($fetch_options) {
308
        $this->fetch_options = $fetch_options;
0 ignored issues
show
Documentation Bug introduced by
The property $fetch_options was declared of type integer, but $fetch_options is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
309
        return $this;
310
    }
311
312
    /**
313
     * @param boolean $fetch_options
314
     * @return Query
315
     */
316
    public function fetchOptions($fetch_options) {
317
        return $this->setFetchOptions($fetch_options);
318
    }
319
320
    /**
321
     * @return int
322
     */
323
    public function getFetchOptions() {
324
        return $this->fetch_options;
325
    }
326
327
    /**
328
     * @return boolean
329
     */
330
    public function getFetchBody() {
331
        return $this->fetch_body;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->fetch_body returns the type integer which is incompatible with the documented return type boolean.
Loading history...
332
    }
333
334
    /**
335
     * @param boolean $fetch_body
336
     * @return Query
337
     */
338
    public function setFetchBody($fetch_body) {
339
        $this->fetch_body = $fetch_body;
0 ignored issues
show
Documentation Bug introduced by
The property $fetch_body was declared of type integer, but $fetch_body is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
340
        return $this;
341
    }
342
343
    /**
344
     * @param boolean $fetch_body
345
     * @return Query
346
     */
347
    public function fetchBody($fetch_body) {
348
        return $this->setFetchBody($fetch_body);
349
    }
350
351
    /**
352
     * @return boolean
353
     */
354
    public function getFetchAttachment() {
355
        return $this->fetch_attachment;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->fetch_attachment returns the type integer which is incompatible with the documented return type boolean.
Loading history...
356
    }
357
358
    /**
359
     * @param boolean $fetch_attachment
360
     * @return Query
361
     */
362
    public function setFetchAttachment($fetch_attachment) {
363
        $this->fetch_attachment = $fetch_attachment;
0 ignored issues
show
Documentation Bug introduced by
The property $fetch_attachment was declared of type integer, but $fetch_attachment is of type boolean. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
364
        return $this;
365
    }
366
367
    /**
368
     * @param boolean $fetch_attachment
369
     * @return Query
370
     */
371
    public function fetchAttachment($fetch_attachment) {
372
        return $this->setFetchAttachment($fetch_attachment);
373
    }
374
375
    /**
376
     * @return int
377
     */
378
    public function getFetchFlags() {
379
        return $this->fetch_flags;
380
    }
381
382
    /**
383
     * @param int $fetch_flags
384
     * @return Query
385
     */
386
    public function setFetchFlags($fetch_flags) {
387
        $this->fetch_flags = $fetch_flags;
388
        return $this;
389
    }
390
}