Completed
Push — master ( 52adce...9eba1a )
by Patrick
03:32
created

Email::getFromAddress()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
1
<?php
2
/**
3
 * Email class
4
 *
5
 * This file describes the Email class
6
 *
7
 * PHP version 5 and 7
8
 *
9
 * @author Patrick Boyd / [email protected]
10
 * @copyright Copyright (c) 2015, Austin Artistic Reconstruction
11
 * @license http://www.apache.org/licenses/ Apache 2.0 License
12
 */
13
14
namespace Email;
15
16
/**
17
 * An class to represent an email
18
 */
19
class Email extends \SerializableObject
20
{
21
    /** The email's sender */
22
    protected $sender;
23
    /** An array of receipients */
24
    protected $to;
25
    /** An array of CC receipients */
26
    protected $cc;
27
    /** An array of BCC receipients */
28
    protected $bcc;
29
    /** The email's reply to address */
30
    protected $replyTo;
31
    /** The subject of the email */
32
    protected $subject;
33
    /** The email's HTML body */
34
    protected $htmlBody;
35
    /** The email's plain text body */
36
    protected $textBody;
37
    /** An array of attachements for the email */
38
    protected $attachments;
39
40
    /**
41
     * Initialize a new email
42
     */
43
    public function __construct()
44
    {
45
        $this->sender = false;
46
        $this->to = array();
47
        $this->cc = array();
48
        $this->bcc = array();
49
        $this->replyTo = false;
50
        $this->subject = false;
51
        $this->htmlBody = '';
52
        $this->textBody = '';
53
        $this->attachments = array();
54
    }
55
56
    /**
57
     * Who is this email going to be sent from
58
     *
59
     * This will return a string either in the format of 'email@address' or 'name <email@address>'
60
     *
61
     * @return string The sender of the email
62
     */
63
    public function getFromAddress()
64
    {
65
        if($this->sender === false)
66
        {
67
            return 'Burning Flipside <[email protected]>';
68
        }
69
        return $this->sender;
70
    }
71
72
    /**
73
     * Who is this email going to
74
     *
75
     * @return array The recipients of the email
76
     */
77
    public function getToAddresses()
78
    {
79
        return $this->to;
80
    }
81
82
    /**
83
     * Who is this email going to (CC)
84
     *
85
     * @return array The recipients of the email
86
     */
87
    public function getCCAddresses()
88
    {
89
        return $this->cc;
90
    }
91
92
    /**
93
     * Who is this email going to (BCC)
94
     *
95
     * @return array The recipients of the email
96
     */
97
    public function getBCCAddresses()
98
    {
99
        return $this->bcc;
100
    }
101
102
    /**
103
     * Who should a recipient reply to?
104
     *
105
     * @return string The reply to address of the email
106
     */
107
    public function getReplyTo()
108
    {
109
        if($this->replyTo === false)
110
        {
111
            return $this->getFromAddress();
112
        }
113
        return $this->replyTo;
114
    }
115
116
    /**
117
     * What is the email's subject?
118
     *
119
     * @return string The email's subject
120
     */
121
    public function getSubject()
122
    {
123
        return $this->subject;
124
    }
125
126
    /**
127
     * What should a user with an HTML capable email client see?
128
     *
129
     * @return string The email in HTML form
130
     */
131
    public function getHTMLBody()
132
    {
133
        return $this->htmlBody;
134
    }
135
136
    /**
137
     * What should a user with a plain text only email client see?
138
     *
139
     * @return string The email in ASCII form
140
     */
141
    public function getTextBody()
142
    {
143
        return $this->textBody;
144
    }
145
146
    /**
147
     * Create the address string given an email address and if specified a name
148
     *
149
     * @param string $email The email address
150
     * @param string $name  The name to associate with the address
151
     *
152
     * @return string The email address and name format
153
     */
154
    protected constructEmailAddressString($email, $name = false)
0 ignored issues
show
Bug introduced by
This code did not parse for me. Apparently, there is an error somewhere around this line:

Syntax error, unexpected T_STRING, expecting T_FUNCTION
Loading history...
155
    {
156
        if($name === false)
157
        {
158
            return $email;
159
        }
160
        return $name.' <'.$email.'>';
161
    }
162
163
    /**
164
     * Set the address the email should be sent from
165
     *
166
     * @param string $email The email address to send from
167
     * @param string $name  The name to associate with the from address
168
     */
169
    public function setFromAddress($email, $name = false)
170
    {
171
        $this->sender = $this->constructEmailAddressString($email, $name);
172
    }
173
174
    /**
175
     * Add a new address to the To: line
176
     *
177
     * @param string $email The email address to send to
178
     * @param string $name  The name to associate with the address
179
     */
180
    public function addToAddress($email, $name = false)
181
    {
182
        $this->addAddress($this->to, $email, $name);
183
    }
184
185
    /**
186
     * Add a new address to the CC: line
187
     *
188
     * @param string $email The email address to send to
189
     * @param string $name  The name to associate with the address
190
     */
191
    public function addCCAddress($email, $name = false)
192
    {
193
        $this->addAddress($this->cc, $email, $name);
194
    }
195
196
    /**
197
     * Add a new address to the BCC: line
198
     *
199
     * @param string $email The email address to send to
200
     * @param string $name  The name to associate with the address
201
     */
202
    public function addBCCAddress($email, $name = false)
203
    {
204
        $this->addAddress($this->bcc, $email, $name);
205
    }
206
207
    /**
208
     * Add an address to the inidicated list
209
     *
210
     * @param array  $list  The list to add the address to
211
     * @param string $email The email address to send to
212
     * @param string $name  The name to associate with the address
213
     */
214
    protected function addAddress(&$list, $email, $name = false)
215
    {
216
        array_push($list, $this->constructEmailAddressString($email, $name));
217
    }
218
219
    /**
220
     * Set the address a recipient should reply to
221
     *
222
     * @param string $email The email address to reply to
223
     * @param string $name  The name to associate with the from address
224
     */
225
    public function setReplyTo($email, $name = false)
226
    {
227
        $this->replyTo = $this->constructEmailAddressString($email, $name);
228
    }
229
230
    /**
231
     * Set the subject line for the email
232
     *
233
     * @param string $subject The email's new subject line
234
     */
235
    public function setSubject($subject)
236
    {
237
        $this->subject = $subject;
238
    }
239
240
    /**
241
     * Set the HTML body for the email
242
     *
243
     * @param string $body The email's new HTML body
244
     */
245
    public function setHTMLBody($body)
246
    {
247
        $this->htmlBody = $body;
248
    }
249
250
    /**
251
     * Set the plain text for the email
252
     *
253
     * @param string $body The email's new plain text body
254
     */
255
    public function setTextBody($body)
256
    {
257
        $this->textBody = $body;
258
    }
259
260
    /**
261
     * Append a string to the HTML Body
262
     *
263
     * @param string $body The string to append to the HTML body
264
     */
265
    public function appendToHTMLBody($body)
266
    {
267
        $this->htmlBody .= $body;
268
    }
269
270
    /**
271
     * Append a string to the Plain Text Body
272
     *
273
     * @param string $body The string to append to the plain text body
274
     */
275
    public function appendToTextBody($body)
276
    {
277
        $this->textBody .= $body;
278
    }
279
280
    /**
281
     * Add an attachment from a memory buffer
282
     *
283
     * @param string $name The file name for the attachment to be sent as
284
     * @param string $buffer The attachment as a binary string
285
     * @param string $mimeType The MIME type to send the attachment as
286
     */
287
    public function addAttachmentFromBuffer($name, $buffer, $mimeType = 'application/octet-stream')
288
    {
289
        array_push($this->attachments, array('name'=>$name, 'data'=>$buffer, 'mimeType'=>$mimeType));
290
    }
291
292
    /**
293
     * Add an attachment from a file on the local disk
294
     *
295
     * @param string $filename The file name and path on the local disk
296
     * @param string $name The file name for the attachment to be sent as
297
     */
298
    public function addAttachmentFromFile($filename, $name = false)
299
    {
300
        if($name === false)
301
        {
302
            $name = basename($filename);
303
        }
304
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
305
        $mimeType = finfo_file($finfo, $filename);
306
        if($mimeType === false)
307
        {
308
            $mimeType = 'application/octet-stream';
309
        }
310
        if(file_exists($filename) && is_file($filename) && is_readable($filename))
311
        {
312
            $this->addAttachmentFromBuffer($name, file_get_contents($filename), $mimeType);
313
        }
314
    }
315
316
    /**
317
     * Does this email have an attachment?
318
     *
319
     * @return boolean True if the email has an attachment. False otherwise
320
     */
321
    public function hasAttachments()
322
    {
323
        return empty($this->attachments) !== true;
324
    }
325
326
    /**
327
     * Serialize the message to a raw MIME encoded format suitable for sending over SMTP
328
     *
329
     * @return string A text version of the message suitable for sending over SMTP
330
     */
331
    public function getRawMessage()
332
    {
333
        $boundary = uniqid(rand(), true);
334
        $rawMessage = 'To: '.$this->encodeRecipients($this->getToAddresses())."\n";
335
        $from = $this->getFromAddress();
336
        if($from === false)
337
        {
338
            throw new \Exception('Message must have a from address');
339
        }
340
        $rawMessage .= 'From: '.$this->encodeRecipients($from)."\n";
341
        if(!empty($this->cc))
342
        {
343
            $rawMessage .= 'CC: '.$this->encodeRecipients($this->getCCAddresses())."\n";
344
        }
345
        if(!empty($this->bcc))
346
        {
347
            $rawMessage .= 'BCC: '.$this->encodeRecipients($this->getBCCAddresses())."\n";
348
        }
349
        $rawMessage .= 'Subject: '.$this->getSubject()."\n";
350
        $rawMessage .= 'MIME-Version: 1.0'."\n";
351
        $rawMessage .= 'Content-type: Multipart/Mixed; boundary="'.$boundary.'"'."\n";
352
        $rawMessage .= "\n--{$boundary}\n";
353
        $rawMessage .= 'Content-type: Multipart/Alternative; boundary="alt-'.$boundary.'"'."\n";
354
        $textBody    = $this->getTextBody();
355
        if($textBody !== false && strlen($textBody) > 0)
356
        {
357
            $rawMessage .= "\n--alt-{$boundary}\n";
358
            $rawMessage .= "Content-Type: text/plain\n\n";
359
            $rawMessage .= $textBody."\n";
360
        }
361
        $htmlBody = $this->getHTMLBody();
362
        if($htmlBody !== false && strlen($htmlBody) > 0)
363
        {
364
            $rawMessage .= "\n--alt-{$boundary}\n";
365
            $rawMessage .= 'Content-Type: text/html; charset="UTF-8"'."\n\n";
366
            $rawMessage .= $htmlBody."\n";
367
        }
368
        $rawMessage .= "\n--alt-{$boundary}--\n";
369
        foreach($this->attachments as $attachment)
370
        {
371
            $rawMessage .= "\n--{$boundary}\n";
372
            $rawMessage .= 'Content-Type: '.$attachment['mimeType'].'; name="'.$attachment['name']."\"\n";
373
            $rawMessage .= 'Content-Disposition: attachment'."\n";
374
            $rawMessage .= 'Content-Transfer-Encoding: base64'."\n\n";
375
            $rawMessage .= chunk_split(base64_encode($attachment['data']), 76, "\n")."\n";
376
        }
377
        $rawMessage .= "\n--{$boundary}--\n";
378
        return $rawMessage;
379
    }
380
381
    /**
382
     * Serialize a recipient so that it can be sent over SMTP
383
     *
384
     * @param string $recipient The recipient in the format 'name <email@address>'
385
     *
386
     * @return string A text version of the recipient name and address suitable for sending over SMTP
387
     */
388
    public function encodeRecipients($recipient)
389
    {
390
        if(is_array($recipient))
391
        {
392
            return join(', ', array_map(array($this, 'encodeRecipients'), $recipient));
393
        }
394
        if(preg_match("/(.*)<(.*)>/", $recipient, $regs))
395
        {
396
            $recipient = '=?UTF-8?B?'.base64_encode($regs[1]).'?= <'.$regs[2].'>';
397
        }
398
        return $recipient;
399
    }
400
}
401
/* vim: set tabstop=4 shiftwidth=4 expandtab: */
402