1 <?php
2
3 namespace Alo;
4
5 use Alo\Statics\Security;
6 use PHPMailer;
7
8 if(!defined('GEN_START')) {
9 http_response_code(404);
10 die();
11 }
12
13 require_once DIR_SYS . 'external' . DIRECTORY_SEPARATOR . 'email' . DIRECTORY_SEPARATOR . 'class.phpmailer.php';
14 require_once DIR_SYS . 'external' . DIRECTORY_SEPARATOR . 'email' . DIRECTORY_SEPARATOR . 'PHPMailerAutoload.php';
15
16 \Alo::loadConfig('email');
17
18 /**
19 * Mail wrapper for the external PHPMailer library
20 *
21 * @author Art <a.molcanovas@gmail.com>
22 * @link https://github.com/PHPMailer/PHPMailer
23 */
24 class Email extends PHPMailer {
25
26 /**
27 * Array of debug outputs, each send operation representing a key/value pair
28 *
29 * @var array
30 */
31 protected $debug_output;
32
33 /**
34 * Array of content attachments to clean afterwards
35 *
36 * @var array
37 */
38 protected $attached_content;
39
40 /**
41 * Instantiates the class
42 *
43 * @author Art <a.molcanovas@gmail.com>
44 *
45 * @param boolean $exceptions Should we throw external exceptions?
46 */
47 function __construct($exceptions = false) {
48 parent::__construct($exceptions);
49
50 if(ALO_EMAIL_ERR_LANG != 'en') {
51 $this->setLanguage(ALO_EMAIL_ERR_LANG);
52 }
53
54 $this->isSMTP(ALO_EMAIL_USE_SMTP);
55 $this->Host = ALO_EMAIL_HOSTS;
56 $this->SMTPAuth = ALO_EMAIL_AUTH;
57 $this->Username = ALO_EMAIL_USERNAME;
58 $this->Password = ALO_EMAIL_PASSWORD;
59 $this->SMTPSecure = ALO_EMAIL_SECURE;
60 $this->Port = ALO_EMAIL_PORT;
61 $this->From = ALO_EMAIL_FROM_DEFAULT_ADDR;
62 $this->FromName = ALO_EMAIL_FROM_DEFAULT_NAME;
63 $this->Subject = ALO_EMAIL_SUBJECT_DEFAULT;
64 $this->isHTML(ALO_EMAIL_HTML_ENABLED);
65 }
66
67 /**
68 * Instantiates the class
69 *
70 * @author Art <a.molcanovas@gmail.com>
71 *
72 * @param boolean $exceptions Should we throw external exceptions?
73 *
74 * @return Email
75 */
76 static function Email($exceptions = false) {
77 return new Email($exceptions);
78 }
79
80 /**
81 * Checks if the supplied string is an email
82 *
83 * @author Art <a.molcanovas@gmail.com>
84 *
85 * @param string $str The input
86 *
87 * @return boolean
88 */
89 static function is_email($str) {
90 if(!is_string(($str))) {
91 return false;
92 } else {
93 return preg_match('/^[a-z\.\-_0-9]+@[a-z\.\-_0-9]+\.[a-z]{2,3}$/is', $str) == 1;
94 }
95 }
96
97 /**
98 * Destructor. Performs cleanup operations
99 *
100 * @author Art <a.molcanovas@gmail.com>
101 */
102 function __destruct() {
103 $this->cleanup();
104 parent::__destruct();
105 }
106
107 /**
108 * Cleans up attached content
109 *
110 * @author Art <a.molcanovas@gmail.com>
111 * @return Email
112 */
113 function cleanup() {
114 if(!empty($this->attached_content)) {
115 foreach($this->attached_content as $file) {
116 if(file_exists($file)) {
117 unlink($file);
118 }
119 }
120
121 $this->attached_content = [];
122 }
123
124 return $this;
125 }
126
127 /**
128 * Adds a recipient address
129 *
130 * @author Art <a.molcanovas@gmail.com>
131 *
132 * @param string $address The address to add
133 * @param string $name Optionally, the recipient's name
134 *
135 * @return Email
136 * @throws \phpmailerException
137 */
138 function addAddress($address, $name = '') {
139 parent::addAddress($address, $name);
140
141 return $this;
142 }
143
144 /**
145 * Adds a BCC address
146 *
147 * @author Art <a.molcanovas@gmail.com>
148 *
149 * @param string $address The address
150 * @param string $name Their name
151 *
152 * @throws \phpmailerException
153 * @return Email
154 */
155 function addBCC($address, $name = '') {
156 parent::addBCC($address, $name);
157
158 return $this;
159 }
160
161 /**
162 * Adds a CC address
163 *
164 * @author Art <a.molcanovas@gmail.com>
165 *
166 * @param string $address The address
167 * @param string $name Their name
168 *
169 * @return Email
170 * @throws \phpmailerException
171 */
172 function addCC($address, $name = '') {
173 parent::addCC($address, $name);
174
175 return $this;
176 }
177
178 /**
179 * Adds reply-to data
180 *
181 * @author Art <a.molcanovas@gmail.com>
182 *
183 * @param string $to Reply-to address
184 * @param string $name Reply-to name
185 *
186 * @return Email
187 * @throws \phpmailerException
188 */
189 function addReplyTo($to, $name = '') {
190 parent::addReplyTo($to, $name);
191
192 return $this;
193 }
194
195 /**
196 * Create a message and send it.
197 *
198 * @author Art <a.molcanovas@gmail.com>
199 * @throws \phpmailerException
200 * @return boolean false on error - See the ErrorInfo property for details of the error.
201 */
202 function send() {
203 ob_start();
204 $send = parent::send();
205 $this->debug_output[] = ob_get_clean();
206
207 return $send;
208 }
209
210 /**
211 * Attempts to attach not a file from the disk, but generated contents
212 *
213 * @author Art <a.molcanovas@gmail.com>
214 *
215 * @param string $name The attachment filename
216 * @param string $content The contents
217 *
218 * @return bool
219 * @throws \Exception
220 * @throws \phpmailerException
221 */
222 function attachContent($name, $content) {
223 $dest_filename = Security::getUniqid('md5', 'email_attachment');
224 $dest = DIR_TMP . $dest_filename;
225
226 if(file_exists($dest)) {
227 //try again
228 return $this->attachContent($name, $content);
229 } elseif(file_put_contents($dest, $content) !== false) {
230 $this->attached_content[] = $dest;
231
232 return $this->addAttachment($dest, $name);
233 } else {
234 return false;
235 }
236 }
237
238 /**
239 * Returns the debug output from calls to $this->send()
240 *
241 * @author Art <a.molcanovas@gmail.com>
242 * @return array
243 */
244 function getDebugOutput() {
245 return $this->debug_output;
246 }
247 }