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