PageRenderTime 27ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/mail.php

https://gitlab.com/dmsapiens/physicians
PHP | 630 lines | 310 code | 48 blank | 272 comment | 6 complexity | b1e15a8c7981d94acab08cf8ef23518b MD5 | raw file
  1. <?php
  2. /**
  3. * Simple Mail
  4. *
  5. * A simple PHP wrapper class for sending email using the mail() method.
  6. *
  7. * PHP version 5
  8. *
  9. * LICENSE: This source file is subject to the MIT license, which is
  10. * available through the world-wide-web at the following URI:
  11. * http://github.com/eoghanobrien/php-simple-mail/LICENCE.txt
  12. *
  13. * @category SimpleMail
  14. * @package SimpleMail
  15. * @author Eoghan O'Brien <eoghan@eoghanobrien.com>
  16. * @copyright 2009 - 2014 Eoghan O'Brien
  17. * @license http://github.com/eoghanobrien/php-simple-mail/LICENCE.txt MIT
  18. * @version 1.5
  19. * @link http://github.com/eoghanobrien/php-simple-mail
  20. */
  21. /**
  22. * Simple Mail class.
  23. *
  24. * @category SimpleMail
  25. * @package SimpleMail
  26. * @author Eoghan O'Brien <eoghan@eoghanobrien.com>
  27. * @copyright 2009 - 2014 Eoghan O'Brien
  28. * @license http://github.com/eoghanobrien/php-simple-mail/LICENCE.txt MIT
  29. * @version 1.4
  30. * @link http://github.com/eoghanobrien/php-simple-mail
  31. */
  32. class SimpleMail
  33. {
  34. /**
  35. * @var int $_wrap
  36. */
  37. protected $_wrap = 78;
  38. /**
  39. * @var array $_to
  40. */
  41. protected $_to = array();
  42. /**
  43. * @var string $_subject
  44. */
  45. protected $_subject;
  46. /**
  47. * @var string $_message
  48. */
  49. protected $_message;
  50. /**
  51. * @var array $_headers
  52. */
  53. protected $_headers = array();
  54. /**
  55. * @var string $_parameters
  56. */
  57. protected $_params;
  58. /**
  59. * @var array $_attachments
  60. */
  61. protected $_attachments = array();
  62. /**
  63. * @var string $_uid
  64. */
  65. protected $_uid;
  66. /**
  67. * __construct
  68. *
  69. * Resets the class properties.
  70. */
  71. public function __construct()
  72. {
  73. $this->reset();
  74. }
  75. /**
  76. * reset
  77. *
  78. * Resets all properties to initial state.
  79. *
  80. * @return SimpleMail
  81. */
  82. public function reset()
  83. {
  84. $this->_to = array();
  85. $this->_headers = array();
  86. $this->_subject = null;
  87. $this->_message = null;
  88. $this->_wrap = 78;
  89. $this->_params = null;
  90. $this->_attachments = array();
  91. $this->_uid = $this->getUniqueId();
  92. return $this;
  93. }
  94. /**
  95. * setTo
  96. *
  97. * @param string $email The email address to send to.
  98. * @param string $name The name of the person to send to.
  99. *
  100. * @return SimpleMail
  101. */
  102. public function setTo($email, $name)
  103. {
  104. $this->_to[] = $this->formatHeader((string) $email, (string) $name);
  105. return $this;
  106. }
  107. /**
  108. * getTo
  109. *
  110. * Return an array of formatted To addresses.
  111. *
  112. * @return array
  113. */
  114. public function getTo()
  115. {
  116. return $this->_to;
  117. }
  118. /**
  119. * setSubject
  120. *
  121. * @param string $subject The email subject
  122. *
  123. * @return SimpleMail
  124. */
  125. public function setSubject($subject)
  126. {
  127. $this->_subject = $this->encodeUtf8(
  128. $this->filterOther((string) $subject)
  129. );
  130. return $this;
  131. }
  132. /**
  133. * getSubject function.
  134. *
  135. * @return string
  136. */
  137. public function getSubject()
  138. {
  139. return $this->_subject;
  140. }
  141. /**
  142. * setMessage
  143. *
  144. * @param string $message The message to send.
  145. *
  146. * @return SimpleMail
  147. */
  148. public function setMessage($message)
  149. {
  150. $this->_message = str_replace("\n.", "\n..", (string) $message);
  151. return $this;
  152. }
  153. /**
  154. * getMessage
  155. *
  156. * @return string
  157. */
  158. public function getMessage()
  159. {
  160. return $this->_message;
  161. }
  162. /**
  163. * addAttachment
  164. *
  165. * @param string $path The file path to the attachment.
  166. * @param string $filename The filename of the attachment when emailed.
  167. *
  168. * @return SimpleMail
  169. */
  170. public function addAttachment($path, $filename = null)
  171. {
  172. $filename = empty($filename) ? basename($path) : $filename;
  173. $this->_attachments[] = array(
  174. 'path' => $path,
  175. 'file' => $filename,
  176. 'data' => $this->getAttachmentData($path)
  177. );
  178. return $this;
  179. }
  180. /**
  181. * getAttachmentData
  182. *
  183. * @param string $path The path to the attachment file.
  184. *
  185. * @return string
  186. */
  187. public function getAttachmentData($path)
  188. {
  189. $filesize = filesize($path);
  190. $handle = fopen($path, "r");
  191. $attachment = fread($handle, $filesize);
  192. fclose($handle);
  193. return chunk_split(base64_encode($attachment));
  194. }
  195. /**
  196. * setFrom
  197. *
  198. * @param string $email The email to send as from.
  199. * @param string $name The name to send as from.
  200. *
  201. * @return SimpleMail
  202. */
  203. public function setFrom($email, $name)
  204. {
  205. $this->addMailHeader('From', (string) $email, (string) $name);
  206. return $this;
  207. }
  208. /**
  209. * addMailHeader
  210. *
  211. * @param string $header The header to add.
  212. * @param string $email The email to add.
  213. * @param string $name The name to add.
  214. *
  215. * @return SimpleMail
  216. */
  217. public function addMailHeader($header, $email = null, $name = null)
  218. {
  219. $address = $this->formatHeader((string) $email, (string) $name);
  220. $this->_headers[] = sprintf('%s: %s', (string) $header, $address);
  221. return $this;
  222. }
  223. /**
  224. * addGenericHeader
  225. *
  226. * @param string $header The generic header to add.
  227. * @param mixed $value The value of the header.
  228. *
  229. * @return SimpleMail
  230. */
  231. public function addGenericHeader($header, $value)
  232. {
  233. $this->_headers[] = sprintf(
  234. '%s: %s',
  235. (string) $header,
  236. (string) $value
  237. );
  238. return $this;
  239. }
  240. /**
  241. * getHeaders
  242. *
  243. * Return the headers registered so far as an array.
  244. *
  245. * @return array
  246. */
  247. public function getHeaders()
  248. {
  249. return $this->_headers;
  250. }
  251. /**
  252. * setAdditionalParameters
  253. *
  254. * Such as "-fyouremail@yourserver.com
  255. *
  256. * @param string $additionalParameters The addition mail parameter.
  257. *
  258. * @return SimpleMail
  259. */
  260. public function setParameters($additionalParameters)
  261. {
  262. $this->_params = (string) $additionalParameters;
  263. return $this;
  264. }
  265. /**
  266. * getAdditionalParameters
  267. *
  268. * @return string
  269. */
  270. public function getParameters()
  271. {
  272. return $this->_params;
  273. }
  274. /**
  275. * setWrap
  276. *
  277. * @param int $wrap The number of characters at which the message will wrap.
  278. *
  279. * @return SimpleMail
  280. */
  281. public function setWrap($wrap = 78)
  282. {
  283. $wrap = (int) $wrap;
  284. if ($wrap < 1) {
  285. $wrap = 78;
  286. }
  287. $this->_wrap = $wrap;
  288. return $this;
  289. }
  290. /**
  291. * getWrap
  292. *
  293. * @return int
  294. */
  295. public function getWrap()
  296. {
  297. return $this->_wrap;
  298. }
  299. /**
  300. * hasAttachments
  301. *
  302. * Checks if the email has any registered attachments.
  303. *
  304. * @return bool
  305. */
  306. public function hasAttachments()
  307. {
  308. return !empty($this->_attachments);
  309. }
  310. /**
  311. * assembleAttachment
  312. *
  313. * @return string
  314. */
  315. public function assembleAttachmentHeaders()
  316. {
  317. $head = array();
  318. $head[] = "MIME-Version: 1.0";
  319. $head[] = "Content-Type: multipart/mixed; boundary=\"{$this->_uid}\"";
  320. return join(PHP_EOL, $head);
  321. }
  322. /**
  323. * assembleAttachmentBody
  324. *
  325. * @return string
  326. */
  327. public function assembleAttachmentBody()
  328. {
  329. $body = array();
  330. $body[] = "This is a multi-part message in MIME format.";
  331. $body[] = "--{$this->_uid}";
  332. $body[] = "Content-type:text/html; charset=\"utf-8\"";
  333. $body[] = "Content-Transfer-Encoding: 7bit";
  334. $body[] = "";
  335. $body[] = $this->_message;
  336. $body[] = "";
  337. $body[] = "--{$this->_uid}";
  338. foreach ($this->_attachments as $attachment) {
  339. $body[] = $this->getAttachmentMimeTemplate($attachment);
  340. }
  341. return implode(PHP_EOL, $body);
  342. }
  343. /**
  344. * getAttachmentMimeTemplate
  345. *
  346. * @param array $attachment An array containing 'file' and 'data' keys.
  347. * @param string $uid A unique identifier for the boundary.
  348. *
  349. * @return string
  350. */
  351. public function getAttachmentMimeTemplate($attachment)
  352. {
  353. $file = $attachment['file'];
  354. $data = $attachment['data'];
  355. $head = array();
  356. $head[] = "Content-Type: application/octet-stream; name=\"{$file}\"";
  357. $head[] = "Content-Transfer-Encoding: base64";
  358. $head[] = "Content-Disposition: attachment; filename=\"{$file}\"";
  359. $head[] = "";
  360. $head[] = $data;
  361. $head[] = "";
  362. $head[] = "--{$this->_uid}";
  363. return implode(PHP_EOL, $head);
  364. }
  365. /**
  366. * send
  367. *
  368. * @throws \RuntimeException on no 'To: ' address to send to.
  369. * @return boolean
  370. */
  371. public function send()
  372. {
  373. $to = $this->getToForSend();
  374. $headers = $this->getHeadersForSend();
  375. if (empty($to)) {
  376. throw new \RuntimeException(
  377. 'Unable to send, no To address has been set.'
  378. );
  379. }
  380. if ($this->hasAttachments()) {
  381. $message = $this->assembleAttachmentBody();
  382. $headers .= PHP_EOL . $this->assembleAttachmentHeaders();
  383. } else {
  384. $message = $this->getWrapMessage();
  385. }
  386. return mail($to, $this->_subject, $message, $headers, $this->_params);
  387. }
  388. /**
  389. * debug
  390. *
  391. * @return string
  392. */
  393. public function debug()
  394. {
  395. return '<pre>' . print_r($this, true) . '</pre>';
  396. }
  397. /**
  398. * magic __toString function
  399. *
  400. * @return string
  401. */
  402. public function __toString()
  403. {
  404. return print_r($this, true);
  405. }
  406. /**
  407. * formatHeader
  408. *
  409. * Formats a display address for emails according to RFC2822 e.g.
  410. * Name <address@domain.tld>
  411. *
  412. * @param string $email The email address.
  413. * @param string $name The display name.
  414. *
  415. * @return string
  416. */
  417. public function formatHeader($email, $name = null)
  418. {
  419. $email = $this->filterEmail($email);
  420. if (empty($name)) {
  421. return $email;
  422. }
  423. $name = $this->encodeUtf8($this->filterName($name));
  424. return sprintf('"%s" <%s>', $name, $email);
  425. }
  426. /**
  427. * encodeUtf8
  428. *
  429. * @param string $value The value to encode.
  430. *
  431. * @return string
  432. */
  433. public function encodeUtf8($value)
  434. {
  435. $value = trim($value);
  436. if (preg_match('/(\s)/', $value)) {
  437. return $this->encodeUtf8Words($value);
  438. }
  439. return $this->encodeUtf8Word($value);
  440. }
  441. /**
  442. * encodeUtf8Word
  443. *
  444. * @param string $value The word to encode.
  445. *
  446. * @return string
  447. */
  448. public function encodeUtf8Word($value)
  449. {
  450. return sprintf('=?UTF-8?B?%s?=', base64_encode($value));
  451. }
  452. /**
  453. * encodeUtf8Words
  454. *
  455. * @param string $value The words to encode.
  456. *
  457. * @return string
  458. */
  459. public function encodeUtf8Words($value)
  460. {
  461. $words = explode(' ', $value);
  462. $encoded = array();
  463. foreach ($words as $word) {
  464. $encoded[] = $this->encodeUtf8Word($word);
  465. }
  466. return join($this->encodeUtf8Word(' '), $encoded);
  467. }
  468. /**
  469. * filterEmail
  470. *
  471. * Removes any carriage return, line feed, tab, double quote, comma
  472. * and angle bracket characters before sanitizing the email address.
  473. *
  474. * @param string $email The email to filter.
  475. *
  476. * @return string
  477. */
  478. public function filterEmail($email)
  479. {
  480. $rule = array(
  481. "\r" => '',
  482. "\n" => '',
  483. "\t" => '',
  484. '"' => '',
  485. ',' => '',
  486. '<' => '',
  487. '>' => ''
  488. );
  489. $email = strtr($email, $rule);
  490. $email = filter_var($email, FILTER_SANITIZE_EMAIL);
  491. return $email;
  492. }
  493. /**
  494. * filterName
  495. *
  496. * Removes any carriage return, line feed or tab characters. Replaces
  497. * double quotes with single quotes and angle brackets with square
  498. * brackets, before sanitizing the string and stripping out html tags.
  499. *
  500. * @param string $name The name to filter.
  501. *
  502. * @return string
  503. */
  504. public function filterName($name)
  505. {
  506. $rule = array(
  507. "\r" => '',
  508. "\n" => '',
  509. "\t" => '',
  510. '"' => "'",
  511. '<' => '[',
  512. '>' => ']',
  513. );
  514. $filtered = filter_var(
  515. $name,
  516. FILTER_SANITIZE_STRING,
  517. FILTER_FLAG_NO_ENCODE_QUOTES
  518. );
  519. return trim(strtr($filtered, $rule));
  520. }
  521. /**
  522. * filterOther
  523. *
  524. * Removes ASCII control characters including any carriage return, line
  525. * feed or tab characters.
  526. *
  527. * @param string $data The data to filter.
  528. *
  529. * @return string
  530. */
  531. public function filterOther($data)
  532. {
  533. return filter_var($data, FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW);
  534. }
  535. /**
  536. * getHeadersForSend
  537. *
  538. * @return string
  539. */
  540. public function getHeadersForSend()
  541. {
  542. if (empty($this->_headers)) {
  543. return '';
  544. }
  545. return join(PHP_EOL, $this->_headers);
  546. }
  547. /**
  548. * getToForSend
  549. *
  550. * @return string
  551. */
  552. public function getToForSend()
  553. {
  554. if (empty($this->_to)) {
  555. return '';
  556. }
  557. return join(', ', $this->_to);
  558. }
  559. /**
  560. * getUniqueId
  561. *
  562. * @return string
  563. */
  564. public function getUniqueId()
  565. {
  566. return md5(uniqid(time()));
  567. }
  568. /**
  569. * getWrapMessage
  570. *
  571. * @return string
  572. */
  573. public function getWrapMessage()
  574. {
  575. return wordwrap($this->_message, $this->_wrap);
  576. }
  577. }