Passed
Push — master ( 225a9b...122a16 )
by Daniel
01:45
created

Mail::getDate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Dacastro4\LaravelGmail\Services\Message;
4
5
use Carbon\Carbon;
6
use Dacastro4\LaravelGmail\GmailConnection;
7
use Dacastro4\LaravelGmail\Traits\HasDecodableBody;
8
use Dacastro4\LaravelGmail\Traits\HasHeaders;
9
use Dacastro4\LaravelGmail\Traits\Modifiable;
10
use Dacastro4\LaravelGmail\Traits\Replyable;
11
use Google_Service_Gmail;
12
use Illuminate\Support\Collection;
13
14
/**
15
 * Class SingleMessage
16
 * @package Dacastro4\LaravelGmail\services
17
 */
18
class Mail extends GmailConnection
19
{
20
	use HasDecodableBody,
21
		HasHeaders,
22
		Modifiable,
23
		Replyable {
24
		Replyable::__construct as private __rConstruct;
25
		Modifiable::__construct as private __mConstruct;
26
	}
27
28
	/**
29
	 * @var
30
	 */
31
	public $id;
32
33
	/**
34
	 * @var
35
	 */
36
	public $internalDate;
37
38
	/**
39
	 * @var
40
	 */
41
	public $labels;
42
43
	/**
44
	 * @var
45
	 */
46
	public $size;
47
48
	/**
49
	 * @var
50
	 */
51
	public $threatId;
52
53
	/**
54
	 * @var \Google_Service_Gmail_MessagePart
55
	 */
56
	public $payload;
57
58
	/**
59
	 * @var Google_Service_Gmail
60
	 */
61
	public $service;
62
63
	/**
64
	 * SingleMessage constructor.
65
	 *
66
	 * @param \Google_Service_Gmail_Message $message
67
	 * @param bool $preload
68
	 *
69
	 */
70
	public function __construct( \Google_Service_Gmail_Message $message = null, $preload = false )
71
	{
72
73
		$this->service = new Google_Service_Gmail( $this );
74
75
		$this->__rConstruct();
76
		$this->__mConstruct();
77
		parent::__construct( config() );
0 ignored issues
show
Unused Code introduced by
The call to Dacastro4\LaravelGmail\T...difiable::__construct() has too many arguments starting with config(). ( Ignorable by Annotation )

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

77
		parent::/** @scrutinizer ignore-call */ 
78
          __construct( config() );

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
78
79
		if ( ! is_null( $message ) ) {
80
			if ( $preload ) {
81
				$message = $this->service->users_messages->get( 'me', $message->getId() );
82
			}
83
84
			$this->id = $message->getId();
85
			$this->internalDate = $message->getInternalDate();
86
			$this->labels = $message->getLabelIds();
87
			$this->size = $message->getSizeEstimate();
88
			$this->threatId = $message->getThreadId();
89
			$this->payload = $message->getPayload();
90
		}
91
	}
92
93
	/**
94
	 * Returns ID of the email
95
	 *
96
	 * @return string
97
	 */
98
	public function getId()
99
	{
100
		return $this->id;
101
	}
102
103
	/**
104
	 * Return a UNIX version of the date
105
	 *
106
	 * @return int UNIX date
107
	 */
108
	public function getInternalDate()
109
	{
110
		return $this->internalDate;
111
	}
112
113
	/**
114
	 * Returns the labels of the email
115
	 * Example: INBOX, STARRED, UNREAD
116
	 *
117
	 * @return array
118
	 */
119
	public function getLabels()
120
	{
121
		return $this->labels;
122
	}
123
124
	/**
125
	 * Returns approximate size of the email
126
	 *
127
	 * @return mixed
128
	 */
129
	public function getSize()
130
	{
131
		return $this->size;
132
	}
133
134
	/**
135
	 * Returns threat ID of the email
136
	 *
137
	 * @return string
138
	 */
139
	public function getThreatId()
140
	{
141
		return $this->threatId;
142
	}
143
144
	/**
145
	 * Returns all the headers of the email
146
	 *
147
	 * @return \Google_Service_Gmail_MessagePartHeader
148
	 */
149
	public function getHeaders()
150
	{
151
		return $this->buildHeaders( $this->payload->getHeaders() );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->buildHeade...>payload->getHeaders()) returns the type Illuminate\Support\Collection which is incompatible with the documented return type Google_Service_Gmail_MessagePartHeader.
Loading history...
152
	}
153
154
	/**
155
	 * Returns the subject of the email
156
	 *
157
	 * @return string
158
	 */
159
	public function getSubject()
160
	{
161
		return $this->getHeader( 'Subject' );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHeader('Subject') also could return the type array which is incompatible with the documented return type string.
Loading history...
162
	}
163
164
	/**
165
	 * Returns array of name and email of each recipient
166
	 *
167
	 * @return array
168
	 */
169
	public function getFrom()
170
	{
171
		$from = $this->getHeader( 'From' );
172
173
		preg_match( '/<(.*)>/', $from, $matches );
0 ignored issues
show
Bug introduced by
It seems like $from can also be of type array; however, parameter $subject of preg_match() does only seem to accept string, 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

173
		preg_match( '/<(.*)>/', /** @scrutinizer ignore-type */ $from, $matches );
Loading history...
174
175
		$name = preg_replace( '/ <(.*)>/', '', $from );
176
177
		return [
178
			'name'  => $name,
179
			'email' => isset( $matches[ 1 ] ) ? $matches[ 1 ] : null,
180
		];
181
	}
182
183
	/**
184
	 * Returns email of sender
185
	 *
186
	 * @return string|null
187
	 */
188
	public function getFromEmail()
189
	{
190
		$from = $this->getHeader( 'From' );
191
192
		preg_match( '/<(.*)>/', $from, $matches );
0 ignored issues
show
Bug introduced by
It seems like $from can also be of type array; however, parameter $subject of preg_match() does only seem to accept string, 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

192
		preg_match( '/<(.*)>/', /** @scrutinizer ignore-type */ $from, $matches );
Loading history...
193
194
		return isset( $matches[ 1 ] ) ? $matches[ 1 ] : null;
195
	}
196
197
	/**
198
	 * Returns name of the sender
199
	 *
200
	 * @return string|null
201
	 */
202
	public function getFromName()
203
	{
204
		$from = $this->getHeader( 'From' );
205
206
		$name = preg_replace( '/ <(.*)>/', '', $from );
207
208
		return $name;
209
	}
210
211
	/**
212
	 * Returns array list of recipients
213
	 *
214
	 * @return array
215
	 */
216
	public function getTo()
217
	{
218
		$allTo = $this->getHeader( 'To' );
219
220
		return $this->formatEmailList( $allTo );
0 ignored issues
show
Bug introduced by
It seems like $allTo can also be of type array; however, parameter $emails of Dacastro4\LaravelGmail\S...Mail::formatEmailList() does only seem to accept string, 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

220
		return $this->formatEmailList( /** @scrutinizer ignore-type */ $allTo );
Loading history...
221
	}
222
223
	/**
224
	 * Returns the original date that the email was sent
225
	 *
226
	 * @return Carbon
227
	 */
228
	public function getDate()
229
	{
230
		return Carbon::parse( $this->getHeader( 'Date' ) );
0 ignored issues
show
Bug introduced by
It seems like $this->getHeader('Date') can also be of type array; however, parameter $time of Carbon\Carbon::parse() does only seem to accept null|string, 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

230
		return Carbon::parse( /** @scrutinizer ignore-type */ $this->getHeader( 'Date' ) );
Loading history...
231
	}
232
233
	/**
234
	 * Returns email of the original recipient
235
	 *
236
	 * @return string
237
	 */
238
	public function getDeliveredTo()
239
	{
240
		return $this->getHeader( 'Delivered-To' );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getHeader('Delivered-To') also could return the type array which is incompatible with the documented return type string.
Loading history...
241
	}
242
243
	/**
244
	 * @param bool $raw
245
	 *
246
	 * @return bool|string
247
	 */
248
	public function getPlainTextBody( $raw = false )
249
	{
250
		$content = $this->getBody();
251
252
		return $raw ? $content : $this->getDecodedBody( $content );
253
	}
254
255
	/**
256
	 * @return string base64 version of the body
257
	 */
258
	public function getRawPlainTextBody()
259
	{
260
		return $this->getPlainTextBody( true );
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getPlainTextBody(true) also could return the type boolean which is incompatible with the documented return type string.
Loading history...
261
	}
262
263
	/**
264
	 * @param bool $raw
265
	 *
266
	 * @return string
267
	 */
268
	public function getHtmlBody( $raw = false )
269
	{
270
		$content = $this->getBody( 'text/html' );
271
272
		return $raw ? $content : $this->getDecodedBody( $content );
273
	}
274
275
	/**
276
	 * @return string base64 version of the body
277
	 */
278
	public function getRawHtmlBody()
279
	{
280
		return $this->getHtmlBody( true );
281
	}
282
283
	/**
284
	 * Returns a collection of attachments
285
	 *
286
	 * @param bool $preload Preload the attachment's data
287
	 *
288
	 * @return Collection
289
	 * @throws \Exception
290
	 */
291
	public function getAttachments($preload = false)
292
	{
293
		$attachments = new Collection( [] );
294
		$parts = $this->payload->getParts();
295
296
		/** @var \Google_Service_Gmail_MessagePart $part */
297
		foreach ( $parts as $part ) {
298
299
			$body = $part->getBody();
300
301
			if ( $body->getAttachmentId() ) {
302
				$attachment = ( new Attachment( $this->getId(), $part ) );
303
				if($preload) {
304
					$attachment = $attachment->getData();
305
				}
306
				$attachments->push(
307
					$attachment
308
				);
309
			}
310
311
		}
312
313
		return $attachments;
314
315
	}
316
317
	/**
318
	 * @return Collection
319
	 * @throws \Exception
320
	 */
321
	public function getAttachmentsWithData()
322
	{
323
		return $this->getAttachments(true);
324
	}
325
326
	/**
327
	 * @return boolean
328
	 */
329
	public function hasAttachments()
330
	{
331
		$attachments = 0;
332
		$parts = $this->payload->getParts();
333
334
		/**  @var \Google_Service_Gmail_MessagePart $part */
335
		foreach ( $parts as $part ) {
336
			$body = $part->getBody();
337
			if ( $body->getAttachmentId() ) {
338
				$attachments ++;
339
				break;
340
			}
341
		}
342
343
		return ! ! $attachments;
344
	}
345
346
	/**
347
	 * @param string $type
348
	 *
349
	 * @return \Google_Service_Gmail_MessagePart|null
350
	 */
351
	private function getBodyPart( $type = 'text/plain' )
352
	{
353
354
		$body = $this->payload->getParts();
355
356
		if ( $this->hasAttachments() ) {
357
			//Get the first attachment that is the main body
358
			$body = isset( $body[ 0 ] ) ? $body[ 0 ] : [];
359
			$parts = $body->getParts();
360
		} else {
361
			$parts = $body;
362
		}
363
364
		/** @var \Google_Service_Gmail_MessagePart $part */
365
		foreach ( $parts as $part ) {
366
			if ( $part->getMimeType() === $type ) {
367
				break;
368
			}
369
		}
370
371
		return $part ?: null;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $part seems to be defined by a foreach iteration on line 365. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
372
373
	}
374
375
	public function getBody( $type = 'text/plain' )
376
	{
377
		$part = $this->getBodyPart( $type );
378
		$body = $part->getBody();
379
380
		return $body->getData();
381
	}
382
383
	/**
384
	 * Get's the gmail information from the Mail
385
	 *
386
	 * @return Mail
387
	 */
388
	public function load()
389
	{
390
		$message = $this->service->users_messages->get( 'me', $this->getId() );
391
392
		return new self( $message );
393
	}
394
395
	private function buildHeaders( $emailHeaders )
396
	{
397
		$headers = [];
398
399
		foreach ( $emailHeaders as $header ) {
400
			/** @var \Google_Service_Gmail_MessagePartHeader $header */
401
402
			$head = new \stdClass();
403
404
			$head->key = $header->getName();
405
			$head->value = $header->getValue();
406
407
			$headers[] = $head;
408
		}
409
410
		return collect( $headers );
411
412
	}
413
414
	/**
415
	 * Returns an array of emails from an string in RFC 822 format
416
	 *
417
	 * @param string $emails email list in RFC 822 format
418
	 *
419
	 * @return array
420
	 */
421
	public function formatEmailList( $emails )
422
	{
423
		$all = [];
424
		$explodedEmails = explode( ',', $emails );
425
426
		foreach ( $explodedEmails as $email ) {
427
428
			preg_match( '/<(.*)>/', $email, $matches );
429
430
			$item['email'] = str_replace(' ', '', isset( $matches[ 1 ] ) ? $matches[1] : $email);
431
432
			$name = preg_replace( '/ <(.*)>/', '', $email );
433
434
			if(starts_with($name, ' ')) {
435
				$name = substr($name, 1);
436
			}
437
438
			$item['name'] = str_replace("\"", '', $name ?: null);
439
440
			$all[] = $item;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $item seems to be defined later in this foreach loop on line 430. Are you sure it is defined here?
Loading history...
441
442
		}
443
444
		return $all;
445
	}
446
447
}