PageRenderTime 25ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/src/common/mail/Mail.class.php

https://gitlab.com/prenaud76/tuleap
PHP | 278 lines | 203 code | 33 blank | 42 comment | 18 complexity | 00a9bf20be656c52f05abe74d4b7e0e7 MD5 | raw file
Possible License(s): LGPL-2.1, MPL-2.0-no-copyleft-exception, LGPL-3.0, GPL-2.0, GPL-3.0
  1. <?php
  2. /*
  3. *
  4. */
  5. require_once('common/dao/UserDao.class.php');
  6. require_once('common/dao/CodendiDataAccess.class.php');
  7. require_once('Codendi_Mail_Interface.class.php');
  8. class Mail implements Codendi_Mail_Interface {
  9. function __construct() {
  10. $this->setHeaderCharset('UTF-8');
  11. $this->setBodyCharset('UTF-8');
  12. $this->setMimeType('text/plain');
  13. $this->setTo('', true);
  14. $this->setBcc('', true);
  15. $this->setCc('', true);
  16. $this->setBody('', true);
  17. $this->clearAdditionalHeaders();
  18. }
  19. var $_headerCharset;
  20. function setHeaderCharset($charset) {
  21. $this->_headerCharset = $charset;
  22. }
  23. function getHeaderCharset() {
  24. return $this->_headerCharset;
  25. }
  26. var $_bodyCharset;
  27. function setBodyCharset($charset) {
  28. $this->_bodyCharset = $charset;
  29. }
  30. function getBodyCharset() {
  31. return $this->_bodyCharset;
  32. }
  33. var $_subject;
  34. function setSubject($subject) {
  35. $this->_subject = $subject;
  36. }
  37. function getSubject() {
  38. return $this->_subject;
  39. }
  40. function getEncodedSubject() {
  41. return $this->_encodeHeader($this->_subject, $this->getHeaderCharset());
  42. }
  43. /**
  44. * Function to encode a header if necessary
  45. * according to RFC2047
  46. * Filename.......: class.html.mime.mail.inc
  47. * Project........: HTML Mime mail class
  48. * Last Modified..: Date: 2002/07/24 13:14:10
  49. * CVS Revision...: Revision: 1.4
  50. * Copyright......: 2001, 2002 Richard Heyes
  51. */
  52. function _encodeHeader($input, $charset) {
  53. preg_match_all('/(\s?\w*[\x80-\xFF]+\w*\s?)/', $input, $matches);
  54. foreach ($matches[1] as $value) {
  55. $replacement = preg_replace('/([\x80-\xFF])/e', '"=" . strtoupper(dechex(ord("\1")))', $value);
  56. $input = str_replace($value, '=?' . $charset . '?Q?' . $replacement . '?=', $input);
  57. }
  58. return $input;
  59. }
  60. /**
  61. * Given a header, this function will decode it
  62. * according to RFC2047. Probably not *exactly*
  63. * conformant, but it does pass all the given
  64. * examples (in RFC2047).
  65. *
  66. * @param string Input header value to decode
  67. * @return string Decoded header value
  68. * @access private
  69. */
  70. function _decodeHeader($input)
  71. {
  72. // Remove white space between encoded-words
  73. $input = preg_replace('/(=\?[^?]+\?(q|b)\?[^?]*\?=)(\s)+=\?/i', '\1=?', $input);
  74. // For each encoded-word...
  75. while (preg_match('/(=\?([^?]+)\?(q|b)\?([^?]*)\?=)/i', $input, $matches)) {
  76. $encoded = $matches[1];
  77. $charset = $matches[2];
  78. $encoding = $matches[3];
  79. $text = $matches[4];
  80. switch (strtolower($encoding)) {
  81. case 'b':
  82. $text = base64_decode($text);
  83. break;
  84. case 'q':
  85. $text = str_replace('_', ' ', $text);
  86. preg_match_all('/=([a-f0-9]{2})/i', $text, $matches);
  87. foreach($matches[1] as $value)
  88. $text = str_replace('='.$value, chr(hexdec($value)), $text);
  89. break;
  90. }
  91. $input = str_replace($encoded, $text, $input);
  92. }
  93. return $input;
  94. }
  95. var $_body;
  96. function setBody($body) {
  97. $this->_body = $body;
  98. }
  99. function getBody() {
  100. return $this->_body;
  101. }
  102. var $_from;
  103. function setFrom($from) {
  104. $this->_from = $from;
  105. }
  106. function getFrom() {
  107. return $this->_from;
  108. }
  109. /**
  110. * Check if given mail is a valid (Ie. Active or Restricted) user.
  111. *
  112. * The given mail can by both user_name or email. Return form is always the
  113. * user email.
  114. *
  115. * @param $list (IN) list of email addresses separated by , or ;
  116. * @return list of email separated by ,
  117. */
  118. function _validateRecipient($list) {
  119. $recipArray = split('[;,]', $list);
  120. $retArray = array();
  121. $user_dao = $this->_getUserDao();
  122. foreach($recipArray as $email) {
  123. $email = trim($email);
  124. if(!empty($email)) {
  125. $dar = $user_dao->searchStatusByEmail($email);
  126. if ($dar->rowCount() > 0) {
  127. $allowed_status = array('A', 'R', 'P', 'V', 'W');
  128. $one_with_status_allowed_found = false;
  129. while (($row = $dar->getRow()) && !$one_with_status_allowed_found) {
  130. if (in_array($row['status'], $allowed_status)) {
  131. $retArray[] = '"'.$this->_encodeHeader($row['realname'], $this->getHeaderCharset()).'" <'.$row['email'].'>';
  132. $one_with_status_allowed_found = true;
  133. }
  134. }
  135. } else {
  136. $retArray[] = $email;
  137. }
  138. }
  139. }
  140. return implode(', ', $retArray);
  141. }
  142. public function setToUser($to) {
  143. foreach ($to as $user) {
  144. $this->_to = array($user->getEmail());
  145. }
  146. }
  147. var $_to;
  148. function setTo($to, $raw=false) {
  149. if($raw)
  150. $this->_to = $to;
  151. else
  152. $this->_to = $this->_validateRecipient($to);
  153. }
  154. function getTo() {
  155. return $this->_to;
  156. }
  157. var $_bcc;
  158. function setBcc($bcc, $raw=false) {
  159. if($raw)
  160. $this->_bcc = $bcc;
  161. else
  162. $this->_bcc = $this->_validateRecipient($bcc);
  163. }
  164. function getBcc() {
  165. return $this->_bcc;
  166. }
  167. var $_cc;
  168. function setCc($cc, $raw=false) {
  169. if($raw)
  170. $this->_cc = $cc;
  171. else
  172. $this->_cc = $this->_validateRecipient($cc);
  173. }
  174. function getCc() {
  175. return $this->_cc;
  176. }
  177. var $_mimeType;
  178. function setMimeType($mimeType) {
  179. $this->_mimeType = $mimeType;
  180. }
  181. function getMimeType() {
  182. return $this->_mimeType;
  183. }
  184. var $_additionalHeaders;
  185. function clearAdditionalHeaders() {
  186. $this->_additionalHeaders = array();
  187. }
  188. function addAdditionalHeader($name, $value) {
  189. $this->_additionalHeaders[$name] = $value;
  190. }
  191. function removeAdditionalHeader($name) {
  192. if (isset($this->_additionalHeaders[$name])) {
  193. unset($this->_additionalHeaders[$name]);
  194. }
  195. }
  196. /**
  197. * @returns TRUE if the mail was successfully accepted for delivery, FALSE otherwise.
  198. * It is important to note that just because the mail was accepted for delivery,
  199. * it does NOT mean the mail will actually reach the intended destination.
  200. **/
  201. function send() {
  202. if($this->getTo() === ''
  203. && $this->getCc() === ''
  204. && $this->getBcc() === '') {
  205. return false;
  206. }
  207. $header = "From: ".$this->getFrom().$GLOBALS['sys_lf'];
  208. $header .= "Content-type: ".$this->getMimeType()."; charset=".$this->getBodyCharset().$GLOBALS['sys_lf'];
  209. $cc = $this->getCc();
  210. if (strlen($cc) > 0) {
  211. $header .= "Cc: ".$cc.$GLOBALS['sys_lf'];
  212. }
  213. $bcc = $this->getBcc();
  214. if (strlen($bcc) > 0) {
  215. $header .= "Bcc: ".$bcc.$GLOBALS['sys_lf'];
  216. }
  217. foreach($this->_additionalHeaders as $name => $value) {
  218. $header .= $name.": ".$value.$GLOBALS['sys_lf'];
  219. }
  220. return $this->_sendmail($header);
  221. }
  222. /**
  223. * Perform effective email send.
  224. * @access protected
  225. */
  226. function _sendmail($header) {
  227. $params = array('mail' => $this,
  228. 'header' => $header);
  229. $em =& EventManager::instance();
  230. $em->processEvent('mail_sendmail', $params);
  231. return mail($this->getTo(),
  232. $this->getEncodedSubject(),
  233. $this->getBody(),
  234. $header
  235. );
  236. }
  237. var $userDao;
  238. function &_getUserDao() {
  239. if (!is_a($this->userDao, 'UserDao')) {
  240. $this->userDao = new UserDao(CodendiDataAccess::instance());
  241. }
  242. return $this->userDao;
  243. }
  244. }
  245. ?>