Changeset ffae15e5 in github


Ignore:
Timestamp:
Sep 29, 2008 3:38:16 AM (5 years ago)
Author:
alecpl <alec@…>
Branches:
master, HEAD, courier-fix, dev-browser-capabilities, pdo, release-0.6, release-0.7, release-0.8
Children:
8d0224c
Parents:
29e697b
Message:
  • Added 'mime_param_folding' option with possibility to choose long/non-ascii attachment names encoding eg. to be readable in MS Outlook/OE (#1485320)
  • Added "advanced options" feature in User Preferences
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • CHANGELOG

    r09f19e6 rffae15e5  
    11CHANGELOG RoundCube Webmail 
    22--------------------------- 
     3 
     42008/09/29 (alec) 
     5---------- 
     6- Added 'mime_param_folding' option with possibility to choose  
     7  long/non-ascii attachment names encoding eg. to be readable 
     8  in MS Outlook/OE (#1485320) 
     9- Added "advanced options" feature in User Preferences 
    310 
    4112008/09/25 (alec) 
  • config/main.inc.php.dist

    r2fd6c21 rffae15e5  
    378378$rcmail_config['inline_images'] = TRUE; 
    379379 
     380// Encoding of long/non-ascii attachment names: 
     381// 0 - Full RFC 2231 compatible 
     382// 1 - RFC 2047 for 'name' and RFC 2231 for 'filename' parameter (Thunderbird's default) 
     383// 2 - Full 2047 compatible 
     384$rcmail_config['mime_param_folding'] = 0; 
     385 
    380386// end of config file 
    381387?> 
  • installer/config.php

    r7d7f67d rffae15e5  
    540540</dd> 
    541541 
     542<dt class="propname">mime_param_folding <span class="userconf">*</span></dt> 
     543<dd> 
     544<?php 
     545 
     546$select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => "cfgmimeparamfolding")); 
     547$select_param_folding->add('Full RFC 2231 (Roundcube, Thunderbird)', '0');  
     548$select_param_folding->add('RFC 2047/2231 (MS Outlook, OE)', '1'); 
     549$select_param_folding->add('Full RFC 2047 (deprecated)', '2'); 
     550 
     551echo $select_param_folding->show(intval($RCI->getprop('mime_param_folding'))); 
     552 
     553?> 
     554<div>How to encode attachment long/non-ascii names</div> 
     555</dd> 
     556 
    542557</dl> 
    543558 
  • program/include/html.php

    r95fcc33 rffae15e5  
    592592    { 
    593593        if (is_string($attr)) 
    594         $attr = array('class' => $attr); 
     594            $attr = array('class' => $attr); 
    595595 
    596596        $cell = new stdClass; 
     
    614614    } 
    615615 
     616    /** 
     617     * Set current row attrib 
     618     * 
     619     * @param array Row attributes 
     620     */ 
     621    public function set_row_attribs($attr = array()) 
     622    { 
     623        if (is_string($attr)) 
     624            $attr = array('class' => $attr); 
     625 
     626        $this->rows[$this->rowindex]->attrib = $attr; 
     627    } 
    616628 
    617629    /** 
  • program/lib/Mail/mime.php

    r09f19e6 rffae15e5  
    324324     * @param string $language    The language of the attachment 
    325325     * @param string $location    The RFC 2557.4 location of the attachment 
     326     * @param string $n_encoding      Use RFC 2047 for attachment name (Content-Type) encoding 
     327     * @param string $f_encoding      Use RFC 2047 for attachment filename (Content-Disposition) encoding 
    326328     * 
    327329     * @return mixed true on success or PEAR_Error object 
     
    336338                           $charset     = '', 
    337339                            $language   = '', 
    338                            $location    = '') 
     340                           $location    = '', 
     341                           $n_encoding  = NULL, 
     342                           $f_encoding   = NULL) 
    339343    { 
    340344        $filedata = ($isfile === true) ? $this->_file2str($file) 
     
    364368                                'language'    => $language, 
    365369                                'location'    => $location, 
    366                                 'disposition' => $disposition 
     370                                'disposition' => $disposition, 
     371                                'name-encoding'    => $n_encoding, 
     372                                'filename-encoding'=> $f_encoding 
    367373                               ); 
    368374        return true; 
     
    533539        $params['dfilename']    = $value['name']; 
    534540        $params['cid']          = $value['cid']; 
     541        if ($value['name-encoding']) { 
     542            $params['name-encoding'] = $value['name-encoding']; 
     543        } 
     544        if ($value['filename-encoding']) { 
     545            $params['filename-encoding'] = $value['filename-encoding']; 
     546        } 
    535547         
    536548        $ret = $obj->addSubpart($value['body'], $params); 
     
    562574            $params['location'] = $value['location']; 
    563575        } 
     576        if ($value['name-encoding']) { 
     577            $params['name-encoding'] = $value['name-encoding']; 
     578        } 
     579        if ($value['filename-encoding']) { 
     580            $params['filename-encoding'] = $value['filename-encoding']; 
     581        } 
    564582        $params['content_type'] = $value['c_type']; 
    565583        $params['disposition']  = isset($value['disposition']) ?  
     
    915933    function _encodeHeaders($input, $params = array()) 
    916934    { 
    917          
    918935        $build_params = $this->_build_params; 
    919936        while (list($key, $value) = each($params)) { 
  • program/lib/Mail/mimePart.php

    r5ec762a rffae15e5  
    183183            } 
    184184        } 
     185         
    185186        if (isset($contentType['type'])) { 
    186187            $headers['Content-Type'] = $contentType['type']; 
    187188            if (isset($contentType['name'])) { 
    188189                $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); 
     190                $headers['Content-Type'] .= 
     191                    $this->_buildHeaderParam('name', $contentType['name'],  
     192                        isset($contentType['charset']) ? $contentType['charset'] : 'US-ASCII',  
     193                        isset($contentType['language']) ? $contentType['language'] : NULL, 
     194                        isset($params['name-encoding']) ?  $params['name-encoding'] : NULL); 
    192195            } elseif (isset($contentType['charset'])) { 
    193196                $headers['Content-Type'] .= "; charset=\"{$contentType['charset']}\""; 
     
    200203            if (isset($contentDisp['filename'])) { 
    201204                $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                $headers['Content-Disposition'] .= 
     206                    $this->_buildHeaderParam('filename', $contentDisp['filename'],  
     207                        isset($contentDisp['charset']) ? $contentDisp['charset'] : 'US-ASCII',  
     208                        isset($contentDisp['language']) ? $contentDisp['language'] : NULL, 
     209                        isset($params['filename-encoding']) ? $params['filename-encoding'] : NULL); 
    205210            } 
    206211        } 
    207          
    208          
    209          
    210          
     212 
    211213        // Default content-type 
    212214        if (!isset($headers['Content-Type'])) { 
     
    389391     * @param $charset      The characterset of $value 
    390392     * @param $language     The language used in $value 
     393     * @param $paramEnc     Parameter encoding type 
    391394     * @param $maxLength    The maximum length of a line. Defauls to 78 
    392395     * 
    393396     * @access private 
    394397     */ 
    395     function _buildHeaderParam($name, $value, $charset=NULL, $language=NULL, $maxLength=78) 
     398    function _buildHeaderParam($name, $value, $charset=NULL, $language=NULL, $paramEnc=NULL, $maxLength=78) 
    396399    { 
    397400        // RFC 2183/2184/2822:  
    398401        // value needs encoding if contains non-ASCII chars or is longer than 78 chars 
    399  
    400402        if (!preg_match('#[^\x20-\x7E]#', $value)) { // ASCII 
    401403            $quoted = addcslashes($value, '\\"'); 
     
    404406        } 
    405407 
     408        // use quoted-printable/base64 encoding (RFC2047) 
     409        if ($paramEnc == 'quoted-printable' || $paramEnc == 'base64') 
     410            return $this->_buildRFC2047Param($name, $value, $charset, $paramEnc); 
     411 
    406412        $encValue = preg_replace('#([^\x20-\x7E])#e', '"%" . strtoupper(dechex(ord("\1")))', $value); 
    407413        $value = "$charset'$language'$encValue"; 
     
    414420        $preLength = strlen(" {$name}*0*=\""); 
    415421        $sufLength = strlen("\";"); 
    416         $maxLength = MAX(16, $maxLength - $preLength - $sufLength - 2); 
     422        $maxLength = max(16, $maxLength - $preLength - $sufLength - 2); 
    417423        $maxLengthReg = "|(.{0,$maxLength}[^\%][^\%])|"; 
    418424 
     
    434440        return $headers; 
    435441    } 
     442 
     443    /** 
     444     * Encodes header parameter as per RFC2047 if needed (values too long will be truncated) 
     445     * 
     446     * @param string $name  The parameter name 
     447     * @param string $value  The parameter value 
     448     * @param string $charset  The parameter charset 
     449     * @param string $encoding  Encoding type (quoted-printable or base64) 
     450     * @param int $maxLength  Encoded parameter max length (75 is the value specified in the RFC) 
     451     * 
     452     * @return string Parameter line 
     453     * @access private 
     454     */ 
     455    function _buildRFC2047Param($name, $value, $charset, $encoding='quoted-printable', $maxLength=75) 
     456    { 
     457        if (!preg_match('#([^\x20-\x7E]){1}#', $value)) 
     458        { 
     459            $quoted = addcslashes($value, '\\"'); 
     460            $maxLength = $maxLength - 6; 
     461            if (strlen($quoted) > $maxLength) 
     462            { 
     463                // truncate filename leaving extension 
     464                $ext = strrchr($quoted, '.'); 
     465                $quoted = substr($quoted, 0, $maxLength - strlen($ext)); 
     466                // remove backslashes from the end of filename 
     467                preg_replace('/[\\\\]+$/', '', $quoted); 
     468                $quoted .= $ext; 
     469            } 
     470        } 
     471        else if ($encoding == 'base64') 
     472        { 
     473            $ext = strrchr($value, '.'); 
     474            $value = substr($value, 0, strlen($value) - strlen($ext)); 
     475             
     476            $ext = base64_encode($ext); 
     477            $value = base64_encode($value); 
     478 
     479            $prefix = '=?' . $charset . '?B?'; 
     480            $suffix = '?='; 
     481            $maxLength = $maxLength - strlen($prefix . $suffix) - strlen($ext) - 2; 
     482 
     483            //We can cut base64 every 4 characters, so the real max 
     484            //we can get must be rounded down. 
     485            $maxLength = $maxLength - ($maxLength % 4); 
     486            $quoted = $prefix . substr($value, 0, $maxLength) . $ext . $suffix; 
     487        } 
     488        else // quoted-printable 
     489        { 
     490            $ext = strrchr($value, '.'); 
     491            $value = substr($value, 0, strlen($value) - strlen($ext)); 
     492 
     493            // Replace all special characters used by the encoder. 
     494            $search  = array('=',   '_',   '?',   ' '); 
     495            $replace = array('=3D', '=5F', '=3F', '_'); 
     496            $ext = str_replace($search, $replace, $ext); 
     497            $value = str_replace($search, $replace, $value); 
     498 
     499            // Replace all extended characters (\x80-xFF) with their 
     500            // ASCII values. 
     501            $ext = preg_replace('/([\x80-\xFF])/e',  
     502                '"=" . strtoupper(dechex(ord("\1")))', $ext); 
     503            $value = preg_replace('/([\x80-\xFF])/e',  
     504                '"=" . strtoupper(dechex(ord("\1")))', $value); 
     505 
     506            $prefix = '=?' . $charset . '?Q?'; 
     507            $suffix = '?='; 
     508 
     509            $maxLength = $maxLength - strlen($prefix . $suffix) - strlen($ext) - 2; 
     510             
     511            // Truncate QP-encoded text at $maxLength 
     512            // but not break any encoded letters. 
     513            if(preg_match("/^(.{0,$maxLength}[^\=][^\=])/", $value, $matches)) 
     514                $value = $matches[1]; 
     515         
     516            $quoted = $prefix . $value . $ext . $suffix; 
     517        } 
     518 
     519        return " {$name}=\"{$quoted}\"; "; 
     520    } 
     521 
    436522} // End of class 
  • program/localization/en_GB/labels.inc

    r3562eb3 rffae15e5  
    228228$labels['everynminutes'] = 'every $n minutes'; 
    229229$labels['never'] = 'never'; 
     230$labels['mimeparamfolding'] = 'Attachment names'; 
     231$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)'; 
     232$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)'; 
     233$labels['2047folding'] = 'Full RFC 2047 (other)'; 
     234$labels['advancedoptions'] = 'advanced options'; 
    230235$labels['messagesdisplaying'] = 'Displaying messages'; 
    231236$labels['messagescomposition'] = 'Composing messages'; 
  • program/localization/en_US/labels.inc

    r3562eb3 rffae15e5  
    285285$labels['messagesdisplaying'] = 'Displaying messages'; 
    286286$labels['messagescomposition'] = 'Composing messages'; 
     287$labels['mimeparamfolding'] = 'Attachment names'; 
     288$labels['2231folding'] = 'Full RFC 2231 (Thunderbird)'; 
     289$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)'; 
     290$labels['2047folding'] = 'Full RFC 2047 (other)'; 
     291$labels['advancedoptions'] = 'advanced options'; 
    287292 
    288293$labels['folder']  = 'Folder'; 
  • program/localization/pl_PL/labels.inc

    r29e697b rffae15e5  
    246246$labels['autosend'] = 'wyślij automatycznie'; 
    247247$labels['ignore'] = 'ignoruj'; 
     248$labels['mimeparamfolding'] = 'Nazwy załĠ
     249czników'; 
     250$labels['2231folding'] = 'zgodne z RFC 2231 (Thunderbird)'; 
     251$labels['miscfolding'] = 'zgodne z RFC 2047/2231 (MS Outlook)'; 
     252$labels['2047folding'] = 'zgodne z RFC 2047 (inne)'; 
     253$labels['advancedoptions'] = 'opcje zaawansowane'; 
    248254$labels['readwhendeleted'] = 'Podczas usuwania oznacz wiadomość jako przeczytanĠ
    249255'; 
  • program/steps/mail/sendmail.inc

    racb08f5 rffae15e5  
    305305        ($ctype == 'message/rfc822' ? $transfer_encoding : 'base64'), 
    306306        ($ctype == 'message/rfc822' ? 'inline' : 'attachment'), 
    307         $message_charset); 
     307        $message_charset, '', '',  
     308        $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL, 
     309        $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL 
     310        ); 
    308311    } 
    309312  } 
     
    317320     
    318321    $MAIL_MIME->addAttachment($filepath, $ctype, $files['name'][$i], true, 
    319         ($ctype == 'message/rfc822' ? $transfer_encoding : 'base64'), 
    320         'attachment', $message_charset); 
     322        $ctype == 'message/rfc822' ? $transfer_encoding : 'base64', 
     323        'attachment', $message_charset, '', '',  
     324        $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL, 
     325        $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL 
     326        ); 
    321327    } 
    322328 
  • program/steps/settings/func.inc

    re98809a rffae15e5  
    225225  } 
    226226 
     227  if (!isset($no_override['mime_param_folding'])) { 
     228    $field_id = 'rcmfd_param_folding'; 
     229    $select_param_folding = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id)); 
     230    $select_param_folding->add(rcube_label('2231folding'), 0); 
     231    $select_param_folding->add(rcube_label('miscfolding'), 1); 
     232    $select_param_folding->add(rcube_label('2047folding'), 2); 
     233 
     234    $table->set_row_attribs('advanced'); 
     235    $table->add('title', html::label($field_id, Q(rcube_label('mimeparamfolding')))); 
     236    $table->add(null, $select_param_folding->show($config['mime_param_folding'])); 
     237  } 
     238 
    227239  $out .= html::tag('fieldset', null, html::tag('legend', null, Q(rcube_label('messagescomposition'))) . $table->show($attrib)); 
    228240 
  • program/steps/settings/save_prefs.inc

    r55fb735 rffae15e5  
    3636  'logout_expunge' => isset($_POST['_logout_expunge']) ? TRUE : FALSE, 
    3737  'draft_autosave' => isset($_POST['_draft_autosave']) ? intval($_POST['_draft_autosave']) : 0, 
     38  'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0, 
    3839  'mdn_requests' => isset($_POST['_mdn_requests']) ? intval($_POST['_mdn_requests']) : 0, 
    3940  'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'], 
  • skins/default/settings.css

    r5d480c1 rffae15e5  
    6262  color: #666666; 
    6363  padding-right: 10px; 
     64} 
     65 
     66#userprefs-box table tr.advanced 
     67{ 
     68  display: none; 
    6469} 
    6570 
     
    254259  color: #999999; 
    255260} 
     261 
     262div.advswitch 
     263{ 
     264  white-space: nowrap; 
     265  text-align: right; 
     266  position: absolute; 
     267  bottom: 35px; 
     268  left: 20px; 
     269  width: 640px; 
     270} 
  • skins/default/templates/settings.html

    r5d480c1 rffae15e5  
    55<roundcube:include file="/includes/links.html" /> 
    66<link rel="stylesheet" type="text/css" href="/settings.css" /> 
     7<script type="text/javascript"> 
     8function show_adv(box) 
     9{ 
     10    var rows = document.getElementsByTagName('TR'); 
     11    for(var i=0; i<rows.length; i++) 
     12        if(rows[i].className && rows[i].className.match(/advanced/)) 
     13            rows[i].style.display = box.checked ? (bw.ie ? 'block' : 'table-row') : 'none'; 
     14} 
     15</script> 
    716</head> 
    817<body> 
     
    2029</div> 
    2130 
    22 <p id="listbuttons"><roundcube:button command="save" type="input" class="button mainaction" label="save" /></p> 
     31<p id="listbuttons"> 
     32<roundcube:button command="save" type="input" class="button mainaction" label="save" /> 
     33</p> 
     34 
     35<div class="advswitch"> 
     36<label for="advswitch"><roundcube:label name="advancedoptions"><label> 
     37<input type="checkbox" id="advswitch" name="_advanced" value="0" onclick="show_adv(this)" /> 
     38</div> 
    2339 
    2440<roundcube:include file="/includes/settingscripts.html" /> 
Note: See TracChangeset for help on using the changeset viewer.