1ed7b5f09Sandi<?php 244f669e9Sandi/** 344f669e9Sandi * Mail functions 444f669e9Sandi * 544f669e9Sandi * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 644f669e9Sandi * @author Andreas Gohr <andi@splitbrain.org> 744f669e9Sandi */ 844f669e9Sandi 944f669e9Sandi 1044f669e9Sandi/** 11d530a62aSAndreas Gohr * Patterns for use in email detection and validation 12d530a62aSAndreas Gohr * 13d530a62aSAndreas Gohr * NOTE: there is an unquoted '/' in RFC2822_ATEXT, it must remain unquoted to be used in the parser 14d530a62aSAndreas Gohr * the pattern uses non-capturing groups as captured groups aren't allowed in the parser 15d530a62aSAndreas Gohr * select pattern delimiters with care! 16d530a62aSAndreas Gohr * 17d530a62aSAndreas Gohr * May not be completly RFC conform! 18d530a62aSAndreas Gohr * @link http://www.faqs.org/rfcs/rfc2822.html (paras 3.4.1 & 3.2.4) 19d530a62aSAndreas Gohr * 20d530a62aSAndreas Gohr * @author Chris Smith <chris@jalakai.co.uk> 21d530a62aSAndreas Gohr * Check if a given mail address is valid 22d530a62aSAndreas Gohr */ 23d530a62aSAndreas Gohrif (!defined('RFC2822_ATEXT')) define('RFC2822_ATEXT', "0-9a-zA-Z!#$%&'*+/=?^_`{|}~-"); 2464159a61SAndreas Gohrif (!defined('PREG_PATTERN_VALID_EMAIL')) define( 2564159a61SAndreas Gohr 'PREG_PATTERN_VALID_EMAIL', 2664159a61SAndreas Gohr '['.RFC2822_ATEXT.']+(?:\.['.RFC2822_ATEXT.']+)*@(?i:[0-9a-z][0-9a-z-]*\.)+(?i:[a-z]{2,63})' 2764159a61SAndreas Gohr); 28d530a62aSAndreas Gohr 295ec3fefcSAndreas Gohr/** 305ec3fefcSAndreas Gohr * Prepare mailfrom replacement patterns 315ec3fefcSAndreas Gohr * 32465e809bSAndreas Gohr * Also prepares a mailfromnobody config that contains an autoconstructed address 33f7cefc02SAndreas Gohr * if the mailfrom one is userdependent and this might not be wanted (subscriptions) 34f7cefc02SAndreas Gohr * 355ec3fefcSAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 365ec3fefcSAndreas Gohr */ 37d868eb89SAndreas Gohrfunction mail_setup() 38d868eb89SAndreas Gohr{ 395ec3fefcSAndreas Gohr global $conf; 40609c41e4SElan Ruusamäe global $USERINFO; 41585bf44eSChristopher Smith /** @var Input $INPUT */ 42585bf44eSChristopher Smith global $INPUT; 43d530a62aSAndreas Gohr 44f7cefc02SAndreas Gohr // auto constructed address 45f7cefc02SAndreas Gohr $host = @parse_url(DOKU_URL, PHP_URL_HOST); 46f7cefc02SAndreas Gohr if(!$host) $host = 'example.com'; 47f7cefc02SAndreas Gohr $noreply = 'noreply@'.$host; 485ec3fefcSAndreas Gohr 4924870174SAndreas Gohr $replace = []; 50609c41e4SElan Ruusamäe if(!empty($USERINFO['mail'])){ 51609c41e4SElan Ruusamäe $replace['@MAIL@'] = $USERINFO['mail']; 525ec3fefcSAndreas Gohr }else{ 53f7cefc02SAndreas Gohr $replace['@MAIL@'] = $noreply; 545ec3fefcSAndreas Gohr } 555ec3fefcSAndreas Gohr 56585bf44eSChristopher Smith // use 'noreply' if no user 57585bf44eSChristopher Smith $replace['@USER@'] = $INPUT->server->str('REMOTE_USER', 'noreply', true); 585ec3fefcSAndreas Gohr 59609c41e4SElan Ruusamäe if(!empty($USERINFO['name'])){ 60609c41e4SElan Ruusamäe $replace['@NAME@'] = $USERINFO['name']; 615ec3fefcSAndreas Gohr }else{ 625ec3fefcSAndreas Gohr $replace['@NAME@'] = ''; 635ec3fefcSAndreas Gohr } 645ec3fefcSAndreas Gohr 65f7cefc02SAndreas Gohr // apply replacements 66*dccd6b2bSAndreas Gohr $from = str_replace( 67*dccd6b2bSAndreas Gohr array_keys($replace), 685ec3fefcSAndreas Gohr array_values($replace), 69*dccd6b2bSAndreas Gohr $conf['mailfrom'] 70*dccd6b2bSAndreas Gohr ); 71f7cefc02SAndreas Gohr 72f7cefc02SAndreas Gohr // any replacements done? set different mailfromnone 73f7cefc02SAndreas Gohr if($from != $conf['mailfrom']){ 74465e809bSAndreas Gohr $conf['mailfromnobody'] = $noreply; 75f7cefc02SAndreas Gohr }else{ 76465e809bSAndreas Gohr $conf['mailfromnobody'] = $from; 77f7cefc02SAndreas Gohr } 78f7cefc02SAndreas Gohr $conf['mailfrom'] = $from; 795ec3fefcSAndreas Gohr} 80d530a62aSAndreas Gohr 81d530a62aSAndreas Gohr/** 82e8f8d645SAndreas Gohr * Check if a given mail address is valid 8344f669e9Sandi * 8444f669e9Sandi * @param string $email the address to check 8544f669e9Sandi * @return bool true if address is valid 8644f669e9Sandi */ 87d868eb89SAndreas Gohrfunction mail_isvalid($email) 88d868eb89SAndreas Gohr{ 893d4e3335SAndreas Gohr return EmailAddressValidator::checkEmailAddress($email, true); 9044f669e9Sandi} 9144f669e9Sandi 9244f669e9Sandi/** 9344f669e9Sandi * Quoted printable encoding 9444f669e9Sandi * 9591275a65SAndreas Gohr * @author umu <umuAThrz.tu-chemnitz.de> 9659752844SAnders Sandblad * @link http://php.net/manual/en/function.imap-8bit.php#61216 97f50a239bSTakamura * 98f50a239bSTakamura * @param string $sText 99f50a239bSTakamura * @param int $maxlen 100f50a239bSTakamura * @param bool $bEmulate_imap_8bit 101f50a239bSTakamura * 102f50a239bSTakamura * @return string 10344f669e9Sandi */ 104d868eb89SAndreas Gohrfunction mail_quotedprintable_encode($sText, $maxlen = 74, $bEmulate_imap_8bit = true) 105d868eb89SAndreas Gohr{ 10691275a65SAndreas Gohr // split text into lines 10791275a65SAndreas Gohr $aLines= preg_split("/(?:\r\n|\r|\n)/", $sText); 108db959ae3SAndreas Gohr $cnt = count($aLines); 10991275a65SAndreas Gohr 110db959ae3SAndreas Gohr for ($i=0; $i<$cnt; $i++) { 11191275a65SAndreas Gohr $sLine =& $aLines[$i]; 11224870174SAndreas Gohr if ($sLine === '') continue; // do nothing, if empty 11391275a65SAndreas Gohr 11491275a65SAndreas Gohr $sRegExp = '/[^\x09\x20\x21-\x3C\x3E-\x7E]/e'; 11591275a65SAndreas Gohr 11691275a65SAndreas Gohr // imap_8bit encodes x09 everywhere, not only at lineends, 11791275a65SAndreas Gohr // for EBCDIC safeness encode !"#$@[\]^`{|}~, 11891275a65SAndreas Gohr // for complete safeness encode every character :) 11991275a65SAndreas Gohr if ($bEmulate_imap_8bit) 1209c107bd1SChristopher Smith $sRegExp = '/[^\x20\x21-\x3C\x3E-\x7E]/'; 12191275a65SAndreas Gohr 1229c107bd1SChristopher Smith $sLine = preg_replace_callback($sRegExp, 'mail_quotedprintable_encode_callback', $sLine); 12391275a65SAndreas Gohr 12491275a65SAndreas Gohr // encode x09,x20 at lineends 12591275a65SAndreas Gohr { 12691275a65SAndreas Gohr $iLength = strlen($sLine); 1272401f18dSSyntaxseed $iLastChar = ord($sLine[$iLength-1]); 12891275a65SAndreas Gohr 12991275a65SAndreas Gohr // !!!!!!!! 13091275a65SAndreas Gohr // imap_8_bit does not encode x20 at the very end of a text, 13191275a65SAndreas Gohr // here is, where I don't agree with imap_8_bit, 13291275a65SAndreas Gohr // please correct me, if I'm wrong, 13391275a65SAndreas Gohr // or comment next line for RFC2045 conformance, if you like 134db959ae3SAndreas Gohr if (!($bEmulate_imap_8bit && ($i==count($aLines)-1))){ 13591275a65SAndreas Gohr if (($iLastChar==0x09)||($iLastChar==0x20)) { 1362401f18dSSyntaxseed $sLine[$iLength-1]='='; 13791275a65SAndreas Gohr $sLine .= ($iLastChar==0x09)?'09':'20'; 13844f669e9Sandi } 139db959ae3SAndreas Gohr } 14091275a65SAndreas Gohr } // imap_8bit encodes x20 before chr(13), too 14191275a65SAndreas Gohr // although IMHO not requested by RFC2045, why not do it safer :) 14291275a65SAndreas Gohr // and why not encode any x20 around chr(10) or chr(13) 14391275a65SAndreas Gohr if ($bEmulate_imap_8bit) { 14491275a65SAndreas Gohr $sLine=str_replace(' =0D', '=20=0D', $sLine); 14591275a65SAndreas Gohr //$sLine=str_replace(' =0A','=20=0A',$sLine); 14691275a65SAndreas Gohr //$sLine=str_replace('=0D ','=0D=20',$sLine); 14791275a65SAndreas Gohr //$sLine=str_replace('=0A ','=0A=20',$sLine); 14844f669e9Sandi } 14944f669e9Sandi 15091275a65SAndreas Gohr // finally split into softlines no longer than $maxlen chars, 15191275a65SAndreas Gohr // for even more safeness one could encode x09,x20 15291275a65SAndreas Gohr // at the very first character of the line 15391275a65SAndreas Gohr // and after soft linebreaks, as well, 15491275a65SAndreas Gohr // but this wouldn't be caught by such an easy RegExp 15591275a65SAndreas Gohr if($maxlen){ 15691275a65SAndreas Gohr preg_match_all('/.{1,'.($maxlen - 2).'}([^=]{0,2})?/', $sLine, $aMatch); 1571a6a1c04SAndreas Gohr $sLine = implode('=' . MAILHEADER_EOL, $aMatch[0]); // add soft crlf's 15891275a65SAndreas Gohr } 15991275a65SAndreas Gohr } 16091275a65SAndreas Gohr 16191275a65SAndreas Gohr // join lines into text 1621a6a1c04SAndreas Gohr return implode(MAILHEADER_EOL, $aLines); 16391275a65SAndreas Gohr} 16444f669e9Sandi 165d868eb89SAndreas Gohrfunction mail_quotedprintable_encode_callback($matches) 166d868eb89SAndreas Gohr{ 1679c107bd1SChristopher Smith return sprintf("=%02X", ord($matches[0])) ; 1689c107bd1SChristopher Smith} 169