mail.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. global $conf;
  36. global $USERINFO;
  37. /** @var Input $INPUT */
  38. global $INPUT;
  39. // auto constructed address
  40. $host = @parse_url(DOKU_URL,PHP_URL_HOST);
  41. if(!$host) $host = 'example.com';
  42. $noreply = 'noreply@'.$host;
  43. $replace = array();
  44. if(!empty($USERINFO['mail'])){
  45. $replace['@MAIL@'] = $USERINFO['mail'];
  46. }else{
  47. $replace['@MAIL@'] = $noreply;
  48. }
  49. // use 'noreply' if no user
  50. $replace['@USER@'] = $INPUT->server->str('REMOTE_USER', 'noreply', true);
  51. if(!empty($USERINFO['name'])){
  52. $replace['@NAME@'] = $USERINFO['name'];
  53. }else{
  54. $replace['@NAME@'] = '';
  55. }
  56. // apply replacements
  57. $from = str_replace(array_keys($replace),
  58. array_values($replace),
  59. $conf['mailfrom']);
  60. // any replacements done? set different mailfromnone
  61. if($from != $conf['mailfrom']){
  62. $conf['mailfromnobody'] = $noreply;
  63. }else{
  64. $conf['mailfromnobody'] = $from;
  65. }
  66. $conf['mailfrom'] = $from;
  67. }
  68. /**
  69. * Check if a given mail address is valid
  70. *
  71. * @param string $email the address to check
  72. * @return bool true if address is valid
  73. */
  74. function mail_isvalid($email) {
  75. return EmailAddressValidator::checkEmailAddress($email, true);
  76. }
  77. /**
  78. * Quoted printable encoding
  79. *
  80. * @author umu <umuAThrz.tu-chemnitz.de>
  81. * @link http://php.net/manual/en/function.imap-8bit.php#61216
  82. *
  83. * @param string $sText
  84. * @param int $maxlen
  85. * @param bool $bEmulate_imap_8bit
  86. *
  87. * @return string
  88. */
  89. function mail_quotedprintable_encode($sText,$maxlen=74,$bEmulate_imap_8bit=true) {
  90. // split text into lines
  91. $aLines= preg_split("/(?:\r\n|\r|\n)/", $sText);
  92. $cnt = count($aLines);
  93. for ($i=0;$i<$cnt;$i++) {
  94. $sLine =& $aLines[$i];
  95. if (strlen($sLine)===0) continue; // do nothing, if empty
  96. $sRegExp = '/[^\x09\x20\x21-\x3C\x3E-\x7E]/e';
  97. // imap_8bit encodes x09 everywhere, not only at lineends,
  98. // for EBCDIC safeness encode !"#$@[\]^`{|}~,
  99. // for complete safeness encode every character :)
  100. if ($bEmulate_imap_8bit)
  101. $sRegExp = '/[^\x20\x21-\x3C\x3E-\x7E]/';
  102. $sLine = preg_replace_callback( $sRegExp, 'mail_quotedprintable_encode_callback', $sLine );
  103. // encode x09,x20 at lineends
  104. {
  105. $iLength = strlen($sLine);
  106. $iLastChar = ord($sLine[$iLength-1]);
  107. // !!!!!!!!
  108. // imap_8_bit does not encode x20 at the very end of a text,
  109. // here is, where I don't agree with imap_8_bit,
  110. // please correct me, if I'm wrong,
  111. // or comment next line for RFC2045 conformance, if you like
  112. if (!($bEmulate_imap_8bit && ($i==count($aLines)-1))){
  113. if (($iLastChar==0x09)||($iLastChar==0x20)) {
  114. $sLine[$iLength-1]='=';
  115. $sLine .= ($iLastChar==0x09)?'09':'20';
  116. }
  117. }
  118. } // imap_8bit encodes x20 before chr(13), too
  119. // although IMHO not requested by RFC2045, why not do it safer :)
  120. // and why not encode any x20 around chr(10) or chr(13)
  121. if ($bEmulate_imap_8bit) {
  122. $sLine=str_replace(' =0D','=20=0D',$sLine);
  123. //$sLine=str_replace(' =0A','=20=0A',$sLine);
  124. //$sLine=str_replace('=0D ','=0D=20',$sLine);
  125. //$sLine=str_replace('=0A ','=0A=20',$sLine);
  126. }
  127. // finally split into softlines no longer than $maxlen chars,
  128. // for even more safeness one could encode x09,x20
  129. // at the very first character of the line
  130. // and after soft linebreaks, as well,
  131. // but this wouldn't be caught by such an easy RegExp
  132. if($maxlen){
  133. preg_match_all( '/.{1,'.($maxlen - 2).'}([^=]{0,2})?/', $sLine, $aMatch );
  134. $sLine = implode( '=' . MAILHEADER_EOL, $aMatch[0] ); // add soft crlf's
  135. }
  136. }
  137. // join lines into text
  138. return implode(MAILHEADER_EOL,$aLines);
  139. }
  140. function mail_quotedprintable_encode_callback($matches){
  141. return sprintf( "=%02X", ord ( $matches[0] ) ) ;
  142. }