Passed
Branch master (6f17b7)
by Daniel
03:55
created

Replyable   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 366
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 366
rs 10
c 0
b 0
f 0
wmc 29

20 Methods

Rating   Name   Duplication   Size   Complexity  
A view() 0 5 1
A convertEmailList() 0 11 3
A to() 0 6 1
A optionalParameters() 0 5 1
A bcc() 0 6 1
A priority() 0 5 1
A cc() 0 6 1
A __construct() 0 3 1
A base64_encode() 0 3 1
A setReplyThreat() 0 7 2
A from() 0 6 1
A attach() 0 13 3
A setHeader() 0 5 1
A setReplySubject() 0 4 2
A reply() 0 12 2
A message() 0 5 1
A send() 0 5 1
A getMessageBody() 0 21 2
A emailList() 0 6 2
A subject() 0 5 1
1
<?php
2
3
namespace Dacastro4\LaravelGmail\Traits;
4
5
use Dacastro4\LaravelGmail\Services\Message\Mail;
6
use Google_Service_Gmail;
7
use Google_Service_Gmail_Message;
8
use Swift_Attachment;
9
use Swift_Message;
10
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
11
12
/**
13
 * @property Google_Service_Gmail $service
14
 */
15
trait Replyable
16
{
17
	use HasHeaders;
18
19
	private $swiftMessage;
20
21
	/**
22
	 * Gmail optional parameters
23
	 *
24
	 * @var array
25
	 */
26
	private $parameters = [];
27
28
	/**
29
	 * Text or html message to send
30
	 *
31
	 * @var string
32
	 */
33
	private $message;
34
35
	/**
36
	 * Subject of the email
37
	 *
38
	 * @var string
39
	 */
40
	private $subject;
41
42
	/**
43
	 * Sender's email
44
	 *
45
	 * @var string
46
	 */
47
	private $from;
48
49
	/**
50
	 * Sender's name
51
	 *
52
	 * @var  string
53
	 */
54
	private $nameFrom;
55
56
	/**
57
	 * Email of the recipient
58
	 *
59
	 * @var string|array
60
	 */
61
	private $to;
62
63
	/**
64
	 * Name of the recipient
65
	 *
66
	 * @var string
67
	 */
68
	private $nameTo;
69
70
	/**
71
	 * Single email or array of email for a carbon copy
72
	 *
73
	 * @var array|string
74
	 */
75
	private $cc;
76
77
	/**
78
	 * Name of the recipient
79
	 *
80
	 * @var string
81
	 */
82
	private $nameCc;
83
84
	/**
85
	 * Single email or array of email for a blind carbon copy
86
	 *
87
	 * @var array|string
88
	 */
89
	private $bcc;
90
91
	/**
92
	 * Name of the recipient
93
	 *
94
	 * @var string
95
	 */
96
	private $nameBcc;
97
98
	/**
99
	 * List of attachments
100
	 *
101
	 * @var array
102
	 */
103
	private $attachments = [];
104
105
	private $priority = 2;
106
107
	public function __construct()
108
	{
109
		$this->swiftMessage = new Swift_Message();
110
	}
111
112
	/**
113
	 * Receives the recipient's
114
	 * If multiple recipients will receive the message an array should be used.
115
	 * Example: array('[email protected]', '[email protected]' => 'A name')
116
	 *
117
	 * If $name is passed and the first parameter is a string, this name will be
118
	 * associated with the address.
119
	 *
120
	 * @param string|array $to
121
	 *
122
	 * @param string|null $name
123
	 *
124
	 * @return Replyable
125
	 */
126
	public function to( $to, $name = null )
127
	{
128
		$this->to = $to;
129
		$this->nameTo = $name;
130
131
		return $this;
132
	}
133
134
	public function from( $from, $name = null )
135
	{
136
		$this->from = $from;
137
		$this->nameTo = $name;
138
139
		return $this;
140
	}
141
142
	/**
143
	 * @param array|string $cc
144
	 *
145
	 * @param string|null $name
146
	 *
147
	 * @return Replyable
148
	 */
149
	public function cc( $cc, $name = null )
150
	{
151
		$this->cc = $this->emailList( $cc, $name );
152
		$this->nameCc = $name;
153
154
		return $this;
155
	}
156
157
	/**
158
	 * @param array|string $bcc
159
	 *
160
	 * @param string|null $name
161
	 *
162
	 * @return Replyable
163
	 */
164
	public function bcc( $bcc, $name = null )
165
	{
166
		$this->bcc = $this->emailList( $bcc, $name );
167
		$this->nameBcc = $name;
168
169
		return $this;
170
	}
171
172
	/**
173
	 * @param string $subject
174
	 *
175
	 * @return Replyable
176
	 */
177
	public function subject( $subject )
178
	{
179
		$this->subject = $subject;
180
181
		return $this;
182
	}
183
184
	/**
185
	 * @param string $view
186
	 * @param array $data
187
	 * @param array $mergeData
188
	 *
189
	 * @return Replyable
190
	 * @throws \Throwable
191
	 */
192
	public function view( $view, $data = [], $mergeData = [] )
193
	{
194
		$this->message = view( $view, $data, $mergeData )->render();
195
196
		return $this;
197
	}
198
199
	/**
200
	 * @param string $message
201
	 *
202
	 * @return Replyable
203
	 */
204
	public function message( $message )
205
	{
206
		$this->message = $message;
207
208
		return $this;
209
	}
210
211
	/**
212
	 * Attaches new file to the email from the Storage folder
213
	 *
214
	 * @param array $files comma separated of files
215
	 *
216
	 * @return Replyable
217
	 * @throws \Exception
218
	 */
219
	public function attach( ...$files )
220
	{
221
222
		foreach ( $files as $file ) {
223
224
			if ( ! file_exists( $file ) ) {
225
				throw new FileNotFoundException( $file );
226
			}
227
228
			array_push( $this->attachments, $file );
229
		}
230
231
		return $this;
232
	}
233
234
	/**
235
	 * The value is an integer where 1 is the highest priority and 5 is the lowest.
236
	 *
237
	 * @param int $priority
238
	 *
239
	 * @return Replyable
240
	 */
241
	public function priority( $priority )
242
	{
243
		$this->priority = $priority;
244
245
		return $this;
246
	}
247
248
	/**
249
	 * @param array $parameters
250
	 *
251
	 * @return Replyable
252
	 */
253
	public function optionalParameters( array $parameters )
254
	{
255
		$this->parameters = $parameters;
256
257
		return $this;
258
	}
259
260
	/**
261
	 * Reply to a specific email
262
	 *
263
	 * @return Mail
264
	 * @throws \Exception
265
	 */
266
	public function reply()
267
	{
268
		if ( ! $this->getId() ) {
269
			throw new \Exception( 'This is a new email. Use send().' );
270
		}
271
272
		$this->setReplyThreat();
273
		$this->setReplySubject();
274
		$body = $this->getMessageBody();
275
		$body->setThreadId( $this->getThreatId() );
276
277
		return new Mail( $this->service->users_messages->send( 'me', $body, $this->parameters ) );
278
	}
279
280
	/**
281
	 * Sends a new email
282
	 *
283
	 * @return Mail
284
	 */
285
	public function send()
286
	{
287
		$body = $this->getMessageBody();
288
289
		return new Mail( $this->service->users_messages->send( 'me', $body, $this->parameters ) );
290
	}
291
292
	/**
293
	 * Add a header to the email
294
	 *
295
	 * @param string $header
296
	 * @param string $value
297
	 */
298
	public function setHeader( $header, $value )
299
	{
300
		$headers = $this->swiftMessage->getHeaders();
301
302
		$headers->addTextHeader( $header, $value );
303
304
	}
305
306
	/**
307
	 * @return Google_Service_Gmail_Message
308
	 */
309
	private function getMessageBody()
310
	{
311
		$body = new Google_Service_Gmail_Message();
312
313
		$this->swiftMessage
314
			->setSubject( $this->subject )
315
			->setFrom( $this->from, $this->nameFrom )
316
			->setTo( $this->to, $this->nameTo )
317
			->setCc( $this->cc, $this->nameCc )
318
			->setBcc( $this->bcc, $this->nameBcc )
319
			->setBody( $this->message, 'text/html' )
320
			->setPriority( $this->priority );
321
322
		foreach ( $this->attachments as $file ) {
323
			$this->swiftMessage
324
				->attach( Swift_Attachment::fromPath( $file ) );
325
		}
326
327
		$body->setRaw( $this->base64_encode( $this->swiftMessage->toString() ) );
328
329
		return $body;
330
	}
331
332
	private function base64_encode( $data )
333
	{
334
		return rtrim( strtr( base64_encode( $data ), '+/', '-_' ), '=' );
335
	}
336
337
	private function emailList( $list, $name = null )
338
	{
339
		if ( is_array( $list ) ) {
340
			return $this->convertEmailList( $list, $name );
341
		} else {
342
			return $list;
343
		}
344
	}
345
346
	private function convertEmailList( $emails, $name = null )
347
	{
348
		$newList = [];
349
		$c = 0;
350
		foreach ( $emails as $key => $email ) {
351
			$emailName = isset( $name[ $c ] ) ? $name[ $c ] : explode( '@', $email )[ 0 ];
352
			$newList[ $email ] = $emailName;
353
			$c = $c + 1;
354
		}
355
356
		return $newList;
357
	}
358
359
	private function setReplySubject()
360
	{
361
		if ( ! $this->subject ) {
362
			$this->subject = $this->getSubject();
363
		}
364
	}
365
366
	private function setReplyThreat()
367
	{
368
		$threatId = $this->getThreatId();
369
		if ( $threatId ) {
370
			$this->setHeader( 'In-Reply-To', $this->getHeader( 'In-Reply-To' ) );
371
			$this->setHeader( 'References', $this->getHeader( 'References' ) );
372
			$this->setHeader( 'Message-ID', $this->getHeader( 'Message-ID' ) );
373
		}
374
	}
375
376
	public abstract function getThreatId();
377
378
	public abstract function getId();
379
380
	public abstract function getSubject();
381
}