Changeset 1530 in subversion


Ignore:
Timestamp:
Jun 13, 2008 3:42:15 PM (5 years ago)
Author:
alec
Message:
Location:
trunk/roundcubemail
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/roundcubemail/CHANGELOG

    r1525 r1530  
    55---------- 
    66- Added option to display images in messages from known senders (#1484601) 
     7- Updated PEAR::Mail_Mime 
    78 
    892008/06/12 (alec) 
  • trunk/roundcubemail/program/lib/Mail/mime.php

    r514 r1530  
    4040 * THE POSSIBILITY OF SUCH DAMAGE. 
    4141 * 
    42  * @category   Mail 
    43  * @package    Mail_Mime 
    44  * @author     Richard Heyes  <richard@phpguru.org> 
    45  * @author     Tomas V.V. Cox <cox@idecnet.com> 
    46  * @author     Cipriano Groenendal <cipri@php.net> 
    47  * @author     Sean Coates <sean@php.net> 
    48  * @copyright  2003-2006 PEAR <pear-group@php.net> 
    49  * @license    http://www.opensource.org/licenses/bsd-license.php BSD License 
    50  * @version    CVS: $Id$ 
    51  * @link       http://pear.php.net/package/Mail_mime 
    52  * @notes      This class is based on HTML Mime Mail class from 
    53  *             Richard Heyes <richard@phpguru.org> which was based also 
    54  *             in the mime_mail.class by Tobias Ratschiller <tobias@dnet.it> 
    55  *             and Sascha Schumann <sascha@schumann.cx> 
     42 * @category  Mail 
     43 * @package   Mail_Mime 
     44 * @author    Richard Heyes  <richard@phpguru.org> 
     45 * @author    Tomas V.V. Cox <cox@idecnet.com> 
     46 * @author    Cipriano Groenendal <cipri@php.net> 
     47 * @author    Sean Coates <sean@php.net> 
     48 * @copyright 2003-2006 PEAR <pear-group@php.net> 
     49 * @license   http://www.opensource.org/licenses/bsd-license.php BSD License 
     50 * @version   CVS: $Id$ 
     51 * @link      http://pear.php.net/package/Mail_mime 
     52 * 
     53 *            This class is based on HTML Mime Mail class from 
     54 *            Richard Heyes <richard@phpguru.org> which was based also 
     55 *            in the mime_mail.class by Tobias Ratschiller <tobias@dnet.it> 
     56 *            and Sascha Schumann <sascha@schumann.cx> 
    5657 */ 
    5758 
     
    6263 * This package depends on PEAR to raise errors. 
    6364 */ 
    64 require_once('PEAR.php'); 
     65require_once 'PEAR.php'; 
    6566 
    6667/** 
     
    7172 * consist of. 
    7273 */ 
    73 require_once('Mail/mimePart.php'); 
     74require_once 'Mail/mimePart.php'; 
    7475 
    7576 
     
    8081 * images and specific headers. 
    8182 * 
    82  * @category   Mail 
    83  * @package    Mail_Mime 
    84  * @author     Richard Heyes  <richard@phpguru.org> 
    85  * @author     Tomas V.V. Cox <cox@idecnet.com> 
    86  * @author     Cipriano Groenendal <cipri@php.net> 
    87  * @author     Sean Coates <sean@php.net> 
    88  * @copyright  2003-2006 PEAR <pear-group@php.net> 
    89  * @license    http://www.opensource.org/licenses/bsd-license.php BSD License 
    90  * @version    Release: @package_version@ 
    91  * @link       http://pear.php.net/package/Mail_mime 
     83 * @category  Mail 
     84 * @package   Mail_Mime 
     85 * @author    Richard Heyes  <richard@phpguru.org> 
     86 * @author    Tomas V.V. Cox <cox@idecnet.com> 
     87 * @author    Cipriano Groenendal <cipri@php.net> 
     88 * @author    Sean Coates <sean@php.net> 
     89 * @copyright 2003-2006 PEAR <pear-group@php.net> 
     90 * @license   http://www.opensource.org/licenses/bsd-license.php BSD License 
     91 * @version   Release: @package_version@ 
     92 * @link      http://pear.php.net/package/Mail_mime 
    9293 */ 
    9394class Mail_mime 
     
    169170     * Constructor function. 
    170171     * 
    171      * @param string $crlf  what type of linebreak to use. 
    172      *                       Defaults to "\r\n" 
     172     * @param string $crlf what type of linebreak to use. 
     173     *                     Defaults to "\r\n" 
     174     * 
    173175     * @return void 
    174176     * 
     
    193195     * 
    194196     * @access private 
     197     * @return void 
    195198     */ 
    196199    function __wakeup() 
     
    206209     * html should show. 
    207210     * 
    208      * @param  string  $data   Either a string or 
    209      *                          the file name with the contents 
    210      * @param  bool    $isfile If true the first param should be treated 
    211      *                          as a file name, else as a string (default) 
    212      * @param  bool    $append If true the text or file is appended to 
    213      *                          the existing body, else the old body is 
    214      *                          overwritten 
     211     * @param string $data   Either a string or 
     212     *                        the file name with the contents 
     213     * @param bool   $isfile If true the first param should be treated 
     214     *                        as a file name, else as a string (default) 
     215     * @param bool   $append If true the text or file is appended to 
     216     *                        the existing body, else the old body is 
     217     *                        overwritten 
     218     * 
    215219     * @return mixed   true on success or PEAR_Error object 
    216220     * @access public 
     
    241245     * Adds a html part to the mail. 
    242246     * 
    243      * @param  string  $data   either a string or the file name with the 
    244      *                          contents 
    245      * @param  bool    $isfile a flag that determines whether $data is a 
    246      *                          filename, or a string(false, default) 
     247     * @param string $data   either a string or the file name with the 
     248     *                        contents 
     249     * @param bool   $isfile a flag that determines whether $data is a 
     250     *                        filename, or a string(false, default) 
     251     * 
    247252     * @return bool    true on success 
    248253     * @access public 
     
    266271     * Adds an image to the list of embedded images. 
    267272     * 
    268      * @param  string  $file       the image file name OR image data itself 
    269      * @param  string  $c_type     the content type 
    270      * @param  string  $name       the filename of the image. 
    271      *                              Only use if $file is the image data. 
    272      * @param  bool    $isfile     whether $file is a filename or not. 
    273      *                              Defaults to true 
    274      * @return bool                true on success 
     273     * @param string $file   the image file name OR image data itself 
     274     * @param string $c_type the content type 
     275     * @param string $name   the filename of the image. 
     276     *                        Only used if $file is the image data. 
     277     * @param bool   $isfile whether $file is a filename or not. 
     278     *                        Defaults to true 
     279     * 
     280     * @return bool          true on success 
    275281     * @access public 
    276282     */ 
     
    300306     * Adds a file to the list of attachments. 
    301307     * 
    302      * @param  string  $file        The file name of the file to attach 
    303      *                              OR the file contents itself 
    304      * @param  string  $c_type      The content type 
    305      * @param  string  $name        The filename of the attachment 
    306      *                              Only use if $file is the contents 
    307      * @param  bool    $isfile      Whether $file is a filename or not 
    308      *                              Defaults to true 
    309      * @param  string  $encoding    The type of encoding to use. 
    310      *                              Defaults to base64. 
    311      *                              Possible values: 7bit, 8bit, base64,  
    312      *                              or quoted-printable. 
    313      * @param  string  $disposition The content-disposition of this file 
    314      *                              Defaults to attachment. 
    315      *                              Possible values: attachment, inline. 
    316      * @param  string  $charset     The character set used in the filename 
    317      *                              of this attachment. 
     308     * @param string $file        The file name of the file to attach 
     309     *                             OR the file contents itself 
     310     * @param string $c_type      The content type 
     311     * @param string $name        The filename of the attachment 
     312     *                             Only use if $file is the contents 
     313     * @param bool   $isfile      Whether $file is a filename or not 
     314     *                             Defaults to true 
     315     * @param string $encoding    The type of encoding to use. 
     316     *                             Defaults to base64. 
     317     *                             Possible values: 7bit, 8bit, base64,  
     318     *                             or quoted-printable. 
     319     * @param string $disposition The content-disposition of this file 
     320     *                             Defaults to attachment. 
     321     *                             Possible values: attachment, inline. 
     322     * @param string $charset     The character set used in the filename 
     323     *                             of this attachment. 
     324     * @param string $language    The language of the attachment 
     325     * @param string $location    The RFC 2557.4 location of the attachment 
     326     * 
    318327     * @return mixed true on success or PEAR_Error object 
    319328     * @access public 
    320329     */ 
    321     function addAttachment($file, $c_type = 'application/octet-stream', 
    322                            $name = '', $isfile = true, 
    323                            $encoding = 'base64', 
    324                            $disposition = 'attachment', $charset = '') 
     330    function addAttachment($file, 
     331                           $c_type      = 'application/octet-stream', 
     332                           $name        = '', 
     333                            $isfile     = true, 
     334                           $encoding    = 'base64', 
     335                           $disposition = 'attachment', 
     336                           $charset     = '', 
     337                            $language   = '', 
     338                           $location    = '') 
    325339    { 
    326340        $filedata = ($isfile === true) ? $this->_file2str($file) 
     
    328342        if ($isfile === true) { 
    329343            // Force the name the user supplied, otherwise use $file 
    330             $filename = (!empty($name)) ? $name : $file; 
     344            $filename = (strlen($name)) ? $name : $file; 
    331345        } else { 
    332346            $filename = $name; 
    333347        } 
    334         if (empty($filename)) { 
    335             $err = PEAR::raiseError( 
    336               "The supplied filename for the attachment can't be empty" 
    337             ); 
    338             return $err; 
     348        if (!strlen($filename)) { 
     349            $msg = "The supplied filename for the attachment can't be empty"; 
     350            $err = PEAR::raiseError($msg); 
     351            return $err; 
    339352        } 
    340353        $filename = basename($filename); 
     
    349362                                'encoding'    => $encoding, 
    350363                                'charset'     => $charset, 
     364                                'language'    => $language, 
     365                                'location'    => $location, 
    351366                                'disposition' => $disposition 
    352367                               ); 
     
    357372     * Get the contents of the given file name as string 
    358373     * 
    359      * @param  string  $file_name  path of file to process 
     374     * @param string $file_name path of file to process 
     375     * 
    360376     * @return string  contents of $file_name 
    361377     * @access private 
     
    363379    function &_file2str($file_name) 
    364380    { 
     381        //Check state of file and raise an error properly 
     382        if (!file_exists($file_name)) { 
     383            $err = PEAR::raiseError('File not found: ' . $file_name); 
     384            return $err; 
     385        } 
     386        if (!is_file($file_name)) { 
     387            $err = PEAR::raiseError('Not a regular file: ' . $file_name); 
     388            return $err; 
     389        } 
    365390        if (!is_readable($file_name)) { 
    366             $err = PEAR::raiseError('File is not readable ' . $file_name); 
     391            $err = PEAR::raiseError('File is not readable: ' . $file_name); 
    367392            return $err; 
    368393        } 
    369         if (!$fd = fopen($file_name, 'rb')) { 
    370             $err = PEAR::raiseError('Could not open ' . $file_name); 
    371             return $err; 
    372         } 
    373         $filesize = filesize($file_name); 
    374         if ($filesize == 0){ 
    375             $cont =  ""; 
    376         }else{ 
    377             if ($magic_quote_setting = get_magic_quotes_runtime()){ 
    378                 set_magic_quotes_runtime(0); 
    379             } 
    380             $cont = fread($fd, $filesize); 
    381             if ($magic_quote_setting){ 
    382                 set_magic_quotes_runtime($magic_quote_setting); 
    383             } 
    384         } 
    385         fclose($fd); 
     394         
     395        //Temporarily reset magic_quotes_runtime and read file contents 
     396        if ($magic_quote_setting = get_magic_quotes_runtime()) { 
     397            set_magic_quotes_runtime(0); 
     398        } 
     399        $cont = file_get_contents($file_name);         
     400        if ($magic_quote_setting) { 
     401            set_magic_quotes_runtime($magic_quote_setting); 
     402        } 
     403         
    386404        return $cont; 
    387405    } 
     
    391409     * returns it during the build process. 
    392410     * 
    393      * @param mixed    The object to add the part to, or 
    394      *                 null if a new object is to be created. 
    395      * @param string   The text to add. 
     411     * @param mixed  &$obj The object to add the part to, or 
     412     *                      null if a new object is to be created. 
     413     * @param string $text The text to add. 
     414     * 
    396415     * @return object  The text mimePart object 
    397416     * @access private 
     
    415434     * returns it during the build process. 
    416435     * 
    417      * @param  mixed   The object to add the part to, or 
    418      *                 null if a new object is to be created. 
    419      * @return object  The html mimePart object 
     436     * @param mixed &$obj The object to add the part to, or 
     437     *                     null if a new object is to be created. 
     438     * 
     439     * @return object The html mimePart object 
    420440     * @access private 
    421441     */ 
     
    439459     * build process. 
    440460     * 
    441      * @return object  The multipart/mixed mimePart object 
     461     * @return object The multipart/mixed mimePart object 
    442462     * @access private 
    443463     */ 
    444464    function &_addMixedPart() 
    445465    { 
     466        $params                 = array(); 
    446467        $params['content_type'] = 'multipart/mixed'; 
     468         
     469        //Create empty multipart/mixed Mail_mimePart object to return 
    447470        $ret = new Mail_mimePart('', $params); 
    448471        return $ret; 
     
    454477     * the build process. 
    455478     * 
    456      * @param  mixed   The object to add the part to, or 
    457      *                 null if a new object is to be created. 
     479     * @param mixed &$obj The object to add the part to, or 
     480     *                     null if a new object is to be created. 
     481     * 
    458482     * @return object  The multipart/mixed mimePart object 
    459483     * @access private 
     
    475499     * the build process. 
    476500     * 
    477      * @param mixed    The object to add the part to, or 
    478      *                 null if a new object is to be created 
     501     * @param mixed &$obj The object to add the part to, or 
     502     *                     null if a new object is to be created 
     503     * 
    479504     * @return object  The multipart/mixed mimePart object 
    480505     * @access private 
     
    495520     * and returns it during the build process. 
    496521     * 
    497      * @param  object  The mimePart to add the image to 
    498      * @param  array   The image information 
     522     * @param object &$obj  The mimePart to add the image to 
     523     * @param array  $value The image information 
     524     * 
    499525     * @return object  The image mimePart object 
    500526     * @access private 
     
    502528    function &_addHtmlImagePart(&$obj, $value) 
    503529    { 
    504         $params['content_type'] = $value['c_type'] . '; ' . 
    505                                   'name="' . $value['name'] . '"'; 
     530        $params['content_type'] = $value['c_type']; 
    506531        $params['encoding']     = 'base64'; 
    507532        $params['disposition']  = 'inline'; 
    508533        $params['dfilename']    = $value['name']; 
    509534        $params['cid']          = $value['cid']; 
     535         
    510536        $ret = $obj->addSubpart($value['body'], $params); 
    511537        return $ret; 
    512          
     538     
    513539    } 
    514540 
     
    517543     * and returns it during the build process. 
    518544     * 
    519      * @param  object  The mimePart to add the image to 
    520      * @param  array   The attachment information 
     545     * @param object &$obj  The mimePart to add the image to 
     546     * @param array  $value The attachment information 
     547     * 
    521548     * @return object  The image mimePart object 
    522549     * @access private 
     
    524551    function &_addAttachmentPart(&$obj, $value) 
    525552    { 
    526         $params['dfilename']    = $value['name']; 
    527         $params['encoding']     = $value['encoding']; 
    528         if ($value['disposition'] != "inline") { 
    529             $fname = array("fname" => $value['name']); 
    530             $fname_enc = $this->_encodeHeaders($fname, array('head_charset' => $value['charset'] ? $value['charset'] : 'iso-8859-1')); 
    531             $params['dfilename'] = $fname_enc['fname']; 
    532         } 
     553        $params['dfilename'] = $value['name']; 
     554        $params['encoding']  = $value['encoding']; 
    533555        if ($value['charset']) { 
    534556            $params['charset'] = $value['charset']; 
    535557        } 
    536         $params['content_type'] = $value['c_type'] . '; ' . 
    537                                   'name="' . $params['dfilename'] . '"'; 
     558        if ($value['language']) { 
     559            $params['language'] = $value['language']; 
     560        } 
     561        if ($value['location']) { 
     562            $params['location'] = $value['location']; 
     563        } 
     564        $params['content_type'] = $value['c_type']; 
    538565        $params['disposition']  = isset($value['disposition']) ?  
    539566                                  $value['disposition'] : 'attachment'; 
     
    549576     * using the $xtra_headers parameter! 
    550577     *  
    551      * @param  string $separation   The separation etween these two parts. 
    552      * @param  array  $build_params The Build parameters passed to the 
    553      *                              &get() function. See &get for more info. 
    554      * @param  array  $xtra_headers The extra headers that should be passed 
    555      *                              to the &headers() function. 
    556      *                              See that function for more info. 
    557      * @param  bool   $overwrite    Overwrite the existing headers with new. 
     578     * @param string $separation   The separation etween these two parts. 
     579     * @param array  $build_params The Build parameters passed to the 
     580     *                             &get() function. See &get for more info. 
     581     * @param array  $xtra_headers The extra headers that should be passed 
     582     *                             to the &headers() function. 
     583     *                             See that function for more info. 
     584     * @param bool   $overwrite    Overwrite the existing headers with new. 
     585     * 
    558586     * @return string The complete e-mail. 
    559587     * @access public 
    560588     */ 
    561     function getMessage($separation = null, $build_params = null, $xtra_headers = null, $overwrite = false) 
    562     { 
    563         if ($separation === null) 
    564         { 
     589    function getMessage( 
     590                        $separation   = null,  
     591                        $build_params = null,  
     592                        $xtra_headers = null,  
     593                        $overwrite    = false 
     594                       ) 
     595    { 
     596        if ($separation === null) { 
    565597            $separation = MAIL_MIME_CRLF; 
    566598        } 
     
    576608     * returns the mime content. 
    577609     * 
    578      * @param  array Build parameters that change the way the email 
    579      *                is built. Should be associative. Can contain: 
     610     * @param array $build_params Build parameters that change the way the email 
     611     *                             is built. Should be associative. Can contain: 
    580612     *                head_encoding  -  What encoding to use for the headers.  
    581613     *                                  Options: quoted-printable or base64 
    582614     *                                  Default is quoted-printable 
    583615     *                text_encoding  -  What encoding to use for plain text 
    584      *                                  Options: 7bit, 8bit, base64, or quoted-printable 
     616     *                                  Options: 7bit, 8bit, 
     617     *                                  base64, or quoted-printable 
    585618     *                                  Default is 7bit 
    586619     *                html_encoding  -  What encoding to use for html 
    587      *                                  Options: 7bit, 8bit, base64, or quoted-printable 
     620     *                                  Options: 7bit, 8bit, 
     621     *                                  base64, or quoted-printable 
    588622     *                                  Default is quoted-printable 
    589623     *                7bit_wrap      -  Number of characters before text is 
     
    596630     *                head_charset   -  The character set to use for headers. 
    597631     *                                  Default is iso-8859-1 
     632     * 
    598633     * @return string The mime content 
    599634     * @access public 
     
    606641            } 
    607642        } 
    608  
    609         if (!empty($this->_html_images) AND isset($this->_htmlbody)) { 
     643         
     644        if (isset($this->_headers['From'])){ 
     645            //Bug #11381: Illegal characters in domain ID 
     646            if (preg_match("|(@[0-9a-zA-Z\-\.]+)|", $this->_headers['From'], $matches)){ 
     647                $domainID = $matches[1]; 
     648            }else{ 
     649                $domainID = "@localhost"; 
     650            } 
     651            foreach($this->_html_images as $i => $img){ 
     652                $this->_html_images[$i]['cid'] = $this->_html_images[$i]['cid'] . $domainID; 
     653            } 
     654        } 
     655         
     656        if (count($this->_html_images) AND isset($this->_htmlbody)) { 
    610657            foreach ($this->_html_images as $key => $value) { 
    611                 $regex = array(); 
     658                $regex   = array(); 
    612659                $regex[] = '#(\s)((?i)src|background|href(?-i))\s*=\s*(["\']?)' . 
    613660                            preg_quote($value['name'], '#') . '\3#'; 
    614661                $regex[] = '#(?i)url(?-i)\(\s*(["\']?)' . 
    615662                            preg_quote($value['name'], '#') . '\1\s*\)#'; 
    616                 $rep = array(); 
     663 
     664                $rep   = array(); 
    617665                $rep[] = '\1\2=\3cid:' . $value['cid'] .'\3'; 
    618                 $rep[] = 'url(\1cid:' . $value['cid'] . '\2)'; 
    619                 $this->_htmlbody = preg_replace($regex, $rep, 
    620                                        $this->_htmlbody 
    621                                    ); 
    622                 $this->_html_images[$key]['name'] = basename($this->_html_images[$key]['name']); 
     666                $rep[] = 'url(\1cid:' . $value['cid'] . '\1)'; 
     667 
     668                $this->_htmlbody = preg_replace($regex, $rep, $this->_htmlbody); 
     669                $this->_html_images[$key]['name'] =  
     670                    basename($this->_html_images[$key]['name']); 
    623671            } 
    624672        } 
    625673 
    626674        $null        = null; 
    627         $attachments = !empty($this->_parts)                ? true : false; 
    628         $html_images = !empty($this->_html_images)          ? true : false; 
    629         $html        = !empty($this->_htmlbody)             ? true : false; 
    630         $text        = (!$html AND !empty($this->_txtbody)) ? true : false; 
     675        $attachments = count($this->_parts)                 ? true : false; 
     676        $html_images = count($this->_html_images)           ? true : false; 
     677        $html        = strlen($this->_htmlbody)             ? true : false; 
     678        $text        = (!$html AND strlen($this->_txtbody)) ? true : false; 
    631679 
    632680        switch (true) { 
     
    661709 
    662710        case $html AND !$attachments AND $html_images: 
     711            $message =& $this->_addRelatedPart($null); 
    663712            if (isset($this->_txtbody)) { 
    664                 $message =& $this->_addAlternativePart($null); 
    665                 $this->_addTextPart($message, $this->_txtbody); 
    666                 $related =& $this->_addRelatedPart($message); 
     713                $alt =& $this->_addAlternativePart($message); 
     714                $this->_addTextPart($alt, $this->_txtbody); 
     715                $this->_addHtmlPart($alt); 
    667716            } else { 
    668                 $message =& $this->_addRelatedPart($null); 
    669                 $related =& $message; 
    670             } 
    671             $this->_addHtmlPart($related); 
     717                $this->_addHtmlPart($message); 
     718            } 
    672719            for ($i = 0; $i < count($this->_html_images); $i++) { 
    673                 $this->_addHtmlImagePart($related, $this->_html_images[$i]); 
     720                $this->_addHtmlImagePart($message, $this->_html_images[$i]); 
    674721            } 
    675722            break; 
     
    711758        if (isset($message)) { 
    712759            $output = $message->encode(); 
     760             
    713761            $this->_headers = array_merge($this->_headers, 
    714762                                          $output['headers']); 
     
    727775     * $array['header-name'] = 'header-value'; 
    728776     * 
    729      * @param  array $xtra_headers Assoc array with any extra headers. 
     777     * @param array $xtra_headers Assoc array with any extra headers. 
    730778     *                             Optional. 
    731      * @param  bool  $overwrite    Overwrite already existing headers. 
     779     * @param bool  $overwrite    Overwrite already existing headers. 
     780     *  
    732781     * @return array Assoc array with the mime headers 
    733782     * @access public 
     
    741790            $headers = array_merge($headers, $xtra_headers); 
    742791        } 
    743         if ($overwrite){ 
     792        if ($overwrite) { 
    744793            $this->_headers = array_merge($this->_headers, $headers); 
    745         }else{ 
     794        } else { 
    746795            $this->_headers = array_merge($headers, $this->_headers); 
    747796        } 
     
    755804     * (usefull if you want to use the PHP mail() function) 
    756805     * 
    757      * @param  array   $xtra_headers Assoc array with any extra headers. 
    758      *                               Optional. 
    759      * @param  bool    $overwrite    Overwrite the existing heaers with new. 
     806     * @param array $xtra_headers Assoc array with any extra headers. 
     807     *                             Optional. 
     808     * @param bool  $overwrite    Overwrite the existing heaers with new. 
     809     * 
    760810     * @return string  Plain text headers 
    761811     * @access public 
     
    764814    { 
    765815        $headers = $this->headers($xtra_headers, $overwrite); 
     816         
    766817        $ret = ''; 
    767818        foreach ($headers as $key => $val) { 
     
    774825     * Sets the Subject header 
    775826     * 
    776      * @param  string $subject String to set the subject to 
    777      * access  public 
     827     * @param string $subject String to set the subject to. 
     828     * 
     829     * @return void 
     830     * @access public 
    778831     */ 
    779832    function setSubject($subject) 
     
    785838     * Set an email to the From (the sender) header 
    786839     * 
    787      * @param  string $email The email direction to add 
     840     * @param string $email The email address to use 
     841     * 
     842     * @return void 
    788843     * @access public 
    789844     */ 
     
    797852     * (multiple calls to this method are allowed) 
    798853     * 
    799      * @param  string $email The email direction to add 
     854     * @param string $email The email direction to add 
     855     * 
     856     * @return void 
    800857     * @access public 
    801858     */ 
     
    813870     * (multiple calls to this method are allowed) 
    814871     * 
    815      * @param  string $email The email direction to add 
     872     * @param string $email The email direction to add 
     873     * 
     874     * @return void 
    816875     * @access public 
    817876     */ 
     
    833892     * function 
    834893     * 
    835      * @param  string $recipients A comma-delimited list of recipients 
     894     * @param string $recipients A comma-delimited list of recipients 
     895     * 
    836896     * @return string Encoded data 
    837897     * @access public 
     
    847907     * Encodes a header as per RFC2047 
    848908     * 
    849      * @param  array $input  The header data to encode 
    850      * @param  array $params Extra build parameters 
     909     * @param array $input  The header data to encode 
     910     * @param array $params Extra build parameters 
     911     * 
    851912     * @return array Encoded data 
    852913     * @access private 
     
    859920            $build_params[$key] = $value; 
    860921        } 
    861          
     922        //$hdr_name: Name of the heaer 
     923        //$hdr_value: Full line of header value. 
     924        //$atoms: The $hdr_value split into atoms* 
     925        //$atom: A single atom to encode.* 
     926        //$hdr_value_out: The recombined $hdr_val-atoms, or the encoded string. 
     927        //Note: Atom as specified here is not exactly the same as an RFC822 atom, 
     928        //as $atom's may contain just a single space. 
     929                 
     930        $useIconv = true;         
     931        if (isset($build_params['ignore-iconv'])) { 
     932            $useIconv = !$build_params['ignore-iconv']; 
     933        }             
    862934        foreach ($input as $hdr_name => $hdr_value) { 
    863             $hdr_vals = preg_split("|(\s)|", $hdr_value, -1, PREG_SPLIT_DELIM_CAPTURE); 
    864             $hdr_value_out=""; 
    865             $previous = ""; 
    866             foreach ($hdr_vals as $hdr_val){ 
    867                 if (!trim($hdr_val)){ 
    868                     //whitespace needs to be handled with another string, or it 
    869                     //won't show between encoded strings. Prepend this to the next item. 
    870                     $previous .= $hdr_val; 
    871                     continue; 
    872                 }else{ 
    873                     $hdr_val = $previous . $hdr_val; 
    874                     $previous = ""; 
     935            /* 
     936            $parts = preg_split('/([ ])/', $hdr_value, -1, PREG_SPLIT_DELIM_CAPTURE); 
     937            $atoms = array(); 
     938            foreach ($parts as $part){ 
     939                $atom .= $part; 
     940                $quoteMatch = preg_match_all('|"|', $atom, $matches) % 2; 
     941                if (!$quoteMatch){ 
     942                    $atoms[] = $atom; 
     943                    $atom = null; 
    875944                } 
    876                 if (function_exists('iconv_mime_encode') && preg_match('#[\x80-\xFF]{1}#', $hdr_val)){ 
    877                     $imePref = array(); 
    878                     if ($build_params['head_encoding'] == 'base64'){ 
     945            } 
     946            if ($atom){ 
     947                $atoms[] = $atom; 
     948            } 
     949            foreach ($atoms as $atom){ 
     950            */ 
     951            if (preg_match('#([\x80-\xFF]){1}#', $hdr_value)) { 
     952                if (function_exists('iconv_mime_encode') && $useIconv) { 
     953                    $imePrefs = array(); 
     954                    if ($build_params['head_encoding'] == 'base64') { 
    879955                        $imePrefs['scheme'] = 'B'; 
    880                     }else{ 
     956                    } else { 
    881957                        $imePrefs['scheme'] = 'Q'; 
    882958                    } 
    883959                    $imePrefs['input-charset']  = $build_params['head_charset']; 
    884960                    $imePrefs['output-charset'] = $build_params['head_charset']; 
    885                     $hdr_val = iconv_mime_encode($hdr_name, $hdr_val, $imePrefs); 
    886                     $hdr_val = preg_replace("#^{$hdr_name}\:\ #", "", $hdr_val); 
    887                 }elseif (preg_match('#[\x80-\xFF]{1}#', $hdr_val)){ 
    888                     //This header contains non ASCII chars and should be encoded. 
    889                     switch ($build_params['head_encoding']) { 
    890                     case 'base64': 
    891                         //Base64 encoding has been selected. 
    892                          
    893                         //Generate the header using the specified params and dynamicly  
    894                         //determine the maximum length of such strings. 
    895                         //75 is the value specified in the RFC. The first -2 is there so  
    896                         //the later regexp doesn't break any of the translated chars. 
    897                         //The -2 on the first line-regexp is to compensate for the ": " 
    898                         //between the header-name and the header value 
    899                         $prefix = '=?' . $build_params['head_charset'] . '?B?'; 
    900                         $suffix = '?='; 
    901                         $maxLength = 75 - strlen($prefix . $suffix) - 2; 
    902                         $maxLength1stLine = $maxLength - strlen($hdr_name) - 2; 
    903                          
    904                         //Base64 encode the entire string 
    905                         $hdr_val = base64_encode($hdr_val); 
    906                          
    907                         //This regexp will break base64-encoded text at every  
    908                         //$maxLength but will not break any encoded letters. 
    909                         $reg1st = "|.{0,$maxLength1stLine}[^\=][^\=]|"; 
    910                         $reg2nd = "|.{0,$maxLength}[^\=][^\=]|"; 
    911                         break; 
    912                     case 'quoted-printable': 
    913                     default: 
    914                         //quoted-printable encoding has been selected 
    915                          
    916                         //Generate the header using the specified params and dynamicly  
    917                         //determine the maximum length of such strings. 
    918                         //75 is the value specified in the RFC. The -2 is there so  
    919                         //the later regexp doesn't break any of the translated chars. 
    920                         //The -2 on the first line-regexp is to compensate for the ": " 
    921                         //between the header-name and the header value 
    922                         $prefix = '=?' . $build_params['head_charset'] . '?Q?'; 
    923                         $suffix = '?='; 
    924                         $maxLength = 75 - strlen($prefix . $suffix) - 2; 
    925                         $maxLength1stLine = $maxLength - strlen($hdr_name) - 2; 
    926                          
    927                         //Replace all special characters used by the encoder. 
    928                         $search  = array("=",   "_",   "?",   " "); 
    929                         $replace = array("=3D", "=5F", "=3F", "_"); 
    930                         $hdr_val = str_replace($search, $replace, $hdr_val); 
    931                          
    932                         //Replace all extended characters (\x80-xFF) with their 
    933                         //ASCII values. 
    934                         $hdr_val = preg_replace( 
    935                             '#([\x80-\xFF])#e', 
    936                             '"=" . strtoupper(dechex(ord("\1")))', 
    937                             $hdr_val 
    938                         ); 
    939                         //This regexp will break QP-encoded text at every $maxLength 
    940                         //but will not break any encoded letters. 
    941                         $reg1st = "|(.{0,$maxLength1stLine})[^\=]|"; 
    942                         $reg2nd = "|(.{0,$maxLength})[^\=]|"; 
    943                         break; 
    944                     } 
    945                     //Begin with the regexp for the first line. 
    946                     $reg = $reg1st; 
    947                     //Prevent lins that are just way to short; 
    948                     if ($maxLength1stLine >1){ 
    949                         $reg = $reg2nd; 
    950                     } 
     961                    $imePrefs['line-length'] = 74; 
     962                    $imePrefs['line-break-chars'] = "\r\n"; //Specified in RFC2047 
     963                     
     964                    $hdr_value = iconv_mime_encode($hdr_name, $hdr_value, $imePrefs); 
     965                    $hdr_value = preg_replace("#^{$hdr_name}\:\ #", "", $hdr_value); 
     966                } elseif ($build_params['head_encoding'] == 'base64') { 
     967                    //Base64 encoding has been selected. 
     968                    //Base64 encode the entire string 
     969                    $hdr_value = base64_encode($hdr_value); 
     970                     
     971                    //Generate the header using the specified params and dynamicly  
     972                    //determine the maximum length of such strings. 
     973                    //75 is the value specified in the RFC. The first -2 is there so  
     974                    //the later regexp doesn't break any of the translated chars. 
     975                    //The -2 on the first line-regexp is to compensate for the ": " 
     976                    //between the header-name and the header value 
     977                    $prefix = '=?' . $build_params['head_charset'] . '?B?'; 
     978                    $suffix = '?='; 
     979                    $maxLength = 75 - strlen($prefix . $suffix) - 2; 
     980                    $maxLength1stLine = $maxLength - strlen($hdr_name) - 2; 
     981 
     982                    //We can cut base4 every 4 characters, so the real max 
     983                    //we can get must be rounded down. 
     984                    $maxLength = $maxLength - ($maxLength % 4); 
     985                    $maxLength1stLine = $maxLength1stLine - ($maxLength1stLine % 4); 
     986                     
     987                    $cutpoint = $maxLength1stLine; 
     988                    $hdr_value_out = $hdr_value; 
    951989                    $output = ""; 
    952                     while ($hdr_val) { 
     990                    while ($hdr_value_out) { 
    953991                        //Split translated string at every $maxLength 
    954                         //But make sure not to break any translated chars. 
    955                         $found = preg_match($reg, $hdr_val, $matches); 
    956                          
    957                         //After this first line, we need to use a different 
    958                         //regexp for the first line. 
    959                         $reg = $reg2nd; 
    960                          
    961                         //Save the found part and encapsulate it in the 
    962                         //prefix & suffix. Then remove the part from the 
    963                         //$hdr_val variable. 
    964                         if ($found){ 
    965                             $part = $matches[0]; 
    966                             $hdr_val = substr($hdr_val, strlen($matches[0])); 
    967                         }else{ 
    968                             $part = $hdr_val; 
    969                             $hdr_val = ""; 
    970                         } 
    971                          
    972                         //RFC 2047 specifies that any split header should be seperated 
    973                         //by a CRLF SPACE.  
    974                         if ($output){ 
     992                        $part = substr($hdr_value_out, 0, $cutpoint); 
     993                        $hdr_value_out = substr($hdr_value_out, $cutpoint); 
     994                        $cutpoint = $maxLength; 
     995                        //RFC 2047 specifies that any split header should  
     996                        //be seperated by a CRLF SPACE.  
     997                        if ($output) { 
    975998                            $output .=  "\r\n "; 
    976999                        } 
    9771000                        $output .= $prefix . $part . $suffix; 
    9781001                    } 
    979                     $hdr_val = $output; 
     1002                    $hdr_value = $output; 
     1003                } else { 
     1004                    //quoted-printable encoding has been selected 
     1005 
     1006                    //Fix for Bug #10298, Ota Mares <om@viazenetti.de> 
     1007                    //Check if there is a double quote at beginning or end of 
     1008                    //the string to prevent that an open or closing quote gets  
     1009                    //ignored because it is encapsuled by an encoding pre/suffix. 
     1010                    //Remove the double quote and set the specific prefix or  
     1011                    //suffix variable so that we can concat the encoded string and 
     1012                    //the double quotes back together to get the intended string. 
     1013                    $quotePrefix = $quoteSuffix = ''; 
     1014                    if ($hdr_value{0} == '"') { 
     1015                        $hdr_value = substr($hdr_value, 1); 
     1016                        $quotePrefix = '"'; 
     1017                    } 
     1018                    if ($hdr_value{strlen($hdr_value)-1} == '"') { 
     1019                        $hdr_value = substr($hdr_value, 0, -1); 
     1020                        $quoteSuffix = '"'; 
     1021                    } 
     1022                     
     1023                    //Generate the header using the specified params and dynamicly  
     1024                    //determine the maximum length of such strings. 
     1025                    //75 is the value specified in the RFC. The -2 is there so  
     1026                    //the later regexp doesn't break any of the translated chars. 
     1027                    //The -2 on the first line-regexp is to compensate for the ": " 
     1028                    //between the header-name and the header value 
     1029                    $prefix = '=?' . $build_params['head_charset'] . '?Q?'; 
     1030                    $suffix = '?='; 
     1031                    $maxLength = 75 - strlen($prefix . $suffix) - 2 - 1; 
     1032                    $maxLength1stLine = $maxLength - strlen($hdr_name) - 2; 
     1033                    $maxLength = $maxLength - 1; 
     1034                     
     1035                    //Replace all special characters used by the encoder. 
     1036                    $search  = array('=',   '_',   '?',   ' '); 
     1037                    $replace = array('=3D', '=5F', '=3F', '_'); 
     1038                    $hdr_value = str_replace($search, $replace, $hdr_value); 
     1039                     
     1040                    //Replace all extended characters (\x80-xFF) with their 
     1041                    //ASCII values. 
     1042                    $hdr_value = preg_replace('#([\x80-\xFF])#e', 
     1043                        '"=" . strtoupper(dechex(ord("\1")))', 
     1044                        $hdr_value); 
     1045 
     1046                    //This regexp will break QP-encoded text at every $maxLength 
     1047                    //but will not break any encoded letters. 
     1048                    $reg1st = "|(.{0,$maxLength1stLine}[^\=][^\=])|"; 
     1049                    $reg2nd = "|(.{0,$maxLength}[^\=][^\=])|"; 
     1050                    //Fix for Bug #10298, Ota Mares <om@viazenetti.de> 
     1051                    //Concat the double quotes and encoded string together 
     1052                    $hdr_value = $quotePrefix . $hdr_value . $quoteSuffix; 
     1053                     
     1054 
     1055                    $hdr_value_out = $hdr_value; 
     1056                    $realMax = $maxLength1stLine + strlen($prefix . $suffix); 
     1057                    if (strlen($hdr_value_out) >= $realMax) { 
     1058                        //Begin with the regexp for the first line. 
     1059                        $reg = $reg1st; 
     1060                        $output = ""; 
     1061                        while ($hdr_value_out) { 
     1062                            //Split translated string at every $maxLength 
     1063                            //But make sure not to break any translated chars. 
     1064                            $found = preg_match($reg, $hdr_value_out, $matches); 
     1065                             
     1066                            //After this first line, we need to use a different 
     1067                            //regexp for the first line. 
     1068                            $reg = $reg2nd; 
     1069                             
     1070                            //Save the found part and encapsulate it in the 
     1071                            //prefix & suffix. Then remove the part from the 
     1072                            //$hdr_value_out variable. 
     1073                            if ($found) { 
     1074                                $part = $matches[0]; 
     1075                                $len = strlen($matches[0]); 
     1076                                $hdr_value_out = substr($hdr_value_out, $len); 
     1077                            } else { 
     1078                                $part = $hdr_value_out; 
     1079                                $hdr_value_out = ""; 
     1080                            } 
     1081                             
     1082                            //RFC 2047 specifies that any split header should  
     1083                            //be seperated by a CRLF SPACE 
     1084                            if ($output) { 
     1085                                $output .=  "\r\n "; 
     1086                            } 
     1087                            $output .= $prefix . $part . $suffix; 
     1088                        } 
     1089                        $hdr_value_out = $output; 
     1090                    } else { 
     1091                        $hdr_value_out = $prefix . $hdr_value_out . $suffix; 
     1092                    } 
     1093                    $hdr_value = $hdr_value_out; 
    9801094                } 
    981                 $hdr_value_out .= $hdr_val; 
    982             } 
    983             $input[$hdr_name] = $hdr_value_out; 
    984         } 
    985  
     1095            } 
     1096            $input[$hdr_name] = $hdr_value; 
     1097        } 
    9861098        return $input; 
    9871099    } 
    9881100 
    9891101    /** 
    990      * Set the object's end-of-line and define the constant if applicable 
     1102     * Set the object's end-of-line and define the constant if applicable. 
    9911103     * 
    9921104     * @param string $eol End Of Line sequence 
     1105     * 
     1106     * @return void 
    9931107     * @access private 
    9941108     */ 
  • trunk/roundcubemail/program/lib/Mail/mimePart.php

    r1323 r1530  
    136136        } 
    137137 
     138        $contentType = array(); 
     139        $contentDisp = array(); 
    138140        foreach ($params as $key => $value) { 
    139141            switch ($key) { 
    140142                case 'content_type': 
    141                     $headers['Content-Type'] = $value . (isset($charset) ? '; charset="' . $charset . '"' : ''); 
     143                    $contentType['type'] = $value; 
     144                    //$headers['Content-Type'] = $value . (isset($charset) ? '; charset="' . $charset . '"' : ''); 
    142145                    break; 
    143146 
     
    152155 
    153156                case 'disposition': 
    154                     $headers['Content-Disposition'] = $value . (isset($dfilename) ? '; filename="' . $dfilename . '"' : ''); 
     157                    $contentDisp['disp'] = $value; 
    155158                    break; 
    156159 
    157160                case 'dfilename': 
    158                     if (isset($headers['Content-Disposition'])) { 
    159                         $headers['Content-Disposition'] .= '; filename="' . $value . '"'; 
    160                     } else { 
    161                         $dfilename = $value; 
    162                     } 
     161                    $contentDisp['filename'] = $value; 
     162                    $contentType['name'] = $value; 
    163163                    break; 
    164164 
     
    168168 
    169169                case 'charset': 
    170                     if (isset($headers['Content-Type'])) { 
    171                         $headers['Content-Type'] .= '; charset="' . $value . '"'; 
    172                     } else { 
    173                         $charset = $value; 
    174                     } 
    175                     break; 
     170                    $contentType['charset'] = $value; 
     171                    $contentDisp['charset'] = $value; 
     172                    break; 
     173 
     174                case 'language': 
     175                    $contentType['language'] = $value; 
     176                    $contentDisp['language'] = $value; 
     177                    break; 
     178 
     179                case 'location': 
     180                    $headers['Content-Location'] = $value; 
     181                    break; 
     182 
    176183            } 
    177184        } 
    178  
     185        if (isset($contentType['type'])) { 
     186            $headers['Content-Type'] = $contentType['type']; 
     187            if (isset($contentType['name'])) { 
     188                $headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF; 
     189                $headers['Content-Type'] .= $this->_buildHeaderParam('name', $contentType['name'],  
     190                                                isset($contentType['charset']) ? $contentType['charset'] : 'US-ASCII',  
     191                                                isset($contentType['language']) ? $contentType['language'] : NULL); 
     192            } elseif (isset($contentType['charset'])) { 
     193                $headers['Content-Type'] .= "; charset=\"{$contentType['charset']}\""; 
     194            } 
     195        } 
     196 
     197 
     198        if (isset($contentDisp['disp'])) { 
     199            $headers['Content-Disposition'] = $contentDisp['disp']; 
     200            if (isset($contentDisp['filename'])) { 
     201                $headers['Content-Disposition'] .= ';' . MAIL_MIMEPART_CRLF; 
     202                $headers['Content-Disposition'] .= $this->_buildHeaderParam('filename', $contentDisp['filename'],  
     203                                                isset($contentDisp['charset']) ? $contentDisp['charset'] : 'US-ASCII',  
     204                                                isset($contentDisp['language']) ? $contentDisp['language'] : NULL); 
     205            } 
     206        } 
     207         
     208         
     209         
     210         
    179211        // Default content-type 
    180212        if (!isset($headers['Content-Type'])) { 
     
    208240        $encoded =& $this->_encoded; 
    209241 
    210         if (!empty($this->_subparts)) { 
    211 // http://pear.php.net/bugs/bug.php?id=13032 
    212 //            srand((double)microtime()*1000000); 
     242        if (count($this->_subparts)) { 
     243            srand((double)microtime()*1000000); 
    213244            $boundary = '=_' . md5(rand() . microtime()); 
    214245            $this->_headers['Content-Type'] .= ';' . MAIL_MIMEPART_CRLF . "\t" . 'boundary="' . $boundary . '"'; 
     
    221252                    $headers[] = $key . ': ' . $value; 
    222253                } 
    223                 $subparts[] = implode(MAIL_MIMEPART_CRLF, $headers) . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF . $tmp['body']; 
     254                $subparts[] = implode(MAIL_MIMEPART_CRLF, $headers) . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF . $tmp['body'] . MAIL_MIMEPART_CRLF; 
    224255            } 
    225256 
    226             $encoded['body'] = '--' . $boundary . MAIL_MIMEPART_CRLF . 
    227                                implode('--' . $boundary . MAIL_MIMEPART_CRLF, $subparts) . 
    228                                '--' . $boundary.'--' . MAIL_MIMEPART_CRLF . MAIL_MIMEPART_CRLF; 
     257            $encoded['body'] = '--' . $boundary . MAIL_MIMEPART_CRLF .  
     258                               rtrim(implode('--' . $boundary . MAIL_MIMEPART_CRLF , $subparts), MAIL_MIMEPART_CRLF) . MAIL_MIMEPART_CRLF .  
     259                               '--' . $boundary.'--' . MAIL_MIMEPART_CRLF; 
    229260 
    230261        } else { 
    231             $encoded['body'] = $this->_getEncodedData($this->_body, $this->_encoding) . MAIL_MIMEPART_CRLF; 
     262            $encoded['body'] = $this->_getEncodedData($this->_body, $this->_encoding); 
    232263        } 
    233264 
     
    308339        $output = ''; 
    309340 
    310         while(list(, $line) = each($lines)){ 
     341        while (list(, $line) = each($lines)) { 
    311342 
    312343            $line    = preg_split('||', $line, -1, PREG_SPLIT_NO_EMPTY); 
     
    318349                $dec  = ord($char); 
    319350 
    320                 if (($dec == 32) AND ($i == ($linlen - 1))){    // convert space at eol only 
     351                if (($dec == 32) AND ($i == ($linlen - 1))) {    // convert space at eol only 
    321352                    $char = '=20'; 
    322353 
    323                 } elseif(($dec == 9) AND ($i == ($linlen - 1))) {  // convert tab at eol only 
     354                } elseif (($dec == 9) AND ($i == ($linlen - 1))) {  // convert tab at eol only 
    324355                    $char = '=09'; 
    325                 } elseif($dec == 9) { 
     356                } elseif ($dec == 9) { 
    326357                    ; // Do nothing if a tab. 
    327                 } elseif(($dec == 61) OR ($dec < 32 ) OR ($dec > 126)) { 
     358                } elseif (($dec == 61) OR ($dec < 32 ) OR ($dec > 126)) { 
    328359                    $char = $escape . strtoupper(sprintf('%02s', dechex($dec))); 
     360                } elseif (($dec == 46) AND (($newline == '') || ((strlen($newline) + strlen("=2E")) >= $line_max))) { 
     361                    //Bug #9722: convert full-stop at bol, 
     362                    //some Windows servers need this, won't break anything (cipri) 
     363                    //Bug #11731: full-stop at bol also needs to be encoded 
     364                    //if this line would push us over the line_max limit. 
     365                    $char = '=2E'; 
    329366                } 
    330367 
     368                //Note, when changing this line, also change the ($dec == 46) 
     369                //check line, as it mimics this line due to Bug #11731 
    331370                if ((strlen($newline) + strlen($char)) >= $line_max) {        // MAIL_MIMEPART_CRLF is not counted 
    332371                    $output  .= $newline . $escape . $eol;                    // soft line break; " =\r\n" is okay 
     
    340379        return $output; 
    341380    } 
     381 
     382    /** 
     383     * _buildHeaderParam() 
     384     * 
     385     * Encodes the paramater of a header. 
     386     * 
     387     * @param $name         The name of the header-parameter 
     388     * @param $value        The value of the paramter 
     389     * @param $charset      The characterset of $value 
     390     * @param $language     The language used in $value 
     391     * @param $maxLength    The maximum length of a line. Defauls to 75 
     392     * 
     393     * @access private 
     394     */ 
     395    function _buildHeaderParam($name, $value, $charset=NULL, $language=NULL, $maxLength=75) 
     396    { 
     397        //If we find chars to encode, or if charset or language 
     398        //is not any of the defaults, we need to encode the value. 
     399        $shouldEncode = 0; 
     400        $secondAsterisk = ''; 
     401        if (preg_match('#([\x80-\xFF]){1}#', $value)) { 
     402            $shouldEncode = 1; 
     403        } elseif ($charset && (strtolower($charset) != 'us-ascii')) { 
     404            $shouldEncode = 1; 
     405        } elseif ($language && ($language != 'en' && $language != 'en-us')) { 
     406            $shouldEncode = 1; 
     407        } 
     408        if ($shouldEncode) { 
     409            $search  = array('%',   ' ',   "\t"); 
     410            $replace = array('%25', '%20', '%09'); 
     411            $encValue = str_replace($search, $replace, $value); 
     412            $encValue = preg_replace('#([\x80-\xFF])#e', '"%" . strtoupper(dechex(ord("\1")))', $encValue); 
     413            $value = "$charset'$language'$encValue"; 
     414            $secondAsterisk = '*'; 
     415        } 
     416        $header = " {$name}{$secondAsterisk}=\"{$value}\"; "; 
     417        if (strlen($header) <= $maxLength) { 
     418            return $header; 
     419        } 
     420 
     421        $preLength = strlen(" {$name}*0{$secondAsterisk}=\""); 
     422        $sufLength = strlen("\";"); 
     423        $maxLength = MAX(16, $maxLength - $preLength - $sufLength - 2); 
     424        $maxLengthReg = "|(.{0,$maxLength}[^\%][^\%])|"; 
     425 
     426        $headers = array(); 
     427        $headCount = 0; 
     428        while ($value) { 
     429            $matches = array(); 
     430            $found = preg_match($maxLengthReg, $value, $matches); 
     431            if ($found) { 
     432                $headers[] = " {$name}*{$headCount}{$secondAsterisk}=\"{$matches[0]}\""; 
     433                $value = substr($value, strlen($matches[0])); 
     434            } else { 
     435                $headers[] = " {$name}*{$headCount}{$secondAsterisk}=\"{$value}\""; 
     436                $value = ""; 
     437            } 
     438            $headCount++; 
     439        } 
     440        $headers = implode(MAIL_MIMEPART_CRLF, $headers) . ';'; 
     441        return $headers; 
     442    } 
    342443} // End of class 
Note: See TracChangeset for help on using the changeset viewer.