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 */ 375ec3fefcSAndreas Gohrfunction mail_setup(){ 385ec3fefcSAndreas Gohr global $conf; 39609c41e4SElan Ruusamäe global $USERINFO; 40585bf44eSChristopher Smith /** @var Input $INPUT */ 41585bf44eSChristopher Smith global $INPUT; 42d530a62aSAndreas Gohr 43f7cefc02SAndreas Gohr // auto constructed address 44f7cefc02SAndreas Gohr $host = @parse_url(DOKU_URL,PHP_URL_HOST); 45f7cefc02SAndreas Gohr if(!$host) $host = 'example.com'; 46f7cefc02SAndreas Gohr $noreply = 'noreply@'.$host; 475ec3fefcSAndreas Gohr 48*24870174SAndreas Gohr $replace = []; 49609c41e4SElan Ruusamäe if(!empty($USERINFO['mail'])){ 50609c41e4SElan Ruusamäe $replace['@MAIL@'] = $USERINFO['mail']; 515ec3fefcSAndreas Gohr }else{ 52f7cefc02SAndreas Gohr $replace['@MAIL@'] = $noreply; 535ec3fefcSAndreas Gohr } 545ec3fefcSAndreas Gohr 55585bf44eSChristopher Smith // use 'noreply' if no user 56585bf44eSChristopher Smith $replace['@USER@'] = $INPUT->server->str('REMOTE_USER', 'noreply', true); 575ec3fefcSAndreas Gohr 58609c41e4SElan Ruusamäe if(!empty($USERINFO['name'])){ 59609c41e4SElan Ruusamäe $replace['@NAME@'] = $USERINFO['name']; 605ec3fefcSAndreas Gohr }else{ 615ec3fefcSAndreas Gohr $replace['@NAME@'] = ''; 625ec3fefcSAndreas Gohr } 635ec3fefcSAndreas Gohr 64f7cefc02SAndreas Gohr // apply replacements 65f7cefc02SAndreas Gohr $from = str_replace(array_keys($replace), 665ec3fefcSAndreas Gohr array_values($replace), 675ec3fefcSAndreas Gohr $conf['mailfrom']); 68f7cefc02SAndreas Gohr 69f7cefc02SAndreas Gohr // any replacements done? set different mailfromnone 70f7cefc02SAndreas Gohr if($from != $conf['mailfrom']){ 71465e809bSAndreas Gohr $conf['mailfromnobody'] = $noreply; 72f7cefc02SAndreas Gohr }else{ 73465e809bSAndreas Gohr $conf['mailfromnobody'] = $from; 74f7cefc02SAndreas Gohr } 75f7cefc02SAndreas Gohr $conf['mailfrom'] = $from; 765ec3fefcSAndreas Gohr} 77d530a62aSAndreas Gohr 78d530a62aSAndreas Gohr/** 79e8f8d645SAndreas Gohr * Check if a given mail address is valid 8044f669e9Sandi * 8144f669e9Sandi * @param string $email the address to check 8244f669e9Sandi * @return bool true if address is valid 8344f669e9Sandi */ 8444f669e9Sandifunction mail_isvalid($email) { 853d4e3335SAndreas Gohr return EmailAddressValidator::checkEmailAddress($email, true); 8644f669e9Sandi} 8744f669e9Sandi 8844f669e9Sandi/** 8944f669e9Sandi * Quoted printable encoding 9044f669e9Sandi * 9191275a65SAndreas Gohr * @author umu <umuAThrz.tu-chemnitz.de> 9259752844SAnders Sandblad * @link http://php.net/manual/en/function.imap-8bit.php#61216 93f50a239bSTakamura * 94f50a239bSTakamura * @param string $sText 95f50a239bSTakamura * @param int $maxlen 96f50a239bSTakamura * @param bool $bEmulate_imap_8bit 97f50a239bSTakamura * 98f50a239bSTakamura * @return string 9944f669e9Sandi */ 10091275a65SAndreas Gohrfunction mail_quotedprintable_encode($sText,$maxlen=74,$bEmulate_imap_8bit=true) { 10191275a65SAndreas Gohr // split text into lines 10291275a65SAndreas Gohr $aLines= preg_split("/(?:\r\n|\r|\n)/", $sText); 103db959ae3SAndreas Gohr $cnt = count($aLines); 10491275a65SAndreas Gohr 105db959ae3SAndreas Gohr for ($i=0;$i<$cnt;$i++) { 10691275a65SAndreas Gohr $sLine =& $aLines[$i]; 107*24870174SAndreas Gohr if ($sLine === '') continue; // do nothing, if empty 10891275a65SAndreas Gohr 10991275a65SAndreas Gohr $sRegExp = '/[^\x09\x20\x21-\x3C\x3E-\x7E]/e'; 11091275a65SAndreas Gohr 11191275a65SAndreas Gohr // imap_8bit encodes x09 everywhere, not only at lineends, 11291275a65SAndreas Gohr // for EBCDIC safeness encode !"#$@[\]^`{|}~, 11391275a65SAndreas Gohr // for complete safeness encode every character :) 11491275a65SAndreas Gohr if ($bEmulate_imap_8bit) 1159c107bd1SChristopher Smith $sRegExp = '/[^\x20\x21-\x3C\x3E-\x7E]/'; 11691275a65SAndreas Gohr 1179c107bd1SChristopher Smith $sLine = preg_replace_callback( $sRegExp, 'mail_quotedprintable_encode_callback', $sLine ); 11891275a65SAndreas Gohr 11991275a65SAndreas Gohr // encode x09,x20 at lineends 12091275a65SAndreas Gohr { 12191275a65SAndreas Gohr $iLength = strlen($sLine); 1222401f18dSSyntaxseed $iLastChar = ord($sLine[$iLength-1]); 12391275a65SAndreas Gohr 12491275a65SAndreas Gohr // !!!!!!!! 12591275a65SAndreas Gohr // imap_8_bit does not encode x20 at the very end of a text, 12691275a65SAndreas Gohr // here is, where I don't agree with imap_8_bit, 12791275a65SAndreas Gohr // please correct me, if I'm wrong, 12891275a65SAndreas Gohr // or comment next line for RFC2045 conformance, if you like 129db959ae3SAndreas Gohr if (!($bEmulate_imap_8bit && ($i==count($aLines)-1))){ 13091275a65SAndreas Gohr if (($iLastChar==0x09)||($iLastChar==0x20)) { 1312401f18dSSyntaxseed $sLine[$iLength-1]='='; 13291275a65SAndreas Gohr $sLine .= ($iLastChar==0x09)?'09':'20'; 13344f669e9Sandi } 134db959ae3SAndreas Gohr } 13591275a65SAndreas Gohr } // imap_8bit encodes x20 before chr(13), too 13691275a65SAndreas Gohr // although IMHO not requested by RFC2045, why not do it safer :) 13791275a65SAndreas Gohr // and why not encode any x20 around chr(10) or chr(13) 13891275a65SAndreas Gohr if ($bEmulate_imap_8bit) { 13991275a65SAndreas Gohr $sLine=str_replace(' =0D','=20=0D',$sLine); 14091275a65SAndreas Gohr //$sLine=str_replace(' =0A','=20=0A',$sLine); 14191275a65SAndreas Gohr //$sLine=str_replace('=0D ','=0D=20',$sLine); 14291275a65SAndreas Gohr //$sLine=str_replace('=0A ','=0A=20',$sLine); 14344f669e9Sandi } 14444f669e9Sandi 14591275a65SAndreas Gohr // finally split into softlines no longer than $maxlen chars, 14691275a65SAndreas Gohr // for even more safeness one could encode x09,x20 14791275a65SAndreas Gohr // at the very first character of the line 14891275a65SAndreas Gohr // and after soft linebreaks, as well, 14991275a65SAndreas Gohr // but this wouldn't be caught by such an easy RegExp 15091275a65SAndreas Gohr if($maxlen){ 15191275a65SAndreas Gohr preg_match_all( '/.{1,'.($maxlen - 2).'}([^=]{0,2})?/', $sLine, $aMatch ); 1521a6a1c04SAndreas Gohr $sLine = implode( '=' . MAILHEADER_EOL, $aMatch[0] ); // add soft crlf's 15391275a65SAndreas Gohr } 15491275a65SAndreas Gohr } 15591275a65SAndreas Gohr 15691275a65SAndreas Gohr // join lines into text 1571a6a1c04SAndreas Gohr return implode(MAILHEADER_EOL,$aLines); 15891275a65SAndreas Gohr} 15944f669e9Sandi 1609c107bd1SChristopher Smithfunction mail_quotedprintable_encode_callback($matches){ 1619c107bd1SChristopher Smith return sprintf( "=%02X", ord ( $matches[0] ) ) ; 1629c107bd1SChristopher Smith} 163