You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

169 lines
5.2 KiB

  1. <?php
  2. /**
  3. * Mail functions
  4. *
  5. * @license GPL 2 (http://www.gnu.org/licenses/gpl.html)
  6. * @author Andreas Gohr <andi@splitbrain.org>
  7. */
  8. /**
  9. * Patterns for use in email detection and validation
  10. *
  11. * NOTE: there is an unquoted '/' in RFC2822_ATEXT, it must remain unquoted to be used in the parser
  12. * the pattern uses non-capturing groups as captured groups aren't allowed in the parser
  13. * select pattern delimiters with care!
  14. *
  15. * May not be completly RFC conform!
  16. * @link http://www.faqs.org/rfcs/rfc2822.html (paras 3.4.1 & 3.2.4)
  17. *
  18. * @author Chris Smith <chris@jalakai.co.uk>
  19. * Check if a given mail address is valid
  20. */
  21. if (!defined('RFC2822_ATEXT')) define('RFC2822_ATEXT', "0-9a-zA-Z!#$%&'*+/=?^_`{|}~-");
  22. if (!defined('PREG_PATTERN_VALID_EMAIL')) define(
  23. 'PREG_PATTERN_VALID_EMAIL',
  24. '[' . RFC2822_ATEXT . ']+(?:\.[' . RFC2822_ATEXT . ']+)*@(?i:[0-9a-z][0-9a-z-]*\.)+(?i:[a-z]{2,63})'
  25. );
  26. /**
  27. * Prepare mailfrom replacement patterns
  28. *
  29. * Also prepares a mailfromnobody config that contains an autoconstructed address
  30. * if the mailfrom one is userdependent and this might not be wanted (subscriptions)
  31. *
  32. * @author Andreas Gohr <andi@splitbrain.org>
  33. */
  34. function mail_setup()
  35. {
  36. global $conf;
  37. global $USERINFO;
  38. /** @var Input $INPUT */
  39. global $INPUT;
  40. // auto constructed address
  41. $host = @parse_url(DOKU_URL, PHP_URL_HOST);
  42. if (!$host) $host = 'example.com';
  43. $noreply = 'noreply@' . $host;
  44. $replace = [];
  45. if (!empty($USERINFO['mail'])) {
  46. $replace['@MAIL@'] = $USERINFO['mail'];
  47. } else {
  48. $replace['@MAIL@'] = $noreply;
  49. }
  50. // use 'noreply' if no user
  51. $replace['@USER@'] = $INPUT->server->str('REMOTE_USER', 'noreply', true);
  52. if (!empty($USERINFO['name'])) {
  53. $replace['@NAME@'] = $USERINFO['name'];
  54. } else {
  55. $replace['@NAME@'] = '';
  56. }
  57. // apply replacements
  58. $from = str_replace(
  59. array_keys($replace),
  60. array_values($replace),
  61. $conf['mailfrom']
  62. );
  63. // any replacements done? set different mailfromnone
  64. if ($from != $conf['mailfrom']) {
  65. $conf['mailfromnobody'] = $noreply;
  66. } else {
  67. $conf['mailfromnobody'] = $from;
  68. }
  69. $conf['mailfrom'] = $from;
  70. }
  71. /**
  72. * Check if a given mail address is valid
  73. *
  74. * @param string $email the address to check
  75. * @return bool true if address is valid
  76. */
  77. function mail_isvalid($email)
  78. {
  79. return EmailAddressValidator::checkEmailAddress($email, true);
  80. }
  81. /**
  82. * Quoted printable encoding
  83. *
  84. * @author umu <umuAThrz.tu-chemnitz.de>
  85. * @link http://php.net/manual/en/function.imap-8bit.php#61216
  86. *
  87. * @param string $sText
  88. * @param int $maxlen
  89. * @param bool $bEmulate_imap_8bit
  90. *
  91. * @return string
  92. */
  93. function mail_quotedprintable_encode($sText, $maxlen = 74, $bEmulate_imap_8bit = true)
  94. {
  95. // split text into lines
  96. $aLines = preg_split("/(?:\r\n|\r|\n)/", $sText);
  97. $cnt = count($aLines);
  98. for ($i = 0; $i < $cnt; $i++) {
  99. $sLine =& $aLines[$i];
  100. if ($sLine === '') continue; // do nothing, if empty
  101. $sRegExp = '/[^\x09\x20\x21-\x3C\x3E-\x7E]/e';
  102. // imap_8bit encodes x09 everywhere, not only at lineends,
  103. // for EBCDIC safeness encode !"#$@[\]^`{|}~,
  104. // for complete safeness encode every character :)
  105. if ($bEmulate_imap_8bit)
  106. $sRegExp = '/[^\x20\x21-\x3C\x3E-\x7E]/';
  107. $sLine = preg_replace_callback($sRegExp, 'mail_quotedprintable_encode_callback', $sLine);
  108. // encode x09,x20 at lineends
  109. {
  110. $iLength = strlen($sLine);
  111. $iLastChar = ord($sLine[$iLength - 1]);
  112. // !!!!!!!!
  113. // imap_8_bit does not encode x20 at the very end of a text,
  114. // here is, where I don't agree with imap_8_bit,
  115. // please correct me, if I'm wrong,
  116. // or comment next line for RFC2045 conformance, if you like
  117. if (!($bEmulate_imap_8bit && ($i == count($aLines) - 1))) {
  118. if (($iLastChar == 0x09) || ($iLastChar == 0x20)) {
  119. $sLine[$iLength - 1] = '=';
  120. $sLine .= ($iLastChar == 0x09) ? '09' : '20';
  121. }
  122. }
  123. } // imap_8bit encodes x20 before chr(13), too
  124. // although IMHO not requested by RFC2045, why not do it safer :)
  125. // and why not encode any x20 around chr(10) or chr(13)
  126. if ($bEmulate_imap_8bit) {
  127. $sLine = str_replace(' =0D', '=20=0D', $sLine);
  128. //$sLine=str_replace(' =0A','=20=0A',$sLine);
  129. //$sLine=str_replace('=0D ','=0D=20',$sLine);
  130. //$sLine=str_replace('=0A ','=0A=20',$sLine);
  131. }
  132. // finally split into softlines no longer than $maxlen chars,
  133. // for even more safeness one could encode x09,x20
  134. // at the very first character of the line
  135. // and after soft linebreaks, as well,
  136. // but this wouldn't be caught by such an easy RegExp
  137. if ($maxlen) {
  138. preg_match_all('/.{1,' . ($maxlen - 2) . '}([^=]{0,2})?/', $sLine, $aMatch);
  139. $sLine = implode('=' . MAILHEADER_EOL, $aMatch[0]); // add soft crlf's
  140. }
  141. }
  142. // join lines into text
  143. return implode(MAILHEADER_EOL, $aLines);
  144. }
  145. function mail_quotedprintable_encode_callback($matches)
  146. {
  147. return sprintf("=%02X", ord($matches[0])) ;
  148. }