Passed
Push — master ( b504b1...f11bbd )
by Daniel
05:51 queued 02:51
created

Replyable::optionalParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 5
rs 10
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 Symfony\Component\Mime\Email;
9
use Illuminate\Container\Container;
10
use Illuminate\Mail\Markdown;
11
use Symfony\Component\HttpFoundation\File\Exception\FileNotFoundException;
12
13
/**
14
 * @property Google_Service_Gmail $service
15
 */
16
trait Replyable
17
{
18
	use HasHeaders;
19
20
	private $symfonyEmail;
21
22
	/**
23
	 * Gmail optional parameters
24
	 *
25
	 * @var array
26
	 */
27
	private $parameters = [];
28
29
	/**
30
	 * Text or html message to send
31
	 *
32
	 * @var string
33
	 */
34
	private $message;
35
36
	/**
37
	 * Subject of the email
38
	 *
39
	 * @var string
40
	 */
41
	private $subject;
42
43
	/**
44
	 * Sender's email
45
	 *
46
	 * @var string
47
	 */
48
	private $from;
49
50
	/**
51
	 * Sender's name
52
	 *
53
	 * @var  string
54
	 */
55
	private $nameFrom;
56
57
	/**
58
	 * Email of the recipient
59
	 *
60
	 * @var string|array
61
	 */
62
	private $to;
63
64
	/**
65
	 * Name of the recipient
66
	 *
67
	 * @var string
68
	 */
69
	private $nameTo;
70
71
	/**
72
	 * Single email or array of email for a carbon copy
73
	 *
74
	 * @var array|string
75
	 */
76
	private $cc;
77
78
	/**
79
	 * Name of the recipient
80
	 *
81
	 * @var string
82
	 */
83
	private $nameCc;
84
85
	/**
86
	 * Single email or array of email for a blind carbon copy
87
	 *
88
	 * @var array|string
89
	 */
90
	private $bcc;
91
92
	/**
93
	 * Name of the recipient
94
	 *
95
	 * @var string
96
	 */
97
	private $nameBcc;
98
99
	/**
100
	 * List of attachments
101
	 *
102
	 * @var array
103
	 */
104
	private $attachments = [];
105
106
	private $priority = 2;
107
108
	public function __construct()
109
	{
110
		$this->symfonyEmail = new Email();
111
	}
112
113
	/**
114
	 * Receives the recipient's
115
	 * If multiple recipients will receive the message an array should be used.
116
	 * Example: array('[email protected]', '[email protected]' => 'A name')
117
	 *
118
	 * If $name is passed and the first parameter is a string, this name will be
119
	 * associated with the address.
120
	 *
121
	 * @param  string|array  $to
122
	 *
123
	 * @param  string|null  $name
124
	 *
125
	 * @return Replyable
126
	 */
127
	public function to($to, $name = null)
128
	{
129
		$this->to = $this->emailList($to, $name);
130
		$this->nameTo = $name;
131
132
		return $this;
133
	}
134
135
	public function from($from, $name = null)
136
	{
137
		$this->from = $from;
138
		$this->nameFrom = $name;
139
140
		return $this;
141
	}
142
143
	/**
144
	 * @param  array|string  $cc
145
	 *
146
	 * @param  string|null  $name
147
	 *
148
	 * @return Replyable
149
	 */
150
	public function cc($cc, $name = null)
151
	{
152
		$this->cc = $this->emailList($cc, $name);
153
		$this->nameCc = $name;
154
155
		return $this;
156
	}
157
158
	private function emailList($list, $name = null)
159
	{
160
		if (is_array($list)) {
161
			return $this->convertEmailList($list, $name);
162
		} else {
163
			return $list;
164
		}
165
	}
166
167
	private function convertEmailList($emails, $name = null)
168
	{
169
		$newList = [];
170
		$count = 0;
171
		foreach ($emails as $key => $email) {
172
			$emailName = isset($name[$count]) ? $name[$count] : explode('@', $email)[0];
173
			$newList[$email] = $emailName;
174
			$count = $count + 1;
175
		}
176
177
		return $newList;
178
	}
179
180
	/**
181
	 * @param  array|string  $bcc
182
	 *
183
	 * @param  string|null  $name
184
	 *
185
	 * @return Replyable
186
	 */
187
	public function bcc($bcc, $name = null)
188
	{
189
		$this->bcc = $this->emailList($bcc, $name);
190
		$this->nameBcc = $name;
191
192
		return $this;
193
	}
194
195
	/**
196
	 * @param  string  $subject
197
	 *
198
	 * @return Replyable
199
	 */
200
	public function subject($subject)
201
	{
202
		$this->subject = $subject;
203
204
		return $this;
205
	}
206
207
	/**
208
	 * @param  string  $view
209
	 * @param  array  $data
210
	 * @param  array  $mergeData
211
	 *
212
	 * @return Replyable
213
	 * @throws \Throwable
214
	 */
215
	public function view($view, $data = [], $mergeData = [])
216
	{
217
		$this->message = view($view, $data, $mergeData)->render();
218
219
		return $this;
220
	}
221
222
    /**
223
     * loads markdown file for message body
224
     *
225
     * @throws \Throwable
226
     * @return Replyable
227
     */
228
    public function markdown(string $markdown_view, array $data = [])
229
    {
230
        $markdown = Container::getInstance()->make(Markdown::class);
231
232
        if (config('mail.markdown.theme')) {
233
            $markdown->theme(config('mail.markdown.theme'));
234
        }
235
236
        $this->message = $markdown->render($markdown_view, $data);
237
238
        return $this;
239
    }
240
241
	/**
242
	 * @param  string  $message
243
	 *
244
	 * @return Replyable
245
	 */
246
	public function message($message)
247
	{
248
		$this->message = $message;
249
250
		return $this;
251
	}
252
253
	/**
254
	 * Attaches new file to the email from the Storage folder
255
	 *
256
	 * @param  array  $files  comma separated of files
257
	 *
258
	 * @return Replyable
259
	 * @throws \Exception
260
	 */
261
	public function attach(...$files)
262
	{
263
264
		foreach ($files as $file) {
265
266
			if (!file_exists($file)) {
267
				throw new FileNotFoundException($file);
268
			}
269
270
			array_push($this->attachments, $file);
271
		}
272
273
		return $this;
274
	}
275
276
	/**
277
	 * The value is an integer where 1 is the highest priority and 5 is the lowest.
278
	 *
279
	 * @param  int  $priority
280
	 *
281
	 * @return Replyable
282
	 */
283
	public function priority($priority)
284
	{
285
		$this->priority = $priority;
286
287
		return $this;
288
	}
289
290
	/**
291
	 * @param  array  $parameters
292
	 *
293
	 * @return Replyable
294
	 */
295
	public function optionalParameters(array $parameters)
296
	{
297
		$this->parameters = $parameters;
298
299
		return $this;
300
	}
301
302
	/**
303
	 * Reply to a specific email
304
	 *
305
	 * @return Mail
306
	 * @throws \Exception
307
	 */
308
	public function reply()
309
	{
310
		if (!$this->getId()) {
311
			throw new \Exception('This is a new email. Use send().');
312
		}
313
314
		$this->setReplyThread();
315
		$this->setReplySubject();
316
		$this->setReplyTo();
317
		$this->setReplyFrom();
318
		$body = $this->getMessageBody();
319
		$body->setThreadId($this->getThreadId());
320
321
		return new Mail($this->service->users_messages->send('me', $body, $this->parameters));
322
	}
323
324
	public abstract function getId();
325
326
	private function setReplyThread()
327
	{
328
		$threadId = $this->getThreadId();
329
		if ($threadId) {
330
			$this->setHeader('In-Reply-To', $this->getMessageIdHeader());
331
			$this->setHeader('References', $this->getHeader('References'));
332
			$this->setHeader('Message-ID', $this->getMessageIdHeader());
333
		}
334
	}
335
	
336
	private function getMessageIdHeader() {
337
		if($this->getHeader('Message-ID')) {
338
			return $this->getHeader('Message-ID');
339
		}
340
		if($this->getHeader('Message-Id')) {
341
			return $this->getHeader('Message-Id');
342
		}
343
		return null;
344
	}
345
346
	public abstract function getThreadId();
347
348
	/**
349
	 * Add a header to the email
350
	 *
351
	 * @param  string  $header
352
	 * @param  string  $value
353
	 */
354
	public function setHeader($header, $value)
355
	{
356
		$headers = $this->symfonyEmail->getHeaders();
357
358
		$headers->addTextHeader($header, $value);
359
360
	}
361
362
	private function setReplySubject()
363
	{
364
		if (!$this->subject) {
365
			$this->subject = $this->getSubject();
366
		}
367
	}
368
369
	private function setReplyTo()
370
	{
371
		if (!$this->to) {
372
			$replyTo = $this->getReplyTo();
373
374
			$this->to = $replyTo['email'];
375
			$this->nameTo = $replyTo['name'];
376
		}
377
	}
378
379
	private function setReplyFrom()
380
	{
381
		if (!$this->from) {
382
			$this->from = $this->getUser();
383
			if(!$this->from) {
384
				throw new \Exception('Reply from is not defined');
385
			}
386
		}
387
	}
388
389
	public abstract function getSubject();
390
391
	public abstract function getReplyTo();
392
393
	public abstract function getUser();
394
395
	/**
396
	 * @return Google_Service_Gmail_Message
397
	 */
398
	private function getMessageBody()
399
	{
400
		$body = new Google_Service_Gmail_Message();
401
402
        if ($this->from) {
403
            $this->symfonyEmail->from($this->from, ($this->nameFrom ? $this->nameFrom : ''));
404
        }
405
406
        if ($this->to) {
407
            $this->symfonyEmail->to($this->to, ($this->nameTo ? $this->nameTo : ''));
408
        }
409
410
        if ($this->cc) {
411
            if (is_array($this->cc)) {
412
                foreach ($this->cc as $emailCc => $nameCc) {
413
                    $this->symfonyEmail->addCc($emailCc, $nameCc);
414
                }
415
            } else {
416
                $this->symfonyEmail->cc($this->cc, ($this->nameCc ? $this->nameCc : ''));
417
            }
418
        }
419
420
        $bccString = "";
421
        if ($this->bcc) {
422
            if (is_array($this->bcc)) {
423
                foreach ($this->bcc as $emailBcc => $nameBcc) {
424
                    $bccString .= "Bcc: " . $nameBcc . " <" . $emailBcc . ">\r\n";
425
                }
426
            } else {
427
                $bccString .= "Bcc: " . ($this->nameBcc ? $this->nameBcc . " " : "") . "<" . $this->bcc . ">\r\n";
428
            }
429
        }
430
431
        $this->symfonyEmail->subject($this->subject)
432
            ->html($this->message)
433
            ->priority($this->priority)
434
        ;
435
436
        foreach ($this->attachments as $file) {
437
            $this->symfonyEmail->attachFromPath($file);
438
        }
439
440
        $body->setRaw($this->base64_encode($bccString . $this->symfonyEmail->toString()));
441
442
		return $body;
443
	}
444
445
	private function base64_encode($data)
446
	{
447
		return rtrim(strtr(base64_encode($data), ['+' => '-', '/' => '_']), '=');
448
	}
449
450
	/**
451
	 * Sends a new email
452
	 *
453
	 * @return self|Mail
454
	 */
455
	public function send()
456
	{
457
		$body = $this->getMessageBody();
458
459
		$this->setMessage($this->service->users_messages->send('me', $body, $this->parameters));
460
461
		return $this;
462
	}
463
464
	protected abstract function setMessage(\Google_Service_Gmail_Message $message);
465
}
466