PageRenderTime 68ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 0ms

/system/application/libraries/Postmark.php

https://github.com/stevefrost/postmark-codeigniter
PHP | 603 lines | 408 code | 62 blank | 133 comment | 57 complexity | bc1d957f3e6f4e56e5ad780123cffc82 MD5 | raw file
  1. <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
  2. /**
  3. * Postmark Email Library
  4. *
  5. * Permits email to be sent using Postmarkapp.com's Servers
  6. *
  7. * @category Libraries
  8. * @author Based on work by János Rusiczki & Markus Hedlund’s.
  9. * @modified Heavily Modified by Zack Kitzmiller
  10. * @modified Further modified by Steve Frost
  11. * @link http://www.github.com/stevefrost/postmark-codeigniter
  12. */
  13. class Postmark {
  14. //private
  15. private $CI
  16. , $api_key = ''
  17. , $validation = FALSE
  18. , $strip_html = FALSE
  19. , $develop = FALSE
  20. , $from_name
  21. , $from_address
  22. , $_reply_to_name
  23. , $_reply_to_address
  24. , $_to_name
  25. , $_to_address
  26. , $_cc_name
  27. , $_cc_address
  28. , $_bcc_address
  29. , $_subject
  30. , $_message_plain
  31. , $_message_html
  32. , $_tag
  33. , $_attachments = array();
  34. /**
  35. * Postmark::__construct
  36. *
  37. * @access public
  38. * @param array initialization parameters
  39. */
  40. public function __construct($params = array())
  41. {
  42. $this->CI =& get_instance();
  43. if (count($params) > 0)
  44. {
  45. $this->initialize($params);
  46. }
  47. if ($this->develop == TRUE)
  48. {
  49. $this->api_key = 'POSTMARK_API_TEST';
  50. }
  51. log_message('debug', 'Postmark Class Initialized');
  52. }
  53. /**
  54. * Initialize Preferences
  55. *
  56. * @access public
  57. * @param array initialization parameters
  58. * @return void
  59. */
  60. public function initialize($params)
  61. {
  62. $this->clear();
  63. if (count($params) > 0)
  64. {
  65. foreach ($params as $key => $value)
  66. {
  67. if (isset($this->$key))
  68. {
  69. $this->$key = $value;
  70. }
  71. }
  72. }
  73. }
  74. /**
  75. * Clear the Email Data
  76. *
  77. * @access public
  78. * @return void
  79. */
  80. public function clear()
  81. {
  82. $this->from_name = '';
  83. $this->from_address = '';
  84. $this->_to_name = '';
  85. $this->_to_address = '';
  86. $this->_cc_name = '';
  87. $this->_cc_address = '';
  88. $this->_subject = '';
  89. $this->_message_plain = '';
  90. $this->_message_html = '';
  91. $this->_tag = '';
  92. $this->_attachments = array();
  93. }
  94. /**
  95. * Set Email FROM address
  96. *
  97. * This could also be set in the config file
  98. *
  99. * TODO:
  100. * Validate Email Addresses ala CodeIgniter's Email Class
  101. *
  102. * @access public
  103. * @return void
  104. */
  105. public function from($address, $name = NULL)
  106. {
  107. if ( ! $this->validation == TRUE)
  108. {
  109. $this->from_address = $address;
  110. $this->from_name = $name;
  111. }
  112. else
  113. {
  114. if ($this->_validate_email($address))
  115. {
  116. $this->from_address = $address;
  117. $this->from_name = $name;
  118. }
  119. else
  120. {
  121. show_error('You have entered an invalid sender address.');
  122. }
  123. }
  124. }
  125. /**
  126. * Set Email TO address
  127. *
  128. * TODO:
  129. * Validate Email Addresses ala CodeIgniter's Email Class
  130. *
  131. * @access public
  132. * @return void
  133. */
  134. public function to($address, $name = NULL)
  135. {
  136. if ( ! $this->validation == TRUE)
  137. {
  138. $this->_to_address = $address;
  139. $this->_to_name = $name;
  140. }
  141. else
  142. {
  143. if ($this->_validate_email($address))
  144. {
  145. $this->_to_address = $address;
  146. $this->_to_name = $name;
  147. }
  148. else
  149. {
  150. show_error('You have entered an invalid recipient address.');
  151. }
  152. }
  153. }
  154. /**
  155. * Set Email ReplyTo address
  156. *
  157. * TODO:
  158. * Validate Email Addresses ala CodeIgniter's Email Class
  159. *
  160. * @access public
  161. * @return void
  162. */
  163. public function reply_to($address, $name = NULL)
  164. {
  165. if ( ! $this->validation == TRUE)
  166. {
  167. $this->_reply_to_address = $address;
  168. $this->_reply_to_name = $name;
  169. }
  170. else
  171. {
  172. if ($this->_validate_email($address))
  173. {
  174. $this->_reply_to_address = $address;
  175. $this->_reply_to_name = $name;
  176. }
  177. else
  178. {
  179. show_error('You have entered an invalid reply to address.');
  180. }
  181. }
  182. }
  183. /**
  184. * Set Email CC address
  185. *
  186. * TODO:
  187. * Validate Email Addresses ala CodeIgniter's Email Class
  188. *
  189. * @access public
  190. * @return void
  191. */
  192. public function cc($address, $name = NULL)
  193. {
  194. if ( ! $this->validation == TRUE)
  195. {
  196. $this->_cc_address = $address;
  197. $this->_cc_name = $name;
  198. }
  199. else
  200. {
  201. if ($this->_validate_email($address))
  202. {
  203. $this->_cc_address = $address;
  204. $this->_cc_name = $name;
  205. }
  206. else
  207. {
  208. show_error('You have entered an invalid recipient address.');
  209. }
  210. }
  211. }
  212. /**
  213. * Set Email BCC address
  214. *
  215. * TODO:
  216. * Validate Email Addresses ala CodeIgniter's Email Class
  217. *
  218. * @access public
  219. * @return void
  220. * @author Adam Jackett, based on cc method
  221. */
  222. public function bcc($address)
  223. {
  224. if ( ! $this->validation == TRUE)
  225. {
  226. $this->_bcc_address = $address;
  227. }
  228. else
  229. {
  230. if ($this->_validate_email($address))
  231. {
  232. $this->_bcc_address = $address;
  233. }
  234. else
  235. {
  236. show_error('You have entered an invalid recipient address.');
  237. }
  238. }
  239. }
  240. /**
  241. * Set Email Subject
  242. *
  243. * @access public
  244. * @return void
  245. */
  246. public function subject($subject)
  247. {
  248. $this->_subject = $subject;
  249. }
  250. /**
  251. * Set Tag
  252. *
  253. * @access public
  254. * @return void
  255. */
  256. public function tag($tag)
  257. {
  258. $this->_tag = $tag;
  259. }
  260. /**
  261. * Set Email Message in Plain Text
  262. *
  263. * @access public
  264. * @return void
  265. */
  266. public function message_plain($message)
  267. {
  268. if ( ! $this->strip_html)
  269. {
  270. $this->_message_plain = $message;
  271. }
  272. else
  273. {
  274. $this->_message_plain = $this->_strip_html($message);
  275. }
  276. }
  277. /**
  278. * Set Email Message in HTML
  279. *
  280. * @access public
  281. * @return void
  282. */
  283. public function message_html($message)
  284. {
  285. $this->_message_html = $message;
  286. }
  287. /**
  288. * Add an attachment
  289. *
  290. * @access public
  291. * @return void
  292. */
  293. public function attach($file, $filename = FALSE)
  294. {
  295. $filesize = filesize($file) + 1;
  296. if ( ! $fp = fopen($file, FOPEN_READ))
  297. {
  298. return FALSE;
  299. }
  300. $content = chunk_split(base64_encode(fread($fp, $filesize)));
  301. fclose($fp);
  302. if(!$filename) $filename = end(explode('/', $file));
  303. $this->_attachments[] = array(
  304. 'Name' => $filename
  305. , 'Content' => $content
  306. , 'ContentType' => $this->_mime_types(end(explode('.', basename($filename))))
  307. );
  308. return TRUE;
  309. }
  310. /**
  311. * Private Function to prepare and send email
  312. */
  313. private function _prepare_data()
  314. {
  315. $data = array();
  316. $data['Subject'] = $this->_subject;
  317. $data['From'] = is_null($this->from_name) ? $this->from_address : "{$this->from_name} <{$this->from_address}>";
  318. $data['To'] = is_null($this->_to_name) ? $this->_to_address : "{$this->_to_name} <{$this->_to_address}>";
  319. if ( ! is_null($this->_cc_address) && ($this->_cc_address != ''))
  320. {
  321. $data['Cc'] = is_null($this->_cc_name) ? $this->_cc_address : "{$this->_cc_name} <{$this->_cc_address}>";
  322. }
  323. if ( ! is_null($this->_bcc_address) && ($this->_bcc_address != ''))
  324. {
  325. $data['Bcc'] = $this->_bcc_address;
  326. }
  327. if ( ! is_null($this->_reply_to_address) && ($this->_reply_to_address != ''))
  328. {
  329. $data['ReplyTo'] = is_null($this->_reply_to_name) ? $this->_reply_to_address : "{$this->_reply_to_name} <{$this->_reply_to_address}>";
  330. }
  331. if ( ! is_null($this->_tag) && ($this->_tag != ''))
  332. {
  333. $data['tag'] = $this->_tag;
  334. }
  335. if ( ! is_null($this->_message_html))
  336. {
  337. $data['HtmlBody'] = $this->_message_html;
  338. }
  339. if ( ! is_null($this->_message_plain))
  340. {
  341. $data['TextBody'] = $this->_message_plain;
  342. }
  343. if(count($this->_attachments) > 0)
  344. {
  345. $data['Attachments'] = $this->_attachments;
  346. }
  347. return $data;
  348. }
  349. function send($from_address = NULL, $from_name = NULL, $to_address = NULL, $to_name = NULL, $subject = NULL, $message_plain = NULL, $message_html = NULL)
  350. {
  351. if ( ! function_exists('curl_init'))
  352. {
  353. if(function_exists('log_message'))
  354. {
  355. log_message('error', 'Postmark - PHP was not built with cURL enabled. Rebuild PHP with --with-curl to use cURL.');
  356. }
  357. return FALSE;
  358. }
  359. if ( ! is_null($from_address)) $this->from($from_address, $from_name);
  360. if ( ! is_null($to_address)) $this->to($to_address, $to_name);
  361. if ( ! is_null($subject)) $this->subject($subject);
  362. if ( ! is_null($message_plain)) $this->message_plain($message_plain);
  363. if ( ! is_null($message_html)) $this->message_html($message_html);
  364. if (is_null($this->api_key))
  365. {
  366. show_error("Postmark API key is not set!");
  367. }
  368. if (is_null($this->from_address))
  369. {
  370. show_error("From address is not set!");
  371. }
  372. if (is_null($this->_to_address))
  373. {
  374. show_error("To address is not set!");
  375. }
  376. if (is_null($this->_subject))
  377. {
  378. show_error("Subject is not set!");
  379. }
  380. if (is_null($this->_message_plain) && is_null($this->_message_html))
  381. {
  382. show_error("Please either set plain message, HTML message or both!");
  383. }
  384. $encoded_data = json_encode($this->_prepare_data());
  385. $headers = array(
  386. 'Accept: application/json'
  387. , 'Content-Type: application/json'
  388. , 'X-Postmark-Server-Token: '.$this->api_key
  389. );
  390. $ch = curl_init();
  391. curl_setopt($ch, CURLOPT_URL, 'http://api.postmarkapp.com/email');
  392. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  393. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
  394. curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data);
  395. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  396. $return = curl_exec($ch);
  397. log_message('debug', 'POSTMARK JSON: '.$encoded_data."\nHeaders: \n\t".implode("\n\t", $headers)."\nReturn:\n$return");
  398. if (curl_error($ch) != '')
  399. {
  400. show_error(curl_error($ch));
  401. }
  402. $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  403. log_message('debug', 'POSTMARK http code:'.$http_code);
  404. if (intval($http_code / 100) != 2)
  405. {
  406. $message = json_decode($return)->Message;
  407. show_error('Error while mailing. Postmark returned HTTP code '.$http_code.' with message "'.$message.'"');
  408. }
  409. }
  410. /**
  411. * Email Validation
  412. *
  413. * @access protected
  414. * @param string
  415. * @return bool
  416. */
  417. protected function _validate_email($address)
  418. {
  419. $addresses = explode(',', $address);
  420. foreach($addresses as $k => $v)
  421. {
  422. if ( ! preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", trim($v)))
  423. {
  424. return FALSE;
  425. }
  426. }
  427. return TRUE;
  428. }
  429. /**
  430. * Strip Html
  431. *
  432. * @access protected
  433. * @param string
  434. * @return string
  435. */
  436. protected function _strip_html($message)
  437. {
  438. $message = preg_replace('/\<br(\s*)?\/?\>/i', "\n", $message);
  439. return strip_tags($message);
  440. }
  441. /**
  442. * Mime Types
  443. *
  444. * @access private
  445. * @param string
  446. * @return string
  447. */
  448. private function _mime_types($ext = "")
  449. {
  450. $mimes = array(
  451. 'hqx' => 'application/mac-binhex40',
  452. 'cpt' => 'application/mac-compactpro',
  453. 'doc' => 'application/msword',
  454. 'bin' => 'application/macbinary',
  455. 'dms' => 'application/octet-stream',
  456. 'lha' => 'application/octet-stream',
  457. 'lzh' => 'application/octet-stream',
  458. 'exe' => 'application/octet-stream',
  459. 'class' => 'application/octet-stream',
  460. 'psd' => 'application/octet-stream',
  461. 'so' => 'application/octet-stream',
  462. 'sea' => 'application/octet-stream',
  463. 'dll' => 'application/octet-stream',
  464. 'oda' => 'application/oda',
  465. 'pdf' => 'application/pdf',
  466. 'ai' => 'application/postscript',
  467. 'eps' => 'application/postscript',
  468. 'ps' => 'application/postscript',
  469. 'smi' => 'application/smil',
  470. 'smil' => 'application/smil',
  471. 'mif' => 'application/vnd.mif',
  472. 'xls' => 'application/vnd.ms-excel',
  473. 'ppt' => 'application/vnd.ms-powerpoint',
  474. 'wbxml' => 'application/vnd.wap.wbxml',
  475. 'wmlc' => 'application/vnd.wap.wmlc',
  476. 'dcr' => 'application/x-director',
  477. 'dir' => 'application/x-director',
  478. 'dxr' => 'application/x-director',
  479. 'dvi' => 'application/x-dvi',
  480. 'gtar' => 'application/x-gtar',
  481. 'php' => 'application/x-httpd-php',
  482. 'php4' => 'application/x-httpd-php',
  483. 'php3' => 'application/x-httpd-php',
  484. 'phtml' => 'application/x-httpd-php',
  485. 'phps' => 'application/x-httpd-php-source',
  486. 'js' => 'application/x-javascript',
  487. 'swf' => 'application/x-shockwave-flash',
  488. 'sit' => 'application/x-stuffit',
  489. 'tar' => 'application/x-tar',
  490. 'tgz' => 'application/x-tar',
  491. 'xhtml' => 'application/xhtml+xml',
  492. 'xht' => 'application/xhtml+xml',
  493. 'zip' => 'application/zip',
  494. 'mid' => 'audio/midi',
  495. 'midi' => 'audio/midi',
  496. 'mpga' => 'audio/mpeg',
  497. 'mp2' => 'audio/mpeg',
  498. 'mp3' => 'audio/mpeg',
  499. 'aif' => 'audio/x-aiff',
  500. 'aiff' => 'audio/x-aiff',
  501. 'aifc' => 'audio/x-aiff',
  502. 'ram' => 'audio/x-pn-realaudio',
  503. 'rm' => 'audio/x-pn-realaudio',
  504. 'rpm' => 'audio/x-pn-realaudio-plugin',
  505. 'ra' => 'audio/x-realaudio',
  506. 'rv' => 'video/vnd.rn-realvideo',
  507. 'wav' => 'audio/x-wav',
  508. 'bmp' => 'image/bmp',
  509. 'gif' => 'image/gif',
  510. 'jpeg' => 'image/jpeg',
  511. 'jpg' => 'image/jpeg',
  512. 'jpe' => 'image/jpeg',
  513. 'png' => 'image/png',
  514. 'tiff' => 'image/tiff',
  515. 'tif' => 'image/tiff',
  516. 'css' => 'text/css',
  517. 'html' => 'text/html',
  518. 'htm' => 'text/html',
  519. 'shtml' => 'text/html',
  520. 'txt' => 'text/plain',
  521. 'text' => 'text/plain',
  522. 'log' => 'text/plain',
  523. 'rtx' => 'text/richtext',
  524. 'rtf' => 'text/rtf',
  525. 'xml' => 'text/xml',
  526. 'xsl' => 'text/xml',
  527. 'mpeg' => 'video/mpeg',
  528. 'mpg' => 'video/mpeg',
  529. 'mpe' => 'video/mpeg',
  530. 'qt' => 'video/quicktime',
  531. 'mov' => 'video/quicktime',
  532. 'avi' => 'video/x-msvideo',
  533. 'movie' => 'video/x-sgi-movie',
  534. 'doc' => 'application/msword',
  535. 'word' => 'application/msword',
  536. 'xl' => 'application/excel',
  537. 'eml' => 'message/rfc822'
  538. );
  539. return ( ! isset($mimes[strtolower($ext)])) ? 'application/x-unknown-content-type' : $mimes[strtolower($ext)];
  540. }
  541. }