PageRenderTime 54ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/mail/cfEMail.class.php

https://bitbucket.org/cyberfox/cyberfox-php-framework
PHP | 610 lines | 235 code | 52 blank | 323 comment | 32 complexity | c0c3eaaa4d4fb0746f91a36e6e79eb84 MD5 | raw file
Possible License(s): LGPL-3.0
  1. <?php
  2. /**
  3. -----------------------------------------------------------------------------
  4. * eMAIL BASE SENDER
  5. *
  6. * Based on PEAR::Mail this class provides you to generate and send an email over sendmail or smtp.
  7. * @link http://pear.php.net/manual/en/package.mail.mail.intro.php
  8. * @link http://pear.php.net/manual/en/package.mail.mail-mime.php
  9. * @link http://www.faqs.org/rfcs/rfc822 RFC822
  10. *
  11. -----------------------------------------------------------------------------
  12. -----------------------------------------------------------------------------
  13. * @copyright (C) 2011 Cyberfox Software Solutions e.U.
  14. * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License version 3 (LGPLv3)
  15. * @author Christian Graf <christian.graf@cyberfox.at>
  16. -----------------------------------------------------------------------------
  17. -----------------------------------------------------------------------------
  18. * @package redfox
  19. * @subpackage messaging
  20. * @category communication
  21. -----------------------------------------------------------------------------
  22. -----------------------------------------------------------------------------
  23. * @version $Id: cfEMail.class.php 105 2012-06-28 06:55:45Z cgraf $
  24. * @date $Date: 2012-06-28 08:55:45 +0200 (Do, 28 Jun 2012) $
  25. * @svnauthor $Author: cgraf $
  26. -----------------------------------------------------------------------------
  27. */
  28. /**
  29. * Include the PEAR::Mail class to work with.
  30. * @link http://pear.php.net/manual/en/package.mail.mail.php
  31. */
  32. require_once('Mail.php'); //PEAR CLASS
  33. /**
  34. * Include the PEAR::Mail_mime class to work with.
  35. * @link http://pear.php.net/manual/en/package.mail.mail-mime.php
  36. */
  37. require_once('Mail/mime.php'); //PEAR CLASS
  38. class cfEMail
  39. {
  40. /**
  41. * CRLF = Carriage Return Line Feed
  42. *
  43. * @var char
  44. * @access public
  45. */
  46. const CRLF = "\n";
  47. /**
  48. * The current mime object
  49. * @link http://pear.php.net/manual/en/package.mail.mail-mime.php
  50. *
  51. * @var Mail_mime
  52. * @access private
  53. */
  54. private $mimeObj = null;
  55. /**
  56. * The current mailer object
  57. * @link http://pear.php.net/manual/en/package.mail.mail.php
  58. *
  59. * @var Mail
  60. * @access private
  61. */
  62. private $mailObj = null;
  63. /**
  64. * The current factory (sending type).
  65. * Only sendmail or smtp currently supported
  66. *
  67. * @var string
  68. * @access private
  69. */
  70. private $factory = null;
  71. /**
  72. * List of supported sending types.
  73. * Only sendmail or smtp currently supported
  74. *
  75. * @var array
  76. * @access private
  77. */
  78. private $availableFactories = array('sendmail', 'smtp', 'mail', 'null');
  79. /**
  80. * List of available recipients.
  81. * Add it with the methods addBcc() or addCc()
  82. *
  83. * @var array
  84. * @access private
  85. */
  86. private $recipients = array();
  87. /**
  88. * Constructor
  89. *
  90. * Creates a new instance from PEAR::Mail_mime
  91. * @link http://pear.php.net/manual/en/package.mail.mail-mime.php
  92. *
  93. * @return void
  94. * @access public
  95. */
  96. public function __construct()
  97. {
  98. $this->mimeObj = new Mail_mime(self::CRLF);
  99. $this->factory = 'sendmail';
  100. }
  101. /**
  102. * setFactory()
  103. *
  104. * Set the "sending" type of the email.
  105. * Only supported factories are allowed. Current there are sending via sendmail or smtp
  106. *
  107. * @return void
  108. * @access public
  109. */
  110. public function SetFactory($Factory)
  111. {
  112. if(!empty($Factory) && in_array(strtolower($Factory), $this->availableFactories) )
  113. $this->factory = strtolower($Factory);
  114. return;
  115. }
  116. /**
  117. * GetFactory()
  118. *
  119. * Returns the current set factory
  120. *
  121. * @return string The current set factory
  122. * @access public
  123. */
  124. public function GetFactory()
  125. {
  126. if(empty($this->factory)) return 'null';
  127. return $this->factory;
  128. }
  129. /**
  130. * getAvailableFactories()
  131. *
  132. * Returns the list of all supported email factories
  133. *
  134. * @return array Assoc array of all supported email factories
  135. * @access public
  136. */
  137. public function GetAvailableFactories()
  138. {
  139. if(empty($this->availableFactories)) return array('null');
  140. return $this->availableFactories;
  141. }
  142. /**
  143. * GetMimeObj()
  144. *
  145. * Get the current mime object as reference.
  146. * @link http://pear.php.net/manual/en/package.mail.mail-mime.mail-mime.php
  147. *
  148. * @return Mail_mime The current mime object as reference
  149. * @access public
  150. */
  151. public function &GetMimeObj()
  152. {
  153. return $this->mimeObj;
  154. }
  155. /**
  156. * GetMailObj()
  157. *
  158. * Get the current mailer object as reference.
  159. * @link http://pear.php.net/manual/en/package.mail.mail.factory.php
  160. *
  161. * @return Mail The current mailer object as reference.
  162. * @access public
  163. */
  164. public function &GetMailObj()
  165. {
  166. if(is_null($this->mailObj))
  167. {
  168. switch($this->GetFactory())
  169. {
  170. case 'smtp':
  171. {
  172. $settings = $this->GetSmtpSettings();
  173. $this->mailObj =& Mail::factory('smtp', $settings);
  174. }
  175. break;
  176. case 'sendmail':
  177. {
  178. $settings = $this->GetSendmailSettings();
  179. $this->mailObj =& Mail::factory('sendmail', $settings);
  180. }
  181. break;
  182. case 'mail':
  183. {
  184. $this->mailObj =& Mail::factory('mail', array());
  185. }
  186. default:
  187. {
  188. $this->mailObj =& Mail::factory('null', array());
  189. }
  190. break;
  191. }
  192. }
  193. return $this->mailObj;
  194. }
  195. /**
  196. * setFrom()
  197. *
  198. * Set the "from" part of the eMail.
  199. *
  200. * @param string $From The email address where the email is came from.
  201. * @return void
  202. * @access public
  203. */
  204. public function SetFrom($From)
  205. {
  206. $this->mimeObj->setFrom($From);
  207. }
  208. /**
  209. * addCc()
  210. *
  211. * Add an "carbon copy (cc)" receptient to the eMail.
  212. *
  213. * Wrapper for Mail_mime::addCc()
  214. * @link http://pear.php.net/package/Mail_Mime/docs/latest/Mail_Mime/Mail_mime.html#methodaddCc
  215. *
  216. * Note: No email syntax verification implemented yet.
  217. *
  218. * @param string $Email The email address of the receptient
  219. * @return void
  220. * @access public
  221. */
  222. public function AddCc($Email)
  223. {
  224. $this->mimeObj->addCc($Email);
  225. $this->recipients[] = $Email;
  226. }
  227. /**
  228. * addBcc()
  229. *
  230. * Add an "blind carbon copy (bcc)" receptient to the eMail.
  231. *
  232. * Wrapper for Mail_mime::addBcc()
  233. * @link http://pear.php.net/package/Mail_Mime/docs/latest/Mail_Mime/Mail_mime.html#methodaddBcc
  234. *
  235. * Note: No email syntax verification implemented yet.
  236. *
  237. * @param string $Email The email address of the receptient
  238. * @return void
  239. * @access public
  240. */
  241. public function AddBcc($Email)
  242. {
  243. $this->mimeObj->addBcc($Email);
  244. $this->recipients[] = $Email;
  245. }
  246. /**
  247. * setSubject()
  248. *
  249. * Set the "subject" part of the eMail.
  250. *
  251. * Wrapper for Mail_mime::setSubject()
  252. * @link http://pear.php.net/package/Mail_Mime/docs/latest/Mail_Mime/Mail_mime.html#methodsetSubject
  253. *
  254. * @param string $Subject The designated subject of the email
  255. * @return void
  256. * @access public
  257. */
  258. public function SetSubject($Subject)
  259. {
  260. $this->mimeObj->setSubject($Subject);
  261. }
  262. /**
  263. * setTextBody()
  264. *
  265. * Set the plain text part of the eMail.
  266. *
  267. * Wrapper for Mail_mime::setTXTBody()
  268. * @link http://pear.php.net/manual/en/package.mail.mail-mime.settxtbody.php
  269. *
  270. * If there is an error an exception will be thrown.
  271. *
  272. * @param string $Body The text to set or, if $Isfile is TRUE a valid filename. An URL as argument is not allowed.
  273. * @param bool $IsFile If TRUE, the content of given file $Body is used as message text.
  274. * @param bool $Append If TRUE, the content will be appended to the existing one.
  275. * @return bool TRUE if the body could be set successfully
  276. * @access public
  277. */
  278. public function SetTextBody($Body, $IsFile = false, $Append = false)
  279. {
  280. $status = $this->mimeObj->setTXTBody($Body, $IsFile, $Append);
  281. if(PEAR::isError($status))
  282. throw new cfException(__METHOD__ .': Could not set the mail body (text) => ' .$status->getMessage());
  283. return $status;
  284. }
  285. /**
  286. * setHtmlBody()
  287. *
  288. * Set the html part of the eMail
  289. *
  290. * Wrapper for Mail_mime::setHTMLBody()
  291. * @link http://pear.php.net/manual/en/package.mail.mail-mime.sethtmlbody.php
  292. *
  293. * @param string $Body The text to set or, if $Isfile is TRUE a valid filename. An URL as argument is not allowed.
  294. * @param bool $IsFile If TRUE, the content of given file $Body is used as message text.
  295. * @param bool $Append If TRUE, the content will be appended to the existing one.
  296. * @return bool TRUE if the body could be set successfully
  297. * @access public
  298. */
  299. public function SetHtmlBody($Body, $IsFile = false, $Append = false)
  300. {
  301. $status = $this->mimeObj->setHTMLBody($Body, $IsFile, $Append);
  302. if(PEAR::isError($status))
  303. throw new cfException(__METHOD__ .': Could not set the mail body (html) => ' .$status->getMessage());
  304. return $status;
  305. }
  306. /**
  307. * addHeaders()
  308. *
  309. * Build an array with the headers needed to prepend to the email (MIME-Version and Content-Type).
  310. *
  311. * Wrapper for Mail_mime::headers()
  312. * @link http://pear.php.net/manual/en/package.mail.mail-mime.headers.php
  313. *
  314. * @param array $Headers Additional headers, the format is $Headers["header-name"] = "header-value"
  315. * @param boolen $Override Overwrite already existing headers. When FALSE, the values already set are kept.
  316. * @return void
  317. * @access public
  318. */
  319. public function AddHeaders($Headers)
  320. {
  321. $this->mimeObj->headers($Headers, false);
  322. }
  323. /**
  324. * getHeaders()
  325. *
  326. * Returns an array with the headers needed to prepend to the email (MIME-Version and Content-Type).
  327. *
  328. * Wrapper for Mail_mime::headers()
  329. * @link http://pear.php.net/manual/en/package.mail.mail-mime.headers.php
  330. *
  331. * @return array The current defined header lines
  332. * @access public
  333. */
  334. public function GetHeaders()
  335. {
  336. return $this->mimeObj->headers();
  337. }
  338. /**
  339. * getPreparedHeaders()
  340. *
  341. * Returns an array with the headers needed to prepend to the email (MIME-Version and Content-Type).
  342. *
  343. * @return array The current defined header lines
  344. * @access public
  345. * @deprecated
  346. */
  347. public function GetPreparedHeaders($Headers = null)
  348. {
  349. if(empty($Headers)) $Headers = $this->getHeaders();
  350. $pHeaders = $this->GetMailObj()->prepareHeaders($Headers);
  351. if(!is_array($pHeaders) || sizeof($pHeaders) != 2)
  352. throw new cfException(__METHOD__ .': Could not prepare headers.');
  353. return $pHeaders;
  354. }
  355. /**
  356. * addAttachment()
  357. *
  358. * Adds a file to the list of attachments.
  359. *
  360. * Wrapper for Mail_mime::addAttachment()
  361. * @link http://pear.php.net/package/Mail_Mime/docs/latest/Mail_Mime/Mail_mime.html#methodaddAttachment
  362. *
  363. * @param string $File The file name of the file to attach OR the file contents itself
  364. * @param string $CType The content type. Defaults to "application/octet-stream"
  365. * @param string $Name The filename of the attachment. Only use if $File is the contents
  366. * @param bool $IsFile Whether $File is a filename or not. Defaults to true
  367. * @param string $Encoding The type of encoding to use. Defaults to base64. Possible values: 7bit, 8bit, base64 or quoted-printable.
  368. * @param string $Charset The character set used in the filename of this attachment.
  369. * @return bool Status
  370. * @access public
  371. */
  372. public function AddAttachment($File, $CType = 'application/octet-stream', $Name = '', $IsFile = true, $Encoding = 'base64', $Charset = '')
  373. {
  374. $status = $this->mimeObj->addAttachment($File, $CType, $Name, $IsFile, $Encoding, '', $Charset);
  375. if(PEAR::isError($status))
  376. throw new cfException(__METHOD__ .': Could not add attachment => ' .$status->getMessage());
  377. return $status;
  378. }
  379. /**
  380. * addHTMLImage()
  381. *
  382. * Adds an image to the list of embedded images.
  383. *
  384. * Wrapper for Mail_mime::addHTMLImage()
  385. * @link http://pear.php.net/package/Mail_Mime/docs/latest/Mail_Mime/Mail_mime.html#methodaddHTMLImage
  386. *
  387. * @param string $File The file name of the file to attach OR the file contents itself
  388. * @param string $CType The content type. Defaults to "application/octet-stream"
  389. * @param string $Name The filename of the attachment. Only use if $File is the contents
  390. * @param bool $IsFile Whether $File is a filename or not. Defaults to true
  391. * @return bool Status
  392. * @access public
  393. */
  394. public function AddHTMLImage($File, $CType = 'application/octet-stream', $Name = '', $IsFile = true)
  395. {
  396. $status = $this->mimeObj->addHTMLImage($File, $CType, $Name, $IsFile);
  397. if(PEAR::isError($status))
  398. throw new cfException(__METHOD__ .': Could not add HTML image => ' .$status->getMessage());
  399. return $status;
  400. }
  401. /**
  402. * GetSmtpSettings()
  403. *
  404. * Get SMPT settings from the config or set it to defaults to send via localhost.
  405. *
  406. * @return array Assoc array of the current defined settings
  407. * @access private
  408. */
  409. public function GetSmtpSettings()
  410. {
  411. $settings=array(
  412. 'host' => 'localhost',
  413. 'port' => 25,
  414. 'auth' => true,
  415. 'username' => '',
  416. 'password' => '',
  417. 'localhost' => 'localhost'
  418. );
  419. if(cfConfig::IsEntrySet('smtp_host', 'application'))
  420. {
  421. $settings['host'] = cfConfig::GetEntry('smtp_host', 'application');
  422. }
  423. if(cfConfig::IsEntrySet('smtp_port', 'application'))
  424. {
  425. $settings['port'] = cfConfig::GetEntry('smtp_port', 'application');
  426. }
  427. if(cfConfig::IsEntrySet('smtp_auth', 'application'))
  428. {
  429. $settings['auth'] = cfConfig::GetEntry('smtp_auth', 'application');
  430. }
  431. if(cfConfig::IsEntrySet('smtp_username', 'application'))
  432. {
  433. $settings['username'] = cfConfig::GetEntry('smtp_username', 'application');
  434. }
  435. if(cfConfig::IsEntrySet('smtp_password', 'application'))
  436. {
  437. $settings['password'] = cfConfig::GetEntry('smtp_password', 'application');
  438. }
  439. if(cfConfig::IsEntrySet('smtp_localhost', 'application'))
  440. {
  441. $settings['localhost'] = cfConfig::GetEntry('smtp_localhost', 'application');
  442. }
  443. if(empty($settings['username']) && empty($settings['password']) && ($settings['host'] == 'localhost' || $settings['host'] == '127.0.0.1'))
  444. {
  445. $settings['auth'] = false;
  446. }
  447. return $settings;
  448. }
  449. /**
  450. * GetSendmailSettings()
  451. *
  452. * Get sendmail settings from the config or set it to defaults.
  453. *
  454. * @return array Assoc array of the current defined settings
  455. * @access private
  456. */
  457. public function GetSendmailSettings()
  458. {
  459. $settings=array(
  460. 'sendmail_path' => '/usr/sbin/sendmail',
  461. 'sendmail_args' => '-i'
  462. );
  463. if(cfConfig::IsEntrySet('sendmail_path', 'application'))
  464. {
  465. $settings['sendmail_path'] = cfConfig::GetEntry('sendmail_path', 'application');
  466. }
  467. if(cfConfig::IsEntrySet('sendmail_args', 'application'))
  468. {
  469. $settings['sendmail_args'] = cfConfig::GetEntry('sendmail_args', 'application');
  470. }
  471. return $settings;
  472. }
  473. /**
  474. * getBody()
  475. *
  476. * Builds the multipart message and returns the mime content.
  477. *
  478. * Wrapper for Mail_mime::get()
  479. * @link http://pear.php.net/package/Mail_Mime/docs/latest/Mail_Mime/Mail_mime.html#methodget
  480. *
  481. * @return string The MIME message content string
  482. * @access public
  483. */
  484. public function GetBody()
  485. {
  486. $options = array(
  487. 'text_charset' => 'utf-8',
  488. 'html_charset' => 'utf-8',
  489. 'head_charset' => 'utf-8'
  490. );
  491. return $this->GetMimeObj()->get($options);
  492. }
  493. /**
  494. * After_send()
  495. *
  496. * OVERLOAD ME: Here you are able to put some additional actions after sending a mail.
  497. *
  498. * @param bool $Status Send status
  499. * @param Mail $MailObj The current mailer object
  500. * @param array $Options Additional options
  501. * @return void
  502. * @access protected
  503. */
  504. protected function After_send($Status, &$MailObj, $Options = array())
  505. {
  506. return;
  507. }
  508. /**
  509. * send()
  510. *
  511. * Send the eMail.
  512. *
  513. * If a error occured, an exception will be thrown.
  514. *
  515. * @param string $To eMail address of the receiptient. Format name@domain.com or "My Name <name@domain.com>"
  516. * @param string $Factory Send over sendmail or smtp
  517. * @param array $Options (optional) Additional options
  518. * @return bool Send status
  519. * @access public
  520. */
  521. public function Send($To, $Factory = null, $Options = array())
  522. {
  523. if(empty($To))
  524. throw new cfException(__METHOD__ .': Could not send the email => Invalid eMail address "' .$To .'"');
  525. if(!empty($Factory))
  526. $this->SetFactory(trim($Factory));
  527. $returnTo = '';
  528. $replyTo = '';
  529. if(isset($Options['return_to']))
  530. {
  531. $returnTo = $Options['return_to'];
  532. }
  533. if(isset($Options['reply_to']))
  534. {
  535. $replyTo = $Options['reply_to'];
  536. }
  537. $this->AddHeaders(array('Return-Path' => $returnTo, 'Reply-To' => $replyTo, 'To' => $To));
  538. $mailObj =& $this->GetMailObj();
  539. //SEND MAIL
  540. $recipients = array();
  541. $recipients = explode(',', $To);
  542. $recipients = array_merge($recipients, $this->recipients);
  543. $eMailBody = $this->GetBody();
  544. $eMailHeaders = $this->GetHeaders();
  545. cfLogger::Log('cfFramework')->Info('Try to send a email to: ' .print_r($recipients, true));
  546. $status = $mailObj->Send($recipients, $eMailHeaders, $eMailBody, $Options);
  547. if(PEAR::isError($status))
  548. {
  549. cfLogger::Log('cfFramework')->Error('Unable to send the email => ' .$status->getMessage());
  550. throw new cfException(__METHOD__ .': Unable to send the email => ' .$status->getMessage());
  551. }
  552. else
  553. cfLogger::Log('cfFramework')->Info('Send-Status: ' .print_r($status, true));
  554. $this->After_send($status, $this, $Options); //for additional actions
  555. return $status;
  556. }
  557. }
  558. ?>