diff options
Diffstat (limited to 'program/steps')
57 files changed, 6688 insertions, 5909 deletions
diff --git a/program/steps/addressbook/copy.inc b/program/steps/addressbook/copy.inc index d4387194a..9114cb1fd 100644 --- a/program/steps/addressbook/copy.inc +++ b/program/steps/addressbook/copy.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/copy.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2007, The Roundcube Dev Team | + | Copyright (C) 2007-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -25,15 +25,14 @@ if (!$OUTPUT->ajax_call) $cids = rcmail_get_cids(); -$target = get_input_value('_to', RCUBE_INPUT_POST); -$target_group = get_input_value('_togid', RCUBE_INPUT_POST); +$target = rcube_utils::get_input_value('_to', rcube_utils::INPUT_POST); +$target_group = rcube_utils::get_input_value('_togid', rcube_utils::INPUT_POST); $success = 0; $errormsg = 'copyerror'; $maxnum = $RCMAIL->config->get('max_group_members', 0); -foreach ($cids as $source => $cid) -{ +foreach ($cids as $source => $cid) { // Something wrong, target not specified if (!strlen($target)) { break; diff --git a/program/steps/addressbook/delete.inc b/program/steps/addressbook/delete.inc index 3bb2ef500..3d57d7074 100644 --- a/program/steps/addressbook/delete.inc +++ b/program/steps/addressbook/delete.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/delete.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -30,8 +30,7 @@ $delcnt = 0; $undo_time = $RCMAIL->config->get('undo_timeout', 0); $RCMAIL->session->remove('contact_undo'); -foreach ($cids as $source => $cid) -{ +foreach ($cids as $source => $cid) { $CONTACTS = rcmail_contact_source($source); if ($CONTACTS->readonly) { @@ -51,8 +50,21 @@ foreach ($cids as $source => $cid) $deleted = !$plugin['abort'] ? $CONTACTS->delete($cid, $undo_time < 1) : $plugin['result']; if (!$deleted) { - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'contactdelerror', 'error'); - $OUTPUT->command('list_contacts'); + if ($plugin['message']) { + $error = $plugin['message']; + } + else if (($error = $CONTACTS->get_error()) && $error['message']) { + $error = $error['message']; + } + else { + $error = 'contactdelerror'; + } + + $source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); + $group = rcube_utils::get_input_value('_gid', rcube_utils::INPUT_GPC); + + $OUTPUT->show_message($error, 'error'); + $OUTPUT->command('list_contacts', $source, $group); $OUTPUT->send(); } else { @@ -113,8 +125,8 @@ $OUTPUT->command('set_rowcount', rcmail_get_rowcount_text($result)); if (!empty($_SESSION['contact_undo'])) { $_SESSION['contact_undo']['ts'] = time(); - $msg = html::span(null, rcube_label('contactdeleted')) - . ' ' . html::a(array('onclick' => JS_OBJECT_NAME.".command('undo', '', this)"), rcube_label('undo')); + $msg = html::span(null, $RCMAIL->gettext('contactdeleted')) + . ' ' . html::a(array('onclick' => rcmail_output::JS_OBJECT_NAME.".command('undo', '', this)"), $RCMAIL->gettext('undo')); $OUTPUT->show_message($msg, 'confirmation', null, true, $undo_time); } diff --git a/program/steps/addressbook/edit.inc b/program/steps/addressbook/edit.inc index 7ddd3e516..3bbbfccdf 100644 --- a/program/steps/addressbook/edit.inc +++ b/program/steps/addressbook/edit.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/edit.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2007, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -36,12 +36,12 @@ if ($RCMAIL->action == 'edit') { // editing not allowed here if ($CONTACTS->readonly || $record['readonly']) { $OUTPUT->show_message('sourceisreadonly'); - rcmail_overwrite_action('show'); + $RCMAIL->overwrite_action('show'); return; } } else { - $source = get_input_value('_source', RCUBE_INPUT_GPC); + $source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); if (strlen($source)) { $CONTACTS = $RCMAIL->get_address_book($source, true); @@ -59,6 +59,25 @@ else { $SOURCE_ID = $source; rcmail_set_sourcename($CONTACTS); + +$OUTPUT->add_handlers(array( + 'contactedithead' => 'rcmail_contact_edithead', + 'contacteditform' => 'rcmail_contact_editform', + 'contactphoto' => 'rcmail_contact_photo', + 'photouploadform' => 'rcmail_upload_photo_form', + 'sourceselector' => 'rcmail_source_selector', + 'filedroparea' => 'rcmail_photo_drop_area', +)); + +if ($RCMAIL->action == 'add' && $OUTPUT->template_exists('contactadd')) { + $OUTPUT->send('contactadd'); +} + +// this will be executed if no template for addcontact exists +$OUTPUT->send('contactedit'); + + + function rcmail_get_edit_record() { global $RCMAIL, $CONTACTS; @@ -70,7 +89,7 @@ function rcmail_get_edit_record() else if ($RCMAIL->action != 'add' && !(($result = $CONTACTS->get_result()) && ($record = $result->first())) ) { - $RCMAIL->output->show_message('contactnotfound'); + $RCMAIL->output->show_message('contactnotfound', 'error'); return false; } @@ -125,7 +144,7 @@ function rcmail_contact_editform($attrib) $form = array( 'contact' => array( - 'name' => rcube_label('properties'), + 'name' => $RCMAIL->gettext('properties'), 'content' => array( 'email' => array('size' => $i_size, 'visible' => true), 'phone' => array('size' => $i_size, 'visible' => true), @@ -135,7 +154,7 @@ function rcmail_contact_editform($attrib) ), ), 'personal' => array( - 'name' => rcube_label('personalinfo'), + 'name' => $RCMAIL->gettext('personalinfo'), 'content' => array( 'gender' => array('visible' => true), 'maidenname' => array('size' => $i_size), @@ -150,7 +169,7 @@ function rcmail_contact_editform($attrib) if (isset($CONTACT_COLTYPES['notes'])) { $form['notes'] = array( - 'name' => rcube_label('notes'), + 'name' => $RCMAIL->gettext('notes'), 'content' => array( 'notes' => array('size' => $t_cols, 'rows' => $t_rows, 'label' => false, 'visible' => true, 'limit' => 1), ), @@ -169,37 +188,56 @@ function rcmail_contact_editform($attrib) function rcmail_upload_photo_form($attrib) { - global $OUTPUT; - - // set defaults - $attrib += array('id' => 'rcmUploadform', 'buttons' => 'yes'); - - // find max filesize value - $max_filesize = parse_bytes(ini_get('upload_max_filesize')); - $max_postsize = parse_bytes(ini_get('post_max_size')); - if ($max_postsize && $max_postsize < $max_filesize) - $max_filesize = $max_postsize; - $max_filesize = show_bytes($max_filesize); - - $hidden = new html_hiddenfield(array('name' => '_cid', 'value' => $GLOBALS['cid'])); - $input = new html_inputfield(array('type' => 'file', 'name' => '_photo', 'size' => $attrib['size'])); - $button = new html_inputfield(array('type' => 'button')); - - $out = html::div($attrib, - $OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'name' => 'uploadform', 'method' => 'post', 'enctype' => 'multipart/form-data'), - $hidden->show() . - html::div(null, $input->show()) . - html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) . - (get_boolean($attrib['buttons']) ? html::div('buttons', - $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' . - $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('upload-photo', this.form)")) - ) : '') - ) - ); - - $OUTPUT->add_label('addphoto','replacephoto'); - $OUTPUT->add_gui_object('uploadform', $attrib['id'].'Frm'); - return $out; + global $RCMAIL, $OUTPUT; + + // set defaults + $attrib += array('id' => 'rcmUploadform', 'buttons' => 'yes'); + + // find max filesize value + $max_filesize = parse_bytes(ini_get('upload_max_filesize')); + $max_postsize = parse_bytes(ini_get('post_max_size')); + + if ($max_postsize && $max_postsize < $max_filesize) { + $max_filesize = $max_postsize; + } + $max_filesize = $RCMAIL->show_bytes($max_filesize); + + $hidden = new html_hiddenfield(array('name' => '_cid', 'value' => $GLOBALS['cid'])); + $input = new html_inputfield(array('type' => 'file', 'name' => '_photo', 'size' => $attrib['size'])); + $button = new html_inputfield(array('type' => 'button')); + + $content = $hidden->show() . html::div(null, $input->show()) + . html::div('hint', $RCMAIL->gettext(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))); + + if (rcube_utils::get_boolean($attrib['buttons'])) { + $content .= html::div('buttons', + $button->show($RCMAIL->gettext('close'), array( + 'class' => 'button', + 'onclick' => "$('#$attrib[id]').hide()" + )) + . ' ' . + $button->show($RCMAIL->gettext('upload'), array( + 'class' => 'button mainaction', + 'onclick' => rcmail_output::JS_OBJECT_NAME . ".command('upload-photo', this.form)" + )) + ); + } + + $out = html::div($attrib, + $OUTPUT->form_tag(array( + 'id' => $attrib['id'] . 'Frm', + 'name' => 'uploadform', + 'method' => 'post', + 'enctype' => 'multipart/form-data' + ), + $content + ) + ); + + $OUTPUT->add_label('addphoto','replacephoto'); + $OUTPUT->add_gui_object('uploadform', $attrib['id'].'Frm'); + + return $out; } // similar function as in /steps/settings/edit_identity.inc @@ -247,7 +285,7 @@ function rcmail_source_selector($attrib) $attrib['name'] = '_source'; $attrib['is_escaped'] = true; - $attrib['onchange'] = JS_OBJECT_NAME . ".command('save', 'reload', this.form)"; + $attrib['onchange'] = rcmail_output::JS_OBJECT_NAME . ".command('save', 'reload', this.form)"; $select = new html_select($attrib); @@ -270,19 +308,3 @@ function rcmail_photo_drop_area($attrib) $OUTPUT->set_env('filedrop', array('action' => 'upload-photo', 'fieldname' => '_photo', 'single' => 1, 'filter' => '^image/.+')); } } - - -$OUTPUT->add_handlers(array( - 'contactedithead' => 'rcmail_contact_edithead', - 'contacteditform' => 'rcmail_contact_editform', - 'contactphoto' => 'rcmail_contact_photo', - 'photouploadform' => 'rcmail_upload_photo_form', - 'sourceselector' => 'rcmail_source_selector', - 'filedroparea' => 'rcmail_photo_drop_area', -)); - -if ($RCMAIL->action == 'add' && $OUTPUT->template_exists('contactadd')) - $OUTPUT->send('contactadd'); - -// this will be executed if no template for addcontact exists -$OUTPUT->send('contactedit'); diff --git a/program/steps/addressbook/export.inc b/program/steps/addressbook/export.inc index 1e988feab..2b45e5cd1 100644 --- a/program/steps/addressbook/export.inc +++ b/program/steps/addressbook/export.inc @@ -6,7 +6,7 @@ | | | This file is part of the Roundcube Webmail client | | Copyright (C) 2008-2013, The Roundcube Dev Team | - | Copyright (C) 2011, Kolab Systems AG | + | Copyright (C) 2011-2013, Kolab Systems AG | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -21,49 +21,8 @@ +-----------------------------------------------------------------------+ */ - -/** - * Copy contact record properties into a vcard object - */ -function prepare_for_export(&$record, $source = null) -{ - $groups = $source && $source->groups && $source->export_groups ? $source->get_record_groups($record['ID']) : null; - - if (empty($record['vcard'])) { - $vcard = new rcube_vcard(); - if ($source) { - $vcard->extend_fieldmap($source->vcard_map); - } - $vcard->load($record['vcard']); - $vcard->reset(); - - foreach ($record as $key => $values) { - list($field, $section) = explode(':', $key); - foreach ((array)$values as $value) { - if (is_array($value) || @strlen($value)) { - $vcard->set($field, $value, strtoupper($section)); - } - } - } - - // append group names - if ($groups) { - $vcard->set('groups', join(',', $groups), null); - } - - $record['vcard'] = $vcard->export(true); - } - // patch categories to alread existing vcard block - else if ($record['vcard'] && !empty($groups) && !strpos($record['vcard'], 'CATEGORIES:')) { - $vgroups = 'CATEGORIES:' . rcube_vcard::vcard_quote(join(',', $groups)); - $record['vcard'] = str_replace('END:VCARD', $vgroups . rcube_vcard::$eol . 'END:VCARD', $record['vcard']); - } -} - - // Use search result -if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) -{ +if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) { $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name'); $search = (array)$_SESSION['search'][$_REQUEST['_search']]; $records = array(); @@ -140,7 +99,7 @@ else { } // send downlaod headers -header('Content-Type: text/x-vcard; charset='.RCMAIL_CHARSET); +header('Content-Type: text/x-vcard; charset='.RCUBE_CHARSET); header('Content-Disposition: attachment; filename="contacts.vcf"'); while ($result && ($row = $result->next())) { @@ -153,3 +112,42 @@ while ($result && ($row = $result->next())) { } exit; + + +/** + * Copy contact record properties into a vcard object + */ +function prepare_for_export(&$record, $source = null) +{ + $groups = $source && $source->groups && $source->export_groups ? $source->get_record_groups($record['ID']) : null; + + if (empty($record['vcard'])) { + $vcard = new rcube_vcard(); + if ($source) { + $vcard->extend_fieldmap($source->vcard_map); + } + $vcard->load($record['vcard']); + $vcard->reset(); + + foreach ($record as $key => $values) { + list($field, $section) = explode(':', $key); + foreach ((array)$values as $value) { + if (is_array($value) || @strlen($value)) { + $vcard->set($field, $value, strtoupper($section)); + } + } + } + + // append group names + if ($groups) { + $vcard->set('groups', join(',', $groups), null); + } + + $record['vcard'] = $vcard->export(true); + } + // patch categories to alread existing vcard block + else if ($record['vcard'] && !empty($groups) && !strpos($record['vcard'], 'CATEGORIES:')) { + $vgroups = 'CATEGORIES:' . rcube_vcard::vcard_quote(join(',', $groups)); + $record['vcard'] = str_replace('END:VCARD', $vgroups . rcube_vcard::$eol . 'END:VCARD', $record['vcard']); + } +} diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc index f94d15338..b33396baf 100644 --- a/program/steps/addressbook/func.inc +++ b/program/steps/addressbook/func.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/func.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2012, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -23,37 +23,37 @@ $SEARCH_MODS_DEFAULT = array('name'=>1, 'firstname'=>1, 'surname'=>1, 'email'=>1 // general definition of contact coltypes $CONTACT_COLTYPES = array( - 'name' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('name'), 'category' => 'main'), - 'firstname' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('firstname'), 'category' => 'main'), - 'surname' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('surname'), 'category' => 'main'), - 'email' => array('type' => 'text', 'size' => 40, 'maxlength' => 254, 'label' => rcube_label('email'), 'subtypes' => array('home','work','other'), 'category' => 'main'), - 'middlename' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('middlename'), 'category' => 'main'), - 'prefix' => array('type' => 'text', 'size' => 8, 'maxlength' => 20, 'limit' => 1, 'label' => rcube_label('nameprefix'), 'category' => 'main'), - 'suffix' => array('type' => 'text', 'size' => 8, 'maxlength' => 20, 'limit' => 1, 'label' => rcube_label('namesuffix'), 'category' => 'main'), - 'nickname' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('nickname'), 'category' => 'main'), - 'jobtitle' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('jobtitle'), 'category' => 'main'), - 'organization' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('organization'), 'category' => 'main'), - 'department' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('department'), 'category' => 'main'), - 'gender' => array('type' => 'select', 'limit' => 1, 'label' => rcube_label('gender'), 'options' => array('male' => rcube_label('male'), 'female' => rcube_label('female')), 'category' => 'personal'), - 'maidenname' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('maidenname'), 'category' => 'personal'), - 'phone' => array('type' => 'text', 'size' => 40, 'maxlength' => 20, 'label' => rcube_label('phone'), 'subtypes' => array('home','home2','work','work2','mobile','main','homefax','workfax','car','pager','video','assistant','other'), 'category' => 'main'), - 'address' => array('type' => 'composite', 'label' => rcube_label('address'), 'subtypes' => array('home','work','other'), 'childs' => array( - 'street' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('street'), 'category' => 'main'), - 'locality' => array('type' => 'text', 'size' => 28, 'maxlength' => 50, 'label' => rcube_label('locality'), 'category' => 'main'), - 'zipcode' => array('type' => 'text', 'size' => 8, 'maxlength' => 15, 'label' => rcube_label('zipcode'), 'category' => 'main'), - 'region' => array('type' => 'text', 'size' => 12, 'maxlength' => 50, 'label' => rcube_label('region'), 'category' => 'main'), - 'country' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('country'), 'category' => 'main'), - ), 'category' => 'main'), - 'birthday' => array('type' => 'date', 'size' => 12, 'maxlength' => 16, 'label' => rcube_label('birthday'), 'limit' => 1, 'render_func' => 'rcmail_format_date_col', 'category' => 'personal'), - 'anniversary' => array('type' => 'date', 'size' => 12, 'maxlength' => 16, 'label' => rcube_label('anniversary'), 'limit' => 1, 'render_func' => 'rcmail_format_date_col', 'category' => 'personal'), - 'website' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('website'), 'subtypes' => array('homepage','work','blog','profile','other'), 'category' => 'main'), - 'im' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => rcube_label('instantmessenger'), 'subtypes' => array('aim','icq','msn','yahoo','jabber','skype','other'), 'category' => 'main'), - 'notes' => array('type' => 'textarea', 'size' => 40, 'rows' => 15, 'maxlength' => 500, 'label' => rcube_label('notes'), 'limit' => 1), - 'photo' => array('type' => 'image', 'limit' => 1, 'category' => 'main'), - 'assistant' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('assistant'), 'category' => 'personal'), - 'manager' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('manager'), 'category' => 'personal'), - 'spouse' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => rcube_label('spouse'), 'category' => 'personal'), - // TODO: define fields for vcards like GEO, KEY + 'name' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('name'), 'category' => 'main'), + 'firstname' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('firstname'), 'category' => 'main'), + 'surname' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('surname'), 'category' => 'main'), + 'email' => array('type' => 'text', 'size' => 40, 'maxlength' => 254, 'label' => $RCMAIL->gettext('email'), 'subtypes' => array('home','work','other'), 'category' => 'main'), + 'middlename' => array('type' => 'text', 'size' => 19, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('middlename'), 'category' => 'main'), + 'prefix' => array('type' => 'text', 'size' => 8, 'maxlength' => 20, 'limit' => 1, 'label' => $RCMAIL->gettext('nameprefix'), 'category' => 'main'), + 'suffix' => array('type' => 'text', 'size' => 8, 'maxlength' => 20, 'limit' => 1, 'label' => $RCMAIL->gettext('namesuffix'), 'category' => 'main'), + 'nickname' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('nickname'), 'category' => 'main'), + 'jobtitle' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('jobtitle'), 'category' => 'main'), + 'organization' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('organization'), 'category' => 'main'), + 'department' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('department'), 'category' => 'main'), + 'gender' => array('type' => 'select', 'limit' => 1, 'label' => $RCMAIL->gettext('gender'), 'options' => array('male' => $RCMAIL->gettext('male'), 'female' => $RCMAIL->gettext('female')), 'category' => 'personal'), + 'maidenname' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('maidenname'), 'category' => 'personal'), + 'phone' => array('type' => 'text', 'size' => 40, 'maxlength' => 20, 'label' => $RCMAIL->gettext('phone'), 'subtypes' => array('home','home2','work','work2','mobile','main','homefax','workfax','car','pager','video','assistant','other'), 'category' => 'main'), + 'address' => array('type' => 'composite', 'label' => $RCMAIL->gettext('address'), 'subtypes' => array('home','work','other'), 'childs' => array( + 'street' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => $RCMAIL->gettext('street'), 'category' => 'main'), + 'locality' => array('type' => 'text', 'size' => 28, 'maxlength' => 50, 'label' => $RCMAIL->gettext('locality'), 'category' => 'main'), + 'zipcode' => array('type' => 'text', 'size' => 8, 'maxlength' => 15, 'label' => $RCMAIL->gettext('zipcode'), 'category' => 'main'), + 'region' => array('type' => 'text', 'size' => 12, 'maxlength' => 50, 'label' => $RCMAIL->gettext('region'), 'category' => 'main'), + 'country' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => $RCMAIL->gettext('country'), 'category' => 'main'), + ), 'category' => 'main'), + 'birthday' => array('type' => 'date', 'size' => 12, 'maxlength' => 16, 'label' => $RCMAIL->gettext('birthday'), 'limit' => 1, 'render_func' => 'rcmail_format_date_col', 'category' => 'personal'), + 'anniversary' => array('type' => 'date', 'size' => 12, 'maxlength' => 16, 'label' => $RCMAIL->gettext('anniversary'), 'limit' => 1, 'render_func' => 'rcmail_format_date_col', 'category' => 'personal'), + 'website' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => $RCMAIL->gettext('website'), 'subtypes' => array('homepage','work','blog','profile','other'), 'category' => 'main'), + 'im' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'label' => $RCMAIL->gettext('instantmessenger'), 'subtypes' => array('aim','icq','msn','yahoo','jabber','skype','other'), 'category' => 'main'), + 'notes' => array('type' => 'textarea', 'size' => 40, 'rows' => 15, 'maxlength' => 500, 'label' => $RCMAIL->gettext('notes'), 'limit' => 1), + 'photo' => array('type' => 'image', 'limit' => 1, 'category' => 'main'), + 'assistant' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('assistant'), 'category' => 'personal'), + 'manager' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('manager'), 'category' => 'personal'), + 'spouse' => array('type' => 'text', 'size' => 40, 'maxlength' => 50, 'limit' => 1, 'label' => $RCMAIL->gettext('spouse'), 'category' => 'personal'), + // TODO: define fields for vcards like GEO, KEY ); $PAGE_SIZE = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50)); @@ -83,12 +83,12 @@ if (!$RCMAIL->action && !$OUTPUT->ajax_call) { $OUTPUT->set_env('writable_source', $writeable); $OUTPUT->set_env('compose_extwin', $RCMAIL->config->get('compose_extwin',false)); - $OUTPUT->set_pagetitle(rcube_label('addressbook')); + $OUTPUT->set_pagetitle($RCMAIL->gettext('addressbook')); $_SESSION['addressbooks_count'] = $count; $_SESSION['addressbooks_count_writeable'] = $writeable; // select address book - $source = get_input_value('_source', RCUBE_INPUT_GPC); + $source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); // use first directory by default if (!strlen($source) || !isset($js_list[$source])) { @@ -109,13 +109,38 @@ if ($undo = $_SESSION['contact_undo']) { $RCMAIL->session->remove('contact_undo'); } +// register UI objects +$OUTPUT->add_handlers(array( + 'directorylist' => 'rcmail_directory_list', +// 'groupslist' => 'rcmail_contact_groups', + 'addresslist' => 'rcmail_contacts_list', + 'addresslisttitle' => 'rcmail_contacts_list_title', + 'addressframe' => 'rcmail_contact_frame', + 'recordscountdisplay' => 'rcmail_rowcount_display', + 'searchform' => array($OUTPUT, 'search_form') +)); + +// register action aliases +$RCMAIL->register_action_map(array( + 'add' => 'edit.inc', + 'group-create' => 'groups.inc', + 'group-rename' => 'groups.inc', + 'group-delete' => 'groups.inc', + 'group-addmembers' => 'groups.inc', + 'group-delmembers' => 'groups.inc', + 'search-create' => 'search.inc', + 'search-delete' => 'search.inc', +)); + + + // instantiate a contacts object according to the given source function rcmail_contact_source($source=null, $init_env=false, $writable=false) { global $RCMAIL, $OUTPUT, $CONTACT_COLTYPES, $PAGE_SIZE; if (!strlen($source)) { - $source = get_input_value('_source', RCUBE_INPUT_GPC); + $source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); } // Get object @@ -129,7 +154,7 @@ function rcmail_contact_source($source=null, $init_env=false, $writable=false) $CONTACTS->set_page(isset($_SESSION['page']) ? $_SESSION['page'] : 1); if (!empty($_REQUEST['_gid'])) - $CONTACTS->set_group(get_input_value('_gid', RCUBE_INPUT_GPC)); + $CONTACTS->set_group(rcube_utils::get_input_value('_gid', rcube_utils::INPUT_GPC)); if (!$init_env) return $CONTACTS; @@ -162,13 +187,13 @@ function rcmail_contact_source($source=null, $init_env=false, $writable=false) function rcmail_set_sourcename($abook) { - global $OUTPUT; + global $OUTPUT, $RCMAIL; // get address book name (for display) if ($abook && $_SESSION['addressbooks_count'] > 1) { $name = $abook->get_name(); if (!$name) { - $name = rcube_label('personaladrbook'); + $name = $RCMAIL->gettext('personaladrbook'); } $OUTPUT->set_env('sourcename', html_entity_decode($name, ENT_COMPAT, 'UTF-8')); } @@ -189,17 +214,17 @@ function rcmail_directory_list($attrib) 'id' => 'rcmli%s', 'class' => '%s', 'noclose' => true), html::a(array('href' => '%s', 'rel' => '%s', - 'onclick' => "return ".JS_OBJECT_NAME.".command('list','%s',this)"), '%s')); + 'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".command('list','%s',this)"), '%s')); $sources = (array) $OUTPUT->get_env('address_sources'); reset($sources); // currently selected source - $current = get_input_value('_source', RCUBE_INPUT_GPC); + $current = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); foreach ($sources as $j => $source) { $id = strval(strlen($source['id']) ? $source['id'] : $j); - $js_id = JQ($id); + $js_id = rcube::JQ($id); // set class name(s) $class_name = 'addressbook'; @@ -214,7 +239,7 @@ function rcmail_directory_list($attrib) $out .= sprintf($line_templ, rcube_utils::html_identifier($id, true), $class_name, - Q(rcmail_url(null, array('_source' => $id))), + rcube::Q($RCMAIL->url(array('_source' => $id))), $source['id'], $js_id, $name); @@ -229,13 +254,13 @@ function rcmail_directory_list($attrib) $line_templ = html::tag('li', array( 'id' => 'rcmli%s', 'class' => '%s'), html::a(array('href' => '#', 'rel' => 'S%s', - 'onclick' => "return ".JS_OBJECT_NAME.".command('listsearch', '%s', this)"), '%s')); + 'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".command('listsearch', '%s', this)"), '%s')); // Saved searches $sources = $RCMAIL->user->list_searches(rcube_user::SEARCH_ADDRESSBOOK); foreach ($sources as $j => $source) { $id = $source['id']; - $js_id = JQ($id); + $js_id = rcube::JQ($id); // set class name(s) $class_name = 'contactsearch'; @@ -248,7 +273,7 @@ function rcmail_directory_list($attrib) rcube_utils::html_identifier('S'.$id, true), $class_name, $id, - $js_id, (!empty($source['name']) ? Q($source['name']) : Q($id))); + $js_id, (!empty($source['name']) ? rcube::Q($source['name']) : rcube::Q($id))); } $OUTPUT->set_env('contactgroups', $jsdata); @@ -275,7 +300,7 @@ function rcmail_contact_groups($args) 'id' => 'rcmli%s', 'class' => 'contactgroup'), html::a(array('href' => '#', 'rel' => '%s:%s', - 'onclick' => "return ".JS_OBJECT_NAME.".command('listgroup',{'source':'%s','id':'%s'},this)"), '%s')); + 'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".command('listgroup',{'source':'%s','id':'%s'},this)"), '%s')); // append collapse/expand toggle and open a new <ul> $is_collapsed = strpos($RCMAIL->config->get('collapsed_abooks',''), '&'.rawurlencode($args['source']).'&') !== false; @@ -285,7 +310,7 @@ function rcmail_contact_groups($args) $groups_html .= sprintf($line_templ, rcube_utils::html_identifier('G' . $args['source'] . $group['ID'], true), $args['source'], $group['ID'], - $args['source'], $group['ID'], Q($group['name']) + $args['source'], $group['ID'], rcube::Q($group['name']) ); $args['jsdata']['G'.$args['source'].$group['ID']] = array( 'source' => $args['source'], 'id' => $group['ID'], @@ -304,7 +329,7 @@ function rcmail_contact_groups($args) // return the contacts list as HTML table function rcmail_contacts_list($attrib) { - global $CONTACTS, $OUTPUT; + global $RCMAIL, $CONTACTS, $OUTPUT; // define list of cols to be displayed $a_show_cols = array('name','action'); @@ -314,7 +339,7 @@ function rcmail_contacts_list($attrib) $attrib['id'] = 'rcmAddressList'; // create XHTML table - $out = rcube_table_output($attrib, array(), $a_show_cols, $CONTACTS->primary_key); + $out = $RCMAIL->table_output($attrib, array(), $a_show_cols, $CONTACTS->primary_key); // set client env $OUTPUT->add_gui_object('contactslist', $attrib['id']); @@ -330,7 +355,7 @@ function rcmail_contacts_list($attrib) function rcmail_js_contacts_list($result, $prefix='') { - global $OUTPUT; + global $OUTPUT, $RCMAIL; if (empty($result) || $result->count == 0) return; @@ -357,7 +382,7 @@ function rcmail_js_contacts_list($result, $prefix='') $val = ''; switch ($col) { case 'name': - $val = Q(rcube_addressbook::compose_list_name($row)); + $val = rcube::Q(rcube_addressbook::compose_list_name($row)); break; case 'action': @@ -365,8 +390,8 @@ function rcmail_js_contacts_list($result, $prefix='') $val = html::a(array( 'href' => '#list', 'rel' => $row['ID'], - 'title' => rcube_label('listgroup'), - 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", JS_OBJECT_NAME, $source_id, $row['CID']), + 'title' => $RCMAIL->gettext('listgroup'), + 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", rcmail_output::JS_OBJECT_NAME, $source_id, $row['CID']), ), '»'); } else @@ -374,7 +399,7 @@ function rcmail_js_contacts_list($result, $prefix='') break; default: - $val = Q($row[$col]); + $val = rcube::Q($row[$col]); break; } @@ -391,7 +416,7 @@ function rcmail_js_contacts_list($result, $prefix='') function rcmail_contacts_list_title($attrib) { - global $OUTPUT; + global $OUTPUT, $RCMAIL; $attrib += array('label' => 'contacts', 'id' => 'rcmabooklisttitle', 'tag' => 'span'); unset($attrib['name']); @@ -399,7 +424,7 @@ function rcmail_contacts_list_title($attrib) $OUTPUT->add_gui_object('addresslist_title', $attrib['id']); $OUTPUT->add_label('contacts'); - return html::tag($attrib['tag'], $attrib, rcube_label($attrib['label']), html::$common_attrib); + return html::tag($attrib['tag'], $attrib, $RCMAIL->gettext($attrib['label']), html::$common_attrib); } @@ -417,23 +442,23 @@ function rcmail_contact_frame($attrib) function rcmail_rowcount_display($attrib) { - global $OUTPUT; + global $RCMAIL; if (!$attrib['id']) $attrib['id'] = 'rcmcountdisplay'; - $OUTPUT->add_gui_object('countdisplay', $attrib['id']); + $RCMAIL->output->add_gui_object('countdisplay', $attrib['id']); if ($attrib['label']) $_SESSION['contactcountdisplay'] = $attrib['label']; - return html::span($attrib, rcube_label('loading')); + return html::span($attrib, $RCMAIL->gettext('loading')); } function rcmail_get_rowcount_text($result=null) { - global $CONTACTS, $PAGE_SIZE; + global $RCMAIL, $CONTACTS, $PAGE_SIZE; // read nr of contacts if (!$result) { @@ -441,9 +466,9 @@ function rcmail_get_rowcount_text($result=null) } if ($result->count == 0) - $out = rcube_label('nocontactsfound'); + $out = $RCMAIL->gettext('nocontactsfound'); else - $out = rcube_label(array( + $out = $RCMAIL->gettext(array( 'name' => $_SESSION['contactcountdisplay'] ? $_SESSION['contactcountdisplay'] : 'contactsfromto', 'vars' => array( 'from' => $result->first + 1, @@ -457,13 +482,15 @@ function rcmail_get_rowcount_text($result=null) function rcmail_get_type_label($type) { + global $RCMAIL; + $label = 'type'.$type; - if (rcube_label_exists($label, '*', $domain)) - return rcube_label($label, $domain); + if ($RCMAIL->text_exists($label, '*', $domain)) + return $RCMAIL->gettext($label, $domain); else if (preg_match('/\w+(\d+)$/', $label, $m) && ($label = preg_replace('/(\d+)$/', '', $label)) - && rcube_label_exists($label, '*', $domain)) - return rcube_label($label, $domain) . ' ' . $m[1]; + && $RCMAIL->text_exists($label, '*', $domain)) + return $RCMAIL->gettext($label, $domain) . ' ' . $m[1]; return ucfirst($type); } @@ -480,7 +507,7 @@ function rcmail_contact_form($form, $record, $attrib = null) $form = $plugin['form']; $record = $plugin['record']; $edit_mode = $RCMAIL->action != 'show'; - $del_button = $attrib['deleteicon'] ? html::img(array('src' => $RCMAIL->output->get_skin_file($attrib['deleteicon']), 'alt' => rcube_label('delete'))) : rcube_label('delete'); + $del_button = $attrib['deleteicon'] ? html::img(array('src' => $RCMAIL->output->get_skin_file($attrib['deleteicon']), 'alt' => $RCMAIL->gettext('delete'))) : $RCMAIL->gettext('delete'); unset($attrib['deleteicon']); $out = ''; @@ -507,7 +534,7 @@ function rcmail_contact_form($form, $record, $attrib = null) continue; $select_add = new html_select(array('class' => 'addfieldmenu', 'rel' => $section)); - $select_add->add(rcube_label('addfield'), ''); + $select_add->add($RCMAIL->gettext('addfield'), ''); // render head section with name fields (not a regular list of rows) if ($section == 'head') { @@ -539,7 +566,7 @@ function rcmail_contact_form($form, $record, $attrib = null) if ($RCMAIL->action == 'show') { if (!empty($record[$col])) - $fields .= html::span('namefield ' . $col, Q($record[$col])) . " "; + $fields .= html::span('namefield ' . $col, rcube::Q($record[$col])) . " "; } else { $colprop = (array)$fieldset['content'][$col] + (array)$coltypes[$col]; @@ -548,7 +575,7 @@ function rcmail_contact_form($form, $record, $attrib = null) $colprop['style'] = 'display:none'; $select_add->add($colprop['label'], $col); } - $fields .= rcmail_get_edit_field($col, $record[$col], $colprop, $colprop['type']); + $fields .= rcube_output::get_edit_field($col, $record[$col], $colprop, $colprop['type']); } } $content .= html::div($blockname, $fields); @@ -557,7 +584,7 @@ function rcmail_contact_form($form, $record, $attrib = null) if ($edit_mode) $content .= html::p('addfield', $select_add->show(null)); - $out .= html::tag('fieldset', $attrib, (!empty($fieldset['name']) ? html::tag('legend', null, Q($fieldset['name'])) : '') . $content) ."\n"; + $out .= html::tag('fieldset', $attrib, (!empty($fieldset['name']) ? html::tag('legend', null, rcube::Q($fieldset['name'])) : '') . $content) ."\n"; continue; } @@ -575,7 +602,7 @@ function rcmail_contact_form($form, $record, $attrib = null) // merge colprop with global coltype configuration $colprop += $coltypes[$field]; - $label = isset($colprop['label']) ? $colprop['label'] : rcube_label($col); + $label = isset($colprop['label']) ? $colprop['label'] : $RCMAIL->gettext($col); // prepare subtype selector in edit mode if ($edit_mode && is_array($colprop['subtypes'])) { @@ -636,10 +663,10 @@ function rcmail_contact_form($form, $record, $attrib = null) if ($edit_mode) { if ($colprop['subtypes'] || $colprop['limit'] != 1) $cp['array'] = true; - $composite['{'.$childcol.'}'] = rcmail_get_edit_field($childcol, $childvalue, $cp, $cp['type']) . " "; + $composite['{'.$childcol.'}'] = rcube_output::get_edit_field($childcol, $childvalue, $cp, $cp['type']) . " "; } else { - $childval = $cp['render_func'] ? call_user_func($cp['render_func'], $childvalue, $childcol) : Q($childvalue); + $childval = $cp['render_func'] ? call_user_func($cp['render_func'], $childvalue, $childcol) : rcube::Q($childvalue); $composite['{'.$childcol.'}'] = html::span('data ' . $childcol, $childval) . " "; } $j++; @@ -666,7 +693,7 @@ function rcmail_contact_form($form, $record, $attrib = null) $val = rcmail_format_date_col($val); } - $val = rcmail_get_edit_field($col, $val, $colprop, $colprop['type']); + $val = rcube_output::get_edit_field($col, $val, $colprop, $colprop['type']); $coltypes[$field]['count']++; } else if ($colprop['render_func']) @@ -674,7 +701,7 @@ function rcmail_contact_form($form, $record, $attrib = null) else if (is_array($colprop['options']) && isset($colprop['options'][$val])) $val = $colprop['options'][$val]; else - $val = Q($val); + $val = rcube::Q($val); // use subtype as label if ($colprop['subtypes']) @@ -682,12 +709,12 @@ function rcmail_contact_form($form, $record, $attrib = null) // add delete button/link if ($edit_mode && !($colprop['visible'] && $colprop['limit'] == 1)) - $val .= html::a(array('href' => '#del', 'class' => 'contactfieldbutton deletebutton', 'title' => rcube_label('delete'), 'rel' => $col), $del_button); + $val .= html::a(array('href' => '#del', 'class' => 'contactfieldbutton deletebutton', 'title' => $RCMAIL->gettext('delete'), 'rel' => $col), $del_button); // display row with label if ($label) { $rows .= html::div('row', - html::div('contactfieldlabel label', $select_subtype ? $select_subtype->show($subtype) : Q($label)) . + html::div('contactfieldlabel label', $select_subtype ? $select_subtype->show($subtype) : rcube::Q($label)) . html::div('contactfieldcontent '.$colprop['type'], $val)); } else // row without label @@ -703,7 +730,7 @@ function rcmail_contact_form($form, $record, $attrib = null) // wrap rows in fieldgroup container if ($rows) { $content .= html::tag('fieldset', array('class' => 'contactfieldgroup ' . ($colprop['subtypes'] ? 'contactfieldgroupmulti ' : '') . 'contactcontroller' . $col, 'style' => ($rows ? null : 'display:none')), - ($colprop['subtypes'] ? html::tag('legend', null, Q($colprop['label'])) : ' ') . + ($colprop['subtypes'] ? html::tag('legend', null, rcube::Q($colprop['label'])) : ' ') . $rows); } } @@ -722,7 +749,7 @@ function rcmail_contact_form($form, $record, $attrib = null) } if ($content) - $out .= html::tag('fieldset', null, html::tag('legend', null, Q($fieldset['name'])) . $content) ."\n"; + $out .= html::tag('fieldset', null, html::tag('legend', null, rcube::Q($fieldset['name'])) . $content) ."\n"; } if ($edit_mode) { @@ -792,7 +819,7 @@ function rcmail_contact_photo($attrib) function rcmail_format_date_col($val) { global $RCMAIL; - return format_date($val, $RCMAIL->config->get('date_format', 'Y-m-d'), false); + return $RCMAIL->format_date($val, $RCMAIL->config->get('date_format', 'Y-m-d'), false); } /** @@ -855,8 +882,8 @@ function rcmail_get_cids($filter = null) // forms. If _source is an empty string then the ID is a string // containing contact ID and source name in form: <ID>-<SOURCE> - $cid = get_input_value('_cid', RCUBE_INPUT_GPC); - $source = (string) get_input_value('_source', RCUBE_INPUT_GPC); + $cid = rcube_utils::get_input_value('_cid', rcube_utils::INPUT_GPC); + $source = (string) rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); if (is_array($cid)) { return $cid; @@ -893,27 +920,3 @@ function rcmail_get_cids($filter = null) return $filter !== null ? $result[$filter] : $result; } - - -// register UI objects -$OUTPUT->add_handlers(array( - 'directorylist' => 'rcmail_directory_list', -// 'groupslist' => 'rcmail_contact_groups', - 'addresslist' => 'rcmail_contacts_list', - 'addresslisttitle' => 'rcmail_contacts_list_title', - 'addressframe' => 'rcmail_contact_frame', - 'recordscountdisplay' => 'rcmail_rowcount_display', - 'searchform' => array($OUTPUT, 'search_form') -)); - -// register action aliases -$RCMAIL->register_action_map(array( - 'add' => 'edit.inc', - 'group-create' => 'groups.inc', - 'group-rename' => 'groups.inc', - 'group-delete' => 'groups.inc', - 'group-addmembers' => 'groups.inc', - 'group-delmembers' => 'groups.inc', - 'search-create' => 'search.inc', - 'search-delete' => 'search.inc', -)); diff --git a/program/steps/addressbook/groups.inc b/program/steps/addressbook/groups.inc index 3b9288a2b..aef93f2c7 100644 --- a/program/steps/addressbook/groups.inc +++ b/program/steps/addressbook/groups.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/groups.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2010, The Roundcube Dev Team | + | Copyright (C) 2010-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,117 +19,136 @@ +-----------------------------------------------------------------------+ */ -$source = get_input_value('_source', RCUBE_INPUT_GPC); +$source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); $CONTACTS = rcmail_contact_source($source); if ($CONTACTS->readonly || !$CONTACTS->groups) { - $OUTPUT->show_message('sourceisreadonly', 'warning'); - $OUTPUT->send(); + $OUTPUT->show_message('sourceisreadonly', 'warning'); + $OUTPUT->send(); } if ($RCMAIL->action == 'group-addmembers') { - if (($gid = get_input_value('_gid', RCUBE_INPUT_POST)) && ($ids = rcmail_get_cids($source))) { - $plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array('group_id' => $gid, 'ids' => $ids, 'source' => $source)); - - $CONTACTS->set_group($gid); - $num2add = count($plugin['ids']); - - if (!$plugin['abort']) { - if (($maxnum = $RCMAIL->config->get('max_group_members', 0)) && ($CONTACTS->count()->count + $num2add > $maxnum)) { - $OUTPUT->show_message('maxgroupmembersreached', 'warning', array('max' => $maxnum)); - $OUTPUT->send(); - } - $result = $CONTACTS->add_to_group($gid, $plugin['ids']); + if (($gid = rcube_utils::get_input_value('_gid', rcube_utils::INPUT_POST)) && ($ids = rcmail_get_cids($source))) { + $plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array( + 'group_id' => $gid, + 'ids' => $ids, + 'source' => $source, + )); + + $CONTACTS->set_group($gid); + $num2add = count($plugin['ids']); + + if (!$plugin['abort']) { + if (($maxnum = $RCMAIL->config->get('max_group_members', 0)) && ($CONTACTS->count()->count + $num2add > $maxnum)) { + $OUTPUT->show_message('maxgroupmembersreached', 'warning', array('max' => $maxnum)); + $OUTPUT->send(); + } + + $result = $CONTACTS->add_to_group($gid, $plugin['ids']); + } + else { + $result = $plugin['result']; + } + + if ($result) + $OUTPUT->show_message('contactaddedtogroup'); + else if ($plugin['abort'] || $CONTACTS->get_error()) + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); + else + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'nogroupassignmentschanged'); } - else { - $result = $plugin['result']; - } - - if ($result) - $OUTPUT->show_message('contactaddedtogroup'); - else if ($plugin['abort'] || $CONTACTS->get_error()) - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); - else - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'nogroupassignmentschanged'); - } } - else if ($RCMAIL->action == 'group-delmembers') { - if (($gid = get_input_value('_gid', RCUBE_INPUT_POST)) && ($ids = rcmail_get_cids($source))) { - $plugin = $RCMAIL->plugins->exec_hook('group_delmembers', array('group_id' => $gid, 'ids' => $ids, 'source' => $source)); + if (($gid = rcube_utils::get_input_value('_gid', rcube_utils::INPUT_POST)) && ($ids = rcmail_get_cids($source))) { + $plugin = $RCMAIL->plugins->exec_hook('group_delmembers', array( + 'group_id' => $gid, + 'ids' => $ids, + 'source' => $source, + )); + + if (!$plugin['abort']) + $result = $CONTACTS->remove_from_group($gid, $plugin['ids']); + else + $result = $plugin['result']; + + if ($result) { + $OUTPUT->show_message('contactremovedfromgroup'); + $OUTPUT->command('remove_group_contacts',array('source' => $source, 'gid' => $gid)); + } + else { + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); + } + } +} +else if ($RCMAIL->action == 'group-create') { + if ($name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true))) { + $plugin = $RCMAIL->plugins->exec_hook('group_create', array( + 'name' => $name, + 'source' => $source, + )); + + if (!$plugin['abort']) + $created = $CONTACTS->create_group($plugin['name']); + else + $created = $plugin['result']; + } - if (!$plugin['abort']) - $result = $CONTACTS->remove_from_group($gid, $plugin['ids']); - else - $result = $plugin['result']; + if ($created && $OUTPUT->ajax_call) { + $created['name'] = rcube::Q($created['name']); - if ($result) { - $OUTPUT->show_message('contactremovedfromgroup'); - $OUTPUT->command('remove_group_contacts',array('source' => $source, 'gid' => $gid)); + $OUTPUT->show_message('groupcreated', 'confirmation'); + $OUTPUT->command('insert_contact_group', array('source' => $source) + $created); } - else { - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); + else if (!$created) { + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); } - } -} - -else if ($RCMAIL->action == 'group-create') { - if ($name = trim(get_input_value('_name', RCUBE_INPUT_POST, true))) { - $plugin = $RCMAIL->plugins->exec_hook('group_create', array('name' => $name, 'source' => $source)); - - if (!$plugin['abort']) - $created = $CONTACTS->create_group($plugin['name']); - else - $created = $plugin['result']; - } - - if ($created && $OUTPUT->ajax_call) { - $created['name'] = Q($created['name']); - $OUTPUT->show_message('groupcreated', 'confirmation'); - $OUTPUT->command('insert_contact_group', array('source' => $source) + $created); - } - else if (!$created) { - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); - } } - else if ($RCMAIL->action == 'group-rename') { - if (($gid = get_input_value('_gid', RCUBE_INPUT_POST)) && ($name = trim(get_input_value('_name', RCUBE_INPUT_POST, true)))) { - $plugin = $RCMAIL->plugins->exec_hook('group_rename', array('group_id' => $gid, 'name' => $name, 'source' => $source)); - - if (!$plugin['abort']) - $newname = $CONTACTS->rename_group($gid, $plugin['name'], $newgid); - else - $newname = $plugin['result']; - } - - if ($newname && $OUTPUT->ajax_call) { - $OUTPUT->show_message('grouprenamed', 'confirmation'); - $OUTPUT->command('update_contact_group', array( - 'source' => $source, 'id' => $gid, 'name' => Q($newname), 'newid' => $newgid)); - } - else if (!$newname) - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); -} + if (($gid = rcube_utils::get_input_value('_gid', rcube_utils::INPUT_POST)) + && ($name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true))) + ) { + $plugin = $RCMAIL->plugins->exec_hook('group_rename', array( + 'group_id' => $gid, + 'name' => $name, + 'source' => $source, + )); + + if (!$plugin['abort']) + $newname = $CONTACTS->rename_group($gid, $plugin['name'], $newgid); + else + $newname = $plugin['result']; + } + if ($newname && $OUTPUT->ajax_call) { + $OUTPUT->show_message('grouprenamed', 'confirmation'); + $OUTPUT->command('update_contact_group', array( + 'source' => $source, 'id' => $gid, 'name' => rcube::Q($newname), 'newid' => $newgid)); + } + else if (!$newname) { + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); + } +} else if ($RCMAIL->action == 'group-delete') { - if ($gid = get_input_value('_gid', RCUBE_INPUT_POST)) { - $plugin = $RCMAIL->plugins->exec_hook('group_delete', array('group_id' => $gid, 'source' => $source)); - - if (!$plugin['abort']) - $deleted = $CONTACTS->delete_group($gid); - else - $deleted = $plugin['result']; - } - - if ($deleted) { - $OUTPUT->show_message('groupdeleted', 'confirmation'); - $OUTPUT->command('remove_group_item', array('source' => $source, 'id' => $gid)); - } - else - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); + if ($gid = rcube_utils::get_input_value('_gid', rcube_utils::INPUT_POST)) { + $plugin = $RCMAIL->plugins->exec_hook('group_delete', array( + 'group_id' => $gid, + 'source' => $source, + )); + + if (!$plugin['abort']) + $deleted = $CONTACTS->delete_group($gid); + else + $deleted = $plugin['result']; + } + + if ($deleted) { + $OUTPUT->show_message('groupdeleted', 'confirmation'); + $OUTPUT->command('remove_group_item', array('source' => $source, 'id' => $gid)); + } + else { + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); + } } // send response $OUTPUT->send(); - diff --git a/program/steps/addressbook/import.inc b/program/steps/addressbook/import.inc index 60f5d7b61..33e473242 100644 --- a/program/steps/addressbook/import.inc +++ b/program/steps/addressbook/import.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/import.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2008-2009, The Roundcube Dev Team | + | Copyright (C) 2008-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -20,169 +20,14 @@ +-----------------------------------------------------------------------+ */ -/** - * Handler function to display the import/upload form - */ -function rcmail_import_form($attrib) -{ - global $RCMAIL, $OUTPUT; - $target = get_input_value('_target', RCUBE_INPUT_GPC); - - $attrib += array('id' => "rcmImportForm"); - - $writable_books = $RCMAIL->get_address_sources(true, true); - - $upload = new html_inputfield(array( - 'type' => 'file', - 'name' => '_file[]', - 'id' => 'rcmimportfile', - 'size' => 40, - 'multiple' => 'multiple', - )); - $form = html::p(null, html::label('rcmimportfile', rcube_label('importfromfile')) . $upload->show()); - $table = new html_table(array('cols' => 2)); - - // addressbook selector - if (count($writable_books) > 1) { - $select = new html_select(array('name' => '_target', 'id' => 'rcmimporttarget', 'is_escaped' => true)); - - foreach ($writable_books as $book) - $select->add($book['name'], $book['id']); - - $table->add('title', html::label('rcmimporttarget', rcube_label('importtarget'))); - $table->add(null, $select->show($target)); - } - else { - $abook = new html_hiddenfield(array('name' => '_target', 'value' => key($writable_books))); - $form .= $abook->show(); - } - - // selector for group import options - if (count($writable_books) >= 1 || $writable_books[0]->groups) { - $select = new html_select(array('name' => '_groups', 'id' => 'rcmimportgroups', 'is_escaped' => true)); - $select->add(rcube_label('none'), '0'); - $select->add(rcube_label('importgroupsall'), '1'); - $select->add(rcube_label('importgroupsexisting'), '2'); - - $table->add('title', html::label('rcmimportgroups', rcube_label('importgroups'))); - $table->add(null, $select->show(get_input_value('_groups', RCUBE_INPUT_GPC))); - } - - // checkbox to replace the entire address book - $check_replace = new html_checkbox(array('name' => '_replace', 'value' => 1, 'id' => 'rcmimportreplace')); - $table->add('title', html::label('rcmimportreplace', rcube_label('importreplace'))); - $table->add(null, $check_replace->show(get_input_value('_replace', RCUBE_INPUT_GPC))); - - $form .= $table->show(array('id' => null) + $attrib); - - $OUTPUT->set_env('writable_source', !empty($writable_books)); - $OUTPUT->add_label('selectimportfile','importwait'); - $OUTPUT->add_gui_object('importform', $attrib['id']); - - $out = html::p(null, Q(rcube_label('importdesc'), 'show')); - - $out .= $OUTPUT->form_tag(array( - 'action' => $RCMAIL->url('import'), - 'method' => 'post', - 'enctype' => 'multipart/form-data') + $attrib, - $form); - - return $out; -} - - -/** - * Render the confirmation page for the import process - */ -function rcmail_import_confirm($attrib) -{ - global $IMPORT_STATS; - - $vars = get_object_vars($IMPORT_STATS); - $vars['names'] = $vars['skipped_names'] = ''; - - $content = html::p(null, rcube_label(array( - 'name' => 'importconfirm', - 'nr' => $IMPORT_STATS->inserted, - 'vars' => $vars, - )) . ($IMPORT_STATS->names ? ':' : '.')); - - if ($IMPORT_STATS->names) - $content .= html::p('em', join(', ', array_map('Q', $IMPORT_STATS->names))); - - if ($IMPORT_STATS->skipped) { - $content .= html::p(null, rcube_label(array( - 'name' => 'importconfirmskipped', - 'nr' => $IMPORT_STATS->skipped, - 'vars' => $vars, - )) . ':'); - $content .= html::p('em', join(', ', array_map('Q', $IMPORT_STATS->skipped_names))); - } - - return html::div($attrib, $content); -} - - -/** - * Create navigation buttons for the current import step - */ -function rcmail_import_buttons($attrib) -{ - global $IMPORT_STATS, $OUTPUT; - $target = get_input_value('_target', RCUBE_INPUT_GPC); - - $attrib += array('type' => 'input'); - unset($attrib['name']); - - if (is_object($IMPORT_STATS)) { - $attrib['class'] = trim($attrib['class'] . ' mainaction'); - $out = $OUTPUT->button(array('command' => 'list', 'prop' => $target, 'label' => 'done') + $attrib); - } - else { - $out = $OUTPUT->button(array('command' => 'list', 'label' => 'cancel') + $attrib); - $out .= ' '; - $attrib['class'] = trim($attrib['class'] . ' mainaction'); - $out .= $OUTPUT->button(array('command' => 'import', 'label' => 'import') + $attrib); - } - - return $out; -} - - -/** - * Returns the matching group id. If group doesn't exist, it'll be created if allowed. - */ -function rcmail_import_group_id($group_name, $CONTACTS, $create, &$import_groups) -{ - $group_id = 0; - foreach ($import_groups as $key => $group) { - if (strtolower($group['name']) == strtolower($group_name)) { - $group_id = $group['ID']; - break; - } - } - - // create a new group - if (!$group_id && $create) { - $new_group = $CONTACTS->create_group($group_name); - if (!$new_group['ID']) - $new_group['ID'] = $new_group['id']; - $import_groups[] = $new_group; - $group_id = $new_group['ID']; - } - - return $group_id; -} - - /** The import process **/ $importstep = 'rcmail_import_form'; if (is_array($_FILES['_file'])) { - $replace = (bool)get_input_value('_replace', RCUBE_INPUT_GPC); - $target = get_input_value('_target', RCUBE_INPUT_GPC); - $with_groups = intval(get_input_value('_groups', RCUBE_INPUT_GPC)); + $replace = (bool)rcube_utils::get_input_value('_replace', rcube_utils::INPUT_GPC); + $target = rcube_utils::get_input_value('_target', rcube_utils::INPUT_GPC); + $with_groups = intval(rcube_utils::get_input_value('_groups', rcube_utils::INPUT_GPC)); $vcards = array(); $upload_error = null; @@ -232,7 +77,8 @@ if (is_array($_FILES['_file'])) { // no vcards detected if (!count($vcards)) { if ($upload_error == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) { - $OUTPUT->show_message('filesizeerror', 'error', array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize'))))); + $size = $RCMAIL->show_bytes(parse_bytes(ini_get('upload_max_filesize'))); + $OUTPUT->show_message('filesizeerror', 'error', array('size' => $size)); } else if ($upload_error) { $OUTPUT->show_message('fileuploaderror', 'error'); @@ -249,7 +95,7 @@ if (is_array($_FILES['_file'])) { $IMPORT_STATS->inserted = $IMPORT_STATS->skipped = $IMPORT_STATS->invalid = $IMPORT_STATS->errors = 0; if ($replace) { - $CONTACTS->delete_all(); + $CONTACTS->delete_all($CONTACTS->groups && $with_groups < 2); } if ($with_groups) { @@ -276,7 +122,7 @@ if (is_array($_FILES['_file'])) { // We're using UTF8 internally $email = $vcard->email[0]; - $email = rcube_idn_to_utf8($email); + $email = rcube_utils::idn_to_utf8($email); if (!$replace) { $existing = null; @@ -330,12 +176,168 @@ if (is_array($_FILES['_file'])) { } -$OUTPUT->set_pagetitle(rcube_label('importcontacts')); +$OUTPUT->set_pagetitle($RCMAIL->gettext('importcontacts')); $OUTPUT->add_handlers(array( - 'importstep' => $importstep, - 'importnav' => 'rcmail_import_buttons', + 'importstep' => $importstep, + 'importnav' => 'rcmail_import_buttons', )); // render page $OUTPUT->send('importcontacts'); + + + +/** + * Handler function to display the import/upload form + */ +function rcmail_import_form($attrib) +{ + global $RCMAIL, $OUTPUT; + + $target = rcube_utils::get_input_value('_target', rcube_utils::INPUT_GPC); + + $attrib += array('id' => "rcmImportForm"); + + $writable_books = $RCMAIL->get_address_sources(true, true); + + $upload = new html_inputfield(array( + 'type' => 'file', + 'name' => '_file[]', + 'id' => 'rcmimportfile', + 'size' => 40, + 'multiple' => 'multiple', + )); + $form = html::p(null, html::label('rcmimportfile', $RCMAIL->gettext('importfromfile')) . $upload->show()); + $table = new html_table(array('cols' => 2)); + + // addressbook selector + if (count($writable_books) > 1) { + $select = new html_select(array('name' => '_target', 'id' => 'rcmimporttarget', 'is_escaped' => true)); + + foreach ($writable_books as $book) { + $select->add($book['name'], $book['id']); + } + + $table->add('title', html::label('rcmimporttarget', $RCMAIL->gettext('importtarget'))); + $table->add(null, $select->show($target)); + } + else { + $abook = new html_hiddenfield(array('name' => '_target', 'value' => key($writable_books))); + $form .= $abook->show(); + } + + // selector for group import options + if (count($writable_books) >= 1 || $writable_books[0]->groups) { + $select = new html_select(array('name' => '_groups', 'id' => 'rcmimportgroups', 'is_escaped' => true)); + $select->add($RCMAIL->gettext('none'), '0'); + $select->add($RCMAIL->gettext('importgroupsall'), '1'); + $select->add($RCMAIL->gettext('importgroupsexisting'), '2'); + + $table->add('title', html::label('rcmimportgroups', $RCMAIL->gettext('importgroups'))); + $table->add(null, $select->show(rcube_utils::get_input_value('_groups', rcube_utils::INPUT_GPC))); + } + + // checkbox to replace the entire address book + $check_replace = new html_checkbox(array('name' => '_replace', 'value' => 1, 'id' => 'rcmimportreplace')); + $table->add('title', html::label('rcmimportreplace', $RCMAIL->gettext('importreplace'))); + $table->add(null, $check_replace->show(rcube_utils::get_input_value('_replace', rcube_utils::INPUT_GPC))); + + $form .= $table->show(array('id' => null) + $attrib); + + $OUTPUT->set_env('writable_source', !empty($writable_books)); + $OUTPUT->add_label('selectimportfile','importwait'); + $OUTPUT->add_gui_object('importform', $attrib['id']); + + $out = html::p(null, rcube::Q($RCMAIL->gettext('importdesc'), 'show')) + . $OUTPUT->form_tag(array( + 'action' => $RCMAIL->url('import'), + 'method' => 'post', + 'enctype' => 'multipart/form-data') + $attrib, + $form); + + return $out; +} + +/** + * Render the confirmation page for the import process + */ +function rcmail_import_confirm($attrib) +{ + global $IMPORT_STATS, $RCMAIL; + + $vars = get_object_vars($IMPORT_STATS); + $vars['names'] = $vars['skipped_names'] = ''; + + $content = html::p(null, $RCMAIL->gettext(array( + 'name' => 'importconfirm', + 'nr' => $IMPORT_STATS->inserted, + 'vars' => $vars, + )) . ($IMPORT_STATS->names ? ':' : '.')); + + if ($IMPORT_STATS->names) { + $content .= html::p('em', join(', ', array_map('Q', $IMPORT_STATS->names))); + } + + if ($IMPORT_STATS->skipped) { + $content .= html::p(null, $RCMAIL->gettext(array( + 'name' => 'importconfirmskipped', + 'nr' => $IMPORT_STATS->skipped, + 'vars' => $vars, + )) . ':') + . html::p('em', join(', ', array_map('Q', $IMPORT_STATS->skipped_names))); + } + + return html::div($attrib, $content); +} + +/** + * Create navigation buttons for the current import step + */ +function rcmail_import_buttons($attrib) +{ + global $IMPORT_STATS, $OUTPUT; + + $target = rcube_utils::get_input_value('_target', rcube_utils::INPUT_GPC); + + $attrib += array('type' => 'input'); + unset($attrib['name']); + + if (is_object($IMPORT_STATS)) { + $attrib['class'] = trim($attrib['class'] . ' mainaction'); + $out = $OUTPUT->button(array('command' => 'list', 'prop' => $target, 'label' => 'done') + $attrib); + } + else { + $out = $OUTPUT->button(array('command' => 'list', 'label' => 'cancel') + $attrib); + $out .= ' '; + $attrib['class'] = trim($attrib['class'] . ' mainaction'); + $out .= $OUTPUT->button(array('command' => 'import', 'label' => 'import') + $attrib); + } + + return $out; +} + +/** + * Returns the matching group id. If group doesn't exist, it'll be created if allowed. + */ +function rcmail_import_group_id($group_name, $CONTACTS, $create, &$import_groups) +{ + $group_id = 0; + foreach ($import_groups as $key => $group) { + if (strtolower($group['name']) == strtolower($group_name)) { + $group_id = $group['ID']; + break; + } + } + + // create a new group + if (!$group_id && $create) { + $new_group = $CONTACTS->create_group($group_name); + if (!$new_group['ID']) + $new_group['ID'] = $new_group['id']; + $import_groups[] = $new_group; + $group_id = $new_group['ID']; + } + + return $group_id; +} diff --git a/program/steps/addressbook/mailto.inc b/program/steps/addressbook/mailto.inc index c3cbcadca..f5ff20bc0 100644 --- a/program/steps/addressbook/mailto.inc +++ b/program/steps/addressbook/mailto.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/mailto.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2007, The Roundcube Dev Team | + | Copyright (C) 2007-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,30 +19,27 @@ +-----------------------------------------------------------------------+ */ -$cids = rcmail_get_cids(); -$mailto = array(); +$cids = rcmail_get_cids(); +$mailto = array(); $recipients = null; -foreach ($cids as $source => $cid) -{ +foreach ($cids as $source => $cid) { $CONTACTS = $RCMAIL->get_address_book($source); - if ($CONTACTS->ready) - { + if ($CONTACTS->ready) { $CONTACTS->set_page(1); $CONTACTS->set_pagesize(count($cid) + 2); // +2 to skip counting query $recipients = $CONTACTS->search($CONTACTS->primary_key, $cid, 0, true, true, 'email'); } } -if (!empty($_REQUEST['_gid']) && isset($_REQUEST['_source'])) -{ - $source = get_input_value('_source', RCUBE_INPUT_GPC); +if (!empty($_REQUEST['_gid']) && isset($_REQUEST['_source'])) { + $source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); $CONTACTS = $RCMAIL->get_address_book($source); - - $group_id = get_input_value('_gid', RCUBE_INPUT_GPC); + + $group_id = rcube_utils::get_input_value('_gid', rcube_utils::INPUT_GPC); $group_data = $CONTACTS->get_group($group_id); - + // group has an email address assigned: use that if ($group_data['email']) { $mailto[] = format_email_recipient($group_data['email'][0], $group_data['name']); @@ -55,16 +52,14 @@ if (!empty($_REQUEST['_gid']) && isset($_REQUEST['_source'])) } } -if ($recipients) -{ +if ($recipients) { while (is_object($recipients) && ($rec = $recipients->iterate())) { $emails = $CONTACTS->get_col_values('email', $rec, true); $mailto[] = format_email_recipient($emails[0], $rec['name']); } } -if (!empty($mailto)) -{ +if (!empty($mailto)) { $mailto_str = join(', ', $mailto); $mailto_id = substr(md5($mailto_str), 0, 16); $_SESSION['mailto'][$mailto_id] = urlencode($mailto_str); diff --git a/program/steps/addressbook/move.inc b/program/steps/addressbook/move.inc index f8204e9ee..6a70e7bda 100644 --- a/program/steps/addressbook/move.inc +++ b/program/steps/addressbook/move.inc @@ -25,8 +25,8 @@ if (!$OUTPUT->ajax_call) { } $cids = rcmail_get_cids(); -$target = get_input_value('_to', RCUBE_INPUT_POST); -$target_group = get_input_value('_togid', RCUBE_INPUT_POST); +$target = rcube_utils::get_input_value('_to', rcube_utils::INPUT_POST); +$target_group = rcube_utils::get_input_value('_togid', rcube_utils::INPUT_POST); $all = 0; $deleted = 0; diff --git a/program/steps/addressbook/photo.inc b/program/steps/addressbook/photo.inc index 658027de4..482185735 100644 --- a/program/steps/addressbook/photo.inc +++ b/program/steps/addressbook/photo.inc @@ -26,7 +26,7 @@ $source = key($cids); $cid = $cids ? array_shift($cids[$source]) : null; // read the referenced file -if (($file_id = get_input_value('_photo', RCUBE_INPUT_GPC)) && ($tempfile = $_SESSION['contacts']['files'][$file_id])) { +if (($file_id = rcube_utils::get_input_value('_photo', rcube_utils::INPUT_GPC)) && ($tempfile = $_SESSION['contacts']['files'][$file_id])) { $tempfile = $RCMAIL->plugins->exec_hook('attachment_display', $tempfile); if ($tempfile['status']) { if ($tempfile['data']) @@ -37,7 +37,7 @@ if (($file_id = get_input_value('_photo', RCUBE_INPUT_GPC)) && ($tempfile = $_SE } else { // by email, search for contact first - if ($email = get_input_value('_email', RCUBE_INPUT_GPC)) { + if ($email = rcube_utils::get_input_value('_email', rcube_utils::INPUT_GPC)) { foreach ($RCMAIL->get_address_sources() as $s) { $abook = $RCMAIL->get_address_book($s['id']); $result = $abook->search(array('email'), $email, 1, true, true, 'photo'); @@ -77,7 +77,7 @@ else { } // deliver alt image -if (!$data && ($alt_img = get_input_value('_alt', RCUBE_INPUT_GPC)) && is_file($alt_img)) { +if (!$data && ($alt_img = rcube_utils::get_input_value('_alt', rcube_utils::INPUT_GPC)) && is_file($alt_img)) { $data = file_get_contents($alt_img); } @@ -86,6 +86,6 @@ if (!$cid && $email) { $RCMAIL->output->future_expire_header(86400); } -header('Content-Type: ' . rc_image_content_type($data)); +header('Content-Type: ' . rcube_mime::image_content_type($data)); echo $data ? $data : file_get_contents('program/resources/blank.gif'); exit; diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc index 2adc53bcf..94556f96b 100644 --- a/program/steps/addressbook/save.inc +++ b/program/steps/addressbook/save.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/save.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2011, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,80 +19,87 @@ +-----------------------------------------------------------------------+ */ -$CONTACTS = rcmail_contact_source(null, true, true); -$cid = get_input_value('_cid', RCUBE_INPUT_POST); +$CONTACTS = rcmail_contact_source(null, true, true); +$cid = rcube_utils::get_input_value('_cid', rcube_utils::INPUT_POST); $return_action = empty($cid) ? 'add' : 'edit'; // Source changed, display the form again if (!empty($_GET['_reload'])) { - rcmail_overwrite_action($return_action); - return; + $RCMAIL->overwrite_action($return_action); + return; } // cannot edit record if ($CONTACTS->readonly) { - $OUTPUT->show_message('contactreadonly', 'error'); - rcmail_overwrite_action($return_action); - return; + $OUTPUT->show_message('contactreadonly', 'error'); + $RCMAIL->overwrite_action($return_action); + return; } // read POST values into hash array $a_record = array(); foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) { - $fname = '_'.$col; - if ($colprop['composite']) - continue; - // gather form data of composite fields - if ($colprop['childs']) { - $values = array(); - foreach ($colprop['childs'] as $childcol => $cp) { - $vals = get_input_value('_'.$childcol, RCUBE_INPUT_POST, true); - foreach ((array)$vals as $i => $val) - $values[$i][$childcol] = $val; + if ($colprop['composite']) { + continue; } - $subtypes = isset($_REQUEST['_subtype_' . $col]) ? (array)get_input_value('_subtype_' . $col, RCUBE_INPUT_POST) : array(''); - foreach ($subtypes as $i => $subtype) { - $suffix = $subtype ? ':'.$subtype : ''; - if ($values[$i]) - $a_record[$col.$suffix][] = $values[$i]; - } - } - // assign values and subtypes - else if (is_array($_POST[$fname])) { - $values = get_input_value($fname, RCUBE_INPUT_POST, true); - $subtypes = get_input_value('_subtype_' . $col, RCUBE_INPUT_POST); - - foreach ($values as $i => $val) { - if ($col == 'email') { - // extract email from full address specification, e.g. "Name" <addr@domain.tld> - $addr = rcube_mime::decode_address_list($val, 1, false); - if (!empty($addr) && ($addr = array_pop($addr)) && $addr['mailto']) { - $val = $addr['mailto']; + + $fname = '_'.$col; + + // gather form data of composite fields + if ($colprop['childs']) { + $values = array(); + foreach ($colprop['childs'] as $childcol => $cp) { + $vals = rcube_utils::get_input_value('_'.$childcol, rcube_utils::INPUT_POST, true); + foreach ((array)$vals as $i => $val) { + $values[$i][$childcol] = $val; + } } - } - $subtype = $subtypes[$i] ? ':'.$subtypes[$i] : ''; - $a_record[$col.$subtype][] = $val; + $subtypes = isset($_REQUEST['_subtype_' . $col]) ? (array)rcube_utils::get_input_value('_subtype_' . $col, rcube_utils::INPUT_POST) : array(''); + foreach ($subtypes as $i => $subtype) { + $suffix = $subtype ? ':'.$subtype : ''; + if ($values[$i]) { + $a_record[$col.$suffix][] = $values[$i]; + } + } } - } - else if (isset($_POST[$fname])) { - $a_record[$col] = get_input_value($fname, RCUBE_INPUT_POST, true); - - // normalize the submitted date strings - if ($colprop['type'] == 'date') { - if ($timestamp = rcube_utils::strtotime($a_record[$col])) { - $a_record[$col] = date('Y-m-d', $timestamp); + // assign values and subtypes + else if (is_array($_POST[$fname])) { + $values = rcube_utils::get_input_value($fname, rcube_utils::INPUT_POST, true); + $subtypes = rcube_utils::get_input_value('_subtype_' . $col, rcube_utils::INPUT_POST); + + foreach ($values as $i => $val) { + if ($col == 'email') { + // extract email from full address specification, e.g. "Name" <addr@domain.tld> + $addr = rcube_mime::decode_address_list($val, 1, false); + if (!empty($addr) && ($addr = array_pop($addr)) && $addr['mailto']) { + $val = $addr['mailto']; + } + } + + $subtype = $subtypes[$i] ? ':'.$subtypes[$i] : ''; + $a_record[$col.$subtype][] = $val; } - else { - unset($a_record[$col]); + } + else if (isset($_POST[$fname])) { + $a_record[$col] = rcube_utils::get_input_value($fname, rcube_utils::INPUT_POST, true); + + // normalize the submitted date strings + if ($colprop['type'] == 'date') { + if ($a_record[$col] && ($dt = rcube_utils::anytodatetime($a_record[$col]))) { + $a_record[$col] = $dt->format('Y-m-d'); + } + else { + unset($a_record[$col]); + } } } - } } // Generate contact's display name (must be before validation) if (empty($a_record['name'])) { $a_record['name'] = rcube_addressbook::compose_display_name($a_record, true); + // Reset it if equals to email address (from compose_display_name()) $email = rcube_addressbook::get_col_values('email', $a_record, true); if ($a_record['name'] == $email[0]) { @@ -103,9 +110,9 @@ if (empty($a_record['name'])) { // do input checks (delegated to $CONTACTS instance) if (!$CONTACTS->validate($a_record)) { $err = (array)$CONTACTS->get_error(); - $OUTPUT->show_message($err['message'] ? Q($err['message']) : 'formincomplete', 'warning'); + $OUTPUT->show_message($err['message'] ? rcube::Q($err['message']) : 'formincomplete', 'warning'); $GLOBALS['EDIT_RECORD'] = $a_record; // store submitted data to be used in edit form - rcmail_overwrite_action($return_action); + $RCMAIL->overwrite_action($return_action); return; } @@ -127,123 +134,125 @@ if (isset($a_record['photo'])) { $RCMAIL->session->remove('contacts'); } -$source = get_input_value('_source', RCUBE_INPUT_GPC); +$source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); // update an existing contact -if (!empty($cid)) -{ - $plugin = $RCMAIL->plugins->exec_hook('contact_update', - array('id' => $cid, 'record' => $a_record, 'source' => $source)); - $a_record = $plugin['record']; - - if (!$plugin['abort']) - $result = $CONTACTS->update($cid, $a_record); - else - $result = $plugin['result']; - - if ($result) { - // LDAP DN change - if (is_string($result) && strlen($result)>1) { - $newcid = $result; - // change cid in POST for 'show' action - $_POST['_cid'] = $newcid; - } +if (!empty($cid)) { + $plugin = $RCMAIL->plugins->exec_hook('contact_update', + array('id' => $cid, 'record' => $a_record, 'source' => $source)); + $a_record = $plugin['record']; - // define list of cols to be displayed - $a_js_cols = array(); - $record = $CONTACTS->get_record($newcid ? $newcid : $cid, true); - $record['email'] = reset($CONTACTS->get_col_values('email', $record, true)); - $record['name'] = rcube_addressbook::compose_list_name($record); - - foreach (array('name') as $col) - $a_js_cols[] = Q((string)$record[$col]); - - // update the changed col in list - $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record); - - // show confirmation - $OUTPUT->show_message('successfullysaved', 'confirmation', null, false); - rcmail_overwrite_action('show'); - } - else { - // show error message - $err = $CONTACTS->get_error(); - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : ($err['message'] ? $err['message'] : 'errorsaving'), 'error', null, false); - rcmail_overwrite_action('show'); - } + if (!$plugin['abort']) + $result = $CONTACTS->update($cid, $a_record); + else + $result = $plugin['result']; + + if ($result) { + // LDAP DN change + if (is_string($result) && strlen($result)>1) { + $newcid = $result; + // change cid in POST for 'show' action + $_POST['_cid'] = $newcid; + } + + // define list of cols to be displayed + $a_js_cols = array(); + $record = $CONTACTS->get_record($newcid ? $newcid : $cid, true); + $record['email'] = reset($CONTACTS->get_col_values('email', $record, true)); + $record['name'] = rcube_addressbook::compose_list_name($record); + + foreach (array('name') as $col) { + $a_js_cols[] = rcube::Q((string)$record[$col]); + } + + // update the changed col in list + $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record); + + // show confirmation + $OUTPUT->show_message('successfullysaved', 'confirmation', null, false); + $RCMAIL->overwrite_action('show'); + } + else { + // show error message + $err = $CONTACTS->get_error(); + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : ($err['message'] ? $err['message'] : 'errorsaving'), 'error', null, false); + $RCMAIL->overwrite_action('show'); + } } // insert a new contact else { - // Name of the addressbook already selected on the list - $orig_source = get_input_value('_orig_source', RCUBE_INPUT_GPC); - - if (!strlen($source)) - $source = $orig_source; - - // show notice if existing contacts with same e-mail are found - foreach ($CONTACTS->get_col_values('email', $a_record, true) as $email) { - if ($email && ($res = $CONTACTS->search('email', $email, 1, false, true)) && $res->count) { - $OUTPUT->show_message('contactexists', 'notice', null, false); - break; - } - } - - $plugin = $RCMAIL->plugins->exec_hook('contact_create', array( - 'record' => $a_record, 'source' => $source)); - $a_record = $plugin['record']; - - // insert record and send response - if (!$plugin['abort']) - $insert_id = $CONTACTS->insert($a_record); - else - $insert_id = $plugin['result']; - - if ($insert_id) { - $CONTACTS->reset(); - - // add new contact to the specified group - if ($CONTACTS->groups && $CONTACTS->group_id) { - $plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array( - 'group_id' => $CONTACTS->group_id, 'ids' => $insert_id, 'source' => $source)); - - $counts = $CONTACTS->count(); - - if (!$plugin['abort']) { - if (($maxnum = $RCMAIL->config->get('max_group_members', 0)) && ($counts->count + 1 > $maxnum)) - $OUTPUT->show_message('maxgroupmembersreached', 'warning', array('max' => $maxnum)); - - $CONTACTS->add_to_group($plugin['group_id'], $plugin['ids']); - } + // Name of the addressbook already selected on the list + $orig_source = rcube_utils::get_input_value('_orig_source', rcube_utils::INPUT_GPC); + + if (!strlen($source)) { + $source = $orig_source; } + + // show notice if existing contacts with same e-mail are found + foreach ($CONTACTS->get_col_values('email', $a_record, true) as $email) { + if ($email && ($res = $CONTACTS->search('email', $email, 1, false, true)) && $res->count) { + $OUTPUT->show_message('contactexists', 'notice', null, false); + break; + } + } + + $plugin = $RCMAIL->plugins->exec_hook('contact_create', array( + 'record' => $a_record, 'source' => $source)); + $a_record = $plugin['record']; + + // insert record and send response + if (!$plugin['abort']) + $insert_id = $CONTACTS->insert($a_record); else - $counts = $CONTACTS->count(); + $insert_id = $plugin['result']; + + if ($insert_id) { + $CONTACTS->reset(); + + // add new contact to the specified group + if ($CONTACTS->groups && $CONTACTS->group_id) { + $plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array( + 'group_id' => $CONTACTS->group_id, 'ids' => $insert_id, 'source' => $source)); - if ((string)$source === (string)$orig_source) { - // add contact row or jump to the page where it should appear - $CONTACTS->reset(); - $result = $CONTACTS->search($CONTACTS->primary_key, $insert_id); + $counts = $CONTACTS->count(); - rcmail_js_contacts_list($result, 'parent.'); - $OUTPUT->command('parent.contact_list.select', html_identifier($insert_id)); + if (!$plugin['abort']) { + if (($maxnum = $RCMAIL->config->get('max_group_members', 0)) && ($counts->count + 1 > $maxnum)) + $OUTPUT->show_message('maxgroupmembersreached', 'warning', array('max' => $maxnum)); - // update record count display - $CONTACTS->reset(); - $OUTPUT->command('parent.set_rowcount', rcmail_get_rowcount_text($counts)); + $CONTACTS->add_to_group($plugin['group_id'], $plugin['ids']); + } + } + else { + $counts = $CONTACTS->count(); + } + + if ((string)$source === (string)$orig_source) { + // add contact row or jump to the page where it should appear + $CONTACTS->reset(); + $result = $CONTACTS->search($CONTACTS->primary_key, $insert_id); + + rcmail_js_contacts_list($result, 'parent.'); + $OUTPUT->command('parent.contact_list.select', rcube_utils::html_identifier($insert_id)); + + // update record count display + $CONTACTS->reset(); + $OUTPUT->command('parent.set_rowcount', rcmail_get_rowcount_text($counts)); + } + else { + // re-set iframe + $OUTPUT->command('parent.show_contentframe'); + } + + // show confirmation + $OUTPUT->show_message('successfullysaved', 'confirmation', null, false); + $OUTPUT->send('iframe'); } else { - // re-set iframe - $OUTPUT->command('parent.show_contentframe'); + // show error message + $err = $CONTACTS->get_error(); + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : ($err['message'] ? $err['message'] : 'errorsaving'), 'error', null, false); + $RCMAIL->overwrite_action('add'); } - - // show confirmation - $OUTPUT->show_message('successfullysaved', 'confirmation', null, false); - $OUTPUT->send('iframe'); - } - else { - // show error message - $err = $CONTACTS->get_error(); - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : ($err['message'] ? $err['message'] : 'errorsaving'), 'error', null, false); - rcmail_overwrite_action('add'); - } } diff --git a/program/steps/addressbook/search.inc b/program/steps/addressbook/search.inc index d153c255a..bb22ec139 100644 --- a/program/steps/addressbook/search.inc +++ b/program/steps/addressbook/search.inc @@ -22,8 +22,8 @@ */ if ($RCMAIL->action == 'search-create') { - $id = get_input_value('_search', RCUBE_INPUT_POST); - $name = get_input_value('_name', RCUBE_INPUT_POST, true); + $id = rcube_utils::get_input_value('_search', rcube_utils::INPUT_POST); + $name = rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true); if (($params = $_SESSION['search_params']) && $params['id'] == $id) { @@ -46,7 +46,7 @@ if ($RCMAIL->action == 'search-create') { if ($result) { $OUTPUT->show_message('savedsearchcreated', 'confirmation'); - $OUTPUT->command('insert_saved_search', Q($name), Q($result)); + $OUTPUT->command('insert_saved_search', rcube::Q($name), rcube::Q($result)); } else $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'savedsearchcreateerror', 'error'); @@ -55,7 +55,7 @@ if ($RCMAIL->action == 'search-create') { } if ($RCMAIL->action == 'search-delete') { - $id = get_input_value('_sid', RCUBE_INPUT_POST); + $id = rcube_utils::get_input_value('_sid', rcube_utils::INPUT_POST); $plugin = $RCMAIL->plugins->exec_hook('saved_search_delete', array('id' => $id)); @@ -66,9 +66,9 @@ if ($RCMAIL->action == 'search-delete') { if ($result) { $OUTPUT->show_message('savedsearchdeleted', 'confirmation'); - $OUTPUT->command('remove_search_item', Q($id)); + $OUTPUT->command('remove_search_item', rcube::Q($id)); // contact list will be cleared, clear also page counter - $OUTPUT->command('set_rowcount', rcube_label('nocontactsfound')); + $OUTPUT->command('set_rowcount', $RCMAIL->gettext('nocontactsfound')); $OUTPUT->set_env('pagecount', 0); } else @@ -91,7 +91,7 @@ function rcmail_contact_search() global $RCMAIL, $OUTPUT, $SEARCH_MODS_DEFAULT, $PAGE_SIZE; $adv = isset($_POST['_adv']); - $sid = get_input_value('_sid', RCUBE_INPUT_GET); + $sid = rcube_utils::get_input_value('_sid', rcube_utils::INPUT_GET); // get search criteria from saved search if ($sid && ($search = $RCMAIL->user->get_search($sid))) { @@ -101,7 +101,7 @@ function rcmail_contact_search() // get fields/values from advanced search form else if ($adv) { foreach (array_keys($_POST) as $key) { - $s = trim(get_input_value($key, RCUBE_INPUT_POST, true)); + $s = trim(rcube_utils::get_input_value($key, rcube_utils::INPUT_POST, true)); if (strlen($s) && preg_match('/^_search_([a-zA-Z0-9_-]+)$/', $key, $m)) { $search[] = $s; $fields[] = $m[1]; @@ -115,8 +115,8 @@ function rcmail_contact_search() } // quick-search else { - $search = trim(get_input_value('_q', RCUBE_INPUT_GET, true)); - $fields = explode(',', get_input_value('_headers', RCUBE_INPUT_GET)); + $search = trim(rcube_utils::get_input_value('_q', rcube_utils::INPUT_GET, true)); + $fields = explode(',', rcube_utils::get_input_value('_headers', rcube_utils::INPUT_GET)); if (empty($fields)) { $fields = array_keys($SEARCH_MODS_DEFAULT); @@ -257,17 +257,17 @@ function rcmail_contact_search_form($attrib) $form = array( 'main' => array( - 'name' => rcube_label('properties'), + 'name' => $RCMAIL->gettext('properties'), 'content' => array( ), ), 'personal' => array( - 'name' => rcube_label('personalinfo'), + 'name' => $RCMAIL->gettext('personalinfo'), 'content' => array( ), ), 'other' => array( - 'name' => rcube_label('other'), + 'name' => $RCMAIL->gettext('other'), 'content' => array( ), ), @@ -297,7 +297,7 @@ function rcmail_contact_search_form($attrib) if ($colprop['type'] != 'image' && !$colprop['nosearch']) { $ftype = $colprop['type'] == 'select' ? 'select' : 'text'; - $label = isset($colprop['label']) ? $colprop['label'] : rcube_label($col); + $label = isset($colprop['label']) ? $colprop['label'] : $RCMAIL->gettext($col); $category = $colprop['category'] ? $colprop['category'] : 'other'; // load jquery UI datepicker for date fields @@ -307,8 +307,8 @@ function rcmail_contact_search_form($attrib) $colprop['size'] = $i_size; - $content = html::div('row', html::div('contactfieldlabel label', Q($label)) - . html::div('contactfieldcontent', rcmail_get_edit_field('search_'.$col, '', $colprop, $ftype))); + $content = html::div('row', html::div('contactfieldlabel label', rcube::Q($label)) + . html::div('contactfieldcontent', rcube_output::get_edit_field('search_'.$col, '', $colprop, $ftype))); $form[$category]['content'][] = $content; } @@ -332,7 +332,7 @@ function rcmail_contact_search_form($attrib) $content = html::div('contactfieldgroup', join("\n", $f['content'])); $out .= html::tag('fieldset', $attrib, - html::tag('legend', null, Q($f['name'])) + html::tag('legend', null, rcube::Q($f['name'])) . $content) . "\n"; } } diff --git a/program/steps/addressbook/show.inc b/program/steps/addressbook/show.inc index efab5e9e5..f4224a3e2 100644 --- a/program/steps/addressbook/show.inc +++ b/program/steps/addressbook/show.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/show.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2012, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -38,6 +38,15 @@ if ($cid && ($record = $CONTACTS->get_record($cid, true))) { // get address book name (for display) rcmail_set_sourcename($CONTACTS); +$OUTPUT->add_handlers(array( + 'contacthead' => 'rcmail_contact_head', + 'contactdetails' => 'rcmail_contact_details', + 'contactphoto' => 'rcmail_contact_photo', +)); + +$OUTPUT->send('contact'); + + function rcmail_contact_head($attrib) { @@ -45,7 +54,7 @@ function rcmail_contact_head($attrib) // check if we have a valid result if (!(($result = $CONTACTS->get_result()) && ($record = $result->first()))) { - $RCMAIL->output->show_message('contactnotfound'); + $RCMAIL->output->show_message('contactnotfound', 'error'); return false; } @@ -72,7 +81,6 @@ function rcmail_contact_details($attrib) // check if we have a valid result if (!(($result = $CONTACTS->get_result()) && ($record = $result->first()))) { - //$RCMAIL->output->show_message('contactnotfound'); return false; } @@ -80,7 +88,7 @@ function rcmail_contact_details($attrib) $form = array( 'contact' => array( - 'name' => rcube_label('properties'), + 'name' => $RCMAIL->gettext('properties'), 'content' => array( 'email' => array('size' => $i_size, 'render_func' => 'rcmail_render_email_value'), 'phone' => array('size' => $i_size), @@ -90,7 +98,7 @@ function rcmail_contact_details($attrib) ), ), 'personal' => array( - 'name' => rcube_label('personalinfo'), + 'name' => $RCMAIL->gettext('personalinfo'), 'content' => array( 'gender' => array('size' => $i_size), 'maidenname' => array('size' => $i_size), @@ -102,19 +110,19 @@ function rcmail_contact_details($attrib) ), ), ); - + if (isset($CONTACT_COLTYPES['notes'])) { $form['notes'] = array( - 'name' => rcube_label('notes'), + 'name' => $RCMAIL->gettext('notes'), 'content' => array( 'notes' => array('type' => 'textarea', 'label' => false), ), ); } - + if ($CONTACTS->groups) { $form['groups'] = array( - 'name' => rcube_label('groups'), + 'name' => $RCMAIL->gettext('groups'), 'content' => rcmail_contact_record_groups($record['ID']), ); } @@ -125,12 +133,14 @@ function rcmail_contact_details($attrib) function rcmail_render_email_value($email) { + global $RCMAIL; + return html::a(array( 'href' => 'mailto:' . $email, - 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ($email)), - 'title' => rcube_label('composeto'), + 'onclick' => sprintf("return %s.command('compose','%s',this)", rcmail_output::JS_OBJECT_NAME, rcube::JQ($email)), + 'title' => $RCMAIL->gettext('composeto'), 'class' => 'email', - ), Q($email)); + ), rcube::Q($email)); } @@ -141,7 +151,7 @@ function rcmail_render_url_value($url) 'href' => $prefix . $url, 'target' => '_blank', 'class' => 'url', - ), Q($url)); + ), rcube::Q($url)); } @@ -164,10 +174,10 @@ function rcmail_contact_record_groups($contact_id) $gid = $group['ID']; $table->add(null, $checkbox->show($members[$gid] ? $gid : null, array('value' => $gid, 'id' => 'ff_gid' . $gid))); - $table->add(null, html::label('ff_gid' . $gid, Q($group['name']))); + $table->add(null, html::label('ff_gid' . $gid, rcube::Q($group['name']))); } - $hiddenfields = new html_hiddenfield(array('name' => '_source', 'value' => get_input_value('_source', RCUBE_INPUT_GPC))); + $hiddenfields = new html_hiddenfield(array('name' => '_source', 'value' => rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC))); $hiddenfields->add(array('name' => '_cid', 'value' => $contact_id)); $form_start = $RCMAIL->output->request_form(array( @@ -182,12 +192,3 @@ function rcmail_contact_record_groups($contact_id) return $form_start . html::tag('fieldset', 'contactfieldgroup contactgroups', $table->show()) . $form_end; } - - -$OUTPUT->add_handlers(array( - 'contacthead' => 'rcmail_contact_head', - 'contactdetails' => 'rcmail_contact_details', - 'contactphoto' => 'rcmail_contact_photo', -)); - -$OUTPUT->send('contact'); diff --git a/program/steps/addressbook/undo.inc b/program/steps/addressbook/undo.inc index c23bd1cb6..ec3feb9c0 100644 --- a/program/steps/addressbook/undo.inc +++ b/program/steps/addressbook/undo.inc @@ -5,7 +5,7 @@ | program/steps/addressbook/undo.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2011, Kolab Systems AG | + | Copyright (C) 2011-2013, Kolab Systems AG | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -20,14 +20,14 @@ */ // process ajax requests only -if (!$OUTPUT->ajax_call) +if (!$OUTPUT->ajax_call) { return; +} $undo = $_SESSION['contact_undo']; $delcnt = 0; -foreach ((array)$undo['data'] as $source => $cid) -{ +foreach ((array)$undo['data'] as $source => $cid) { $CONTACTS = rcmail_contact_source($source); $plugin = $RCMAIL->plugins->exec_hook('contact_undelete', array( diff --git a/program/steps/addressbook/upload_photo.inc b/program/steps/addressbook/upload_photo.inc index 035d67e83..dbb76d229 100644 --- a/program/steps/addressbook/upload_photo.inc +++ b/program/steps/addressbook/upload_photo.inc @@ -54,7 +54,7 @@ if ($filepath = $_FILES['_photo']['tmp_name']) { )); } else { - $attachment['error'] = rcube_label('invalidimageformat'); + $attachment['error'] = $RCMAIL->gettext('invalidimageformat'); } if ($attachment['status'] && !$attachment['abort']) { @@ -63,14 +63,16 @@ if ($filepath = $_FILES['_photo']['tmp_name']) { $OUTPUT->command('replace_contact_photo', $file_id); } else { // upload failed - $err = $_FILES['_photo']['error']; + $err = $_FILES['_photo']['error']; + $size = $RCMAIL->show_bytes(parse_bytes(ini_get('upload_max_filesize'))); + if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) - $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize')))))); + $msg = $RCMAIL->gettext(array('name' => 'filesizeerror', 'vars' => array('size' => $size))); else if ($attachment['error']) $msg = $attachment['error']; else - $msg = rcube_label('fileuploaderror'); - + $msg = $RCMAIL->gettext('fileuploaderror'); + $OUTPUT->command('display_message', $msg, 'error'); } } @@ -78,9 +80,9 @@ else if ($_SERVER['REQUEST_METHOD'] == 'POST') { // if filesize exceeds post_max_size then $_FILES array is empty, // show filesizeerror instead of fileuploaderror if ($maxsize = ini_get('post_max_size')) - $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes($maxsize))))); + $msg = $RCMAIL->gettext(array('name' => 'filesizeerror', 'vars' => array('size' => $RCMAIL->show_bytes(parse_bytes($maxsize))))); else - $msg = rcube_label('fileuploaderror'); + $msg = $RCMAIL->gettext('fileuploaderror'); $OUTPUT->command('display_message', $msg, 'error'); } diff --git a/program/steps/mail/addcontact.inc b/program/steps/mail/addcontact.inc index 380557766..76bf2ee32 100644 --- a/program/steps/mail/addcontact.inc +++ b/program/steps/mail/addcontact.inc @@ -5,7 +5,7 @@ | program/steps/mail/addcontact.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -20,69 +20,74 @@ */ // only process ajax requests -if (!$OUTPUT->ajax_call) - return; +if (!$OUTPUT->ajax_call) { + return; +} // Get default addressbook $CONTACTS = $RCMAIL->get_address_book(-1, true); -if (!empty($_POST['_address']) && is_object($CONTACTS)) -{ - $contact_arr = rcube_mime::decode_address_list(get_input_value('_address', RCUBE_INPUT_POST, true), 1, false); - - if (!empty($contact_arr[1]['mailto'])) { - $contact = array( - 'email' => $contact_arr[1]['mailto'], - 'name' => $contact_arr[1]['name'] - ); - - // Validity checks - if (empty($contact['email'])) { - $OUTPUT->show_message('errorsavingcontact', 'error'); - $OUTPUT->send(); - } - - $email = rcube_idn_to_ascii($contact['email']); - if (!check_email($email, false)) { - $OUTPUT->show_message('emailformaterror', 'error', array('email' => $contact['email'])); - $OUTPUT->send(); +if (!empty($_POST['_address']) && is_object($CONTACTS)) { + $address = rcube_utils::get_input_value('_address', rcube_utils::INPUT_POST, true); + $contact_arr = rcube_mime::decode_address_list($address, 1, false); + + if (!empty($contact_arr[1]['mailto'])) { + $contact = array( + 'email' => $contact_arr[1]['mailto'], + 'name' => $contact_arr[1]['name'], + ); + + // Validity checks + if (empty($contact['email'])) { + $OUTPUT->show_message('errorsavingcontact', 'error'); + $OUTPUT->send(); + } + + $email = rcube_utils::idn_to_ascii($contact['email']); + if (!rcube_utils::check_email($email, false)) { + $OUTPUT->show_message('emailformaterror', 'error', array('email' => $contact['email'])); + $OUTPUT->send(); + } + + $contact['email'] = rcube_utils::idn_to_utf8($contact['email']); + + $contact = $RCMAIL->plugins->exec_hook('contact_displayname', $contact); + + if (empty($contact['firstname']) || empty($contact['surname'])) { + $contact['name'] = rcube_addressbook::compose_display_name($contact); + } + + // validate contact record + if (!$CONTACTS->validate($contact, true)) { + $error = $CONTACTS->get_error(); + // TODO: show dialog to complete record + // if ($error['type'] == rcube_addressbook::ERROR_VALIDATE) { } + + $OUTPUT->show_message($error['message'] ? $error['message'] : 'errorsavingcontact', 'error'); + $OUTPUT->send(); + } + + // check for existing contacts + $existing = $CONTACTS->search('email', $contact['email'], 1, false); + + if ($done = $existing->count) { + $OUTPUT->show_message('contactexists', 'warning'); + } + else { + $plugin = $RCMAIL->plugins->exec_hook('contact_create', array('record' => $contact, 'source' => null)); + $contact = $plugin['record']; + + $done = !$plugin['abort'] ? $CONTACTS->insert($contact) : $plugin['result']; + + if ($done) { + $OUTPUT->show_message('addedsuccessfully', 'confirmation'); + } + } } - - $contact['email'] = rcube_idn_to_utf8($contact['email']); - $contact = $RCMAIL->plugins->exec_hook('contact_displayname', $contact); - - if (empty($contact['firstname']) || empty($contact['surname'])) - $contact['name'] = rcube_addressbook::compose_display_name($contact); - - // validate contact record - if (!$CONTACTS->validate($contact, true)) { - $error = $CONTACTS->get_error(); - // TODO: show dialog to complete record - // if ($error['type'] == rcube_addressbook::ERROR_VALIDATE) { } - - $OUTPUT->show_message($error['message'] ? $error['message'] : 'errorsavingcontact', 'error'); - $OUTPUT->send(); - } - - // check for existing contacts - $existing = $CONTACTS->search('email', $contact['email'], 1, false); - - if ($done = $existing->count) - $OUTPUT->show_message('contactexists', 'warning'); - else { - $plugin = $RCMAIL->plugins->exec_hook('contact_create', array('record' => $contact, 'source' => null)); - $contact = $plugin['record']; - - $done = !$plugin['abort'] ? $CONTACTS->insert($contact) : $plugin['result']; - - if ($done) - $OUTPUT->show_message('addedsuccessfully', 'confirmation'); - } - } } -if (!$done) - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsavingcontact', 'error'); +if (!$done) { + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsavingcontact', 'error'); +} $OUTPUT->send(); - diff --git a/program/steps/mail/attachments.inc b/program/steps/mail/attachments.inc index 85aa9542b..85bc36cac 100644 --- a/program/steps/mail/attachments.inc +++ b/program/steps/mail/attachments.inc @@ -5,7 +5,7 @@ | program/steps/mail/attachments.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -21,62 +21,73 @@ // Upload progress update if (!empty($_GET['_progress'])) { - rcube_upload_progress(); + $RCMAIL->upload_progress(); } -$COMPOSE_ID = get_input_value('_id', RCUBE_INPUT_GPC); +$COMPOSE_ID = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); $COMPOSE = null; if ($COMPOSE_ID && $_SESSION['compose_data_' . $COMPOSE_ID]) { - $SESSION_KEY = 'compose_data_' . $COMPOSE_ID; - $COMPOSE =& $_SESSION[$SESSION_KEY]; + $SESSION_KEY = 'compose_data_' . $COMPOSE_ID; + $COMPOSE =& $_SESSION[$SESSION_KEY]; } if (!$COMPOSE) { - die("Invalid session var!"); + die("Invalid session var!"); } // remove an attachment -if ($RCMAIL->action=='remove-attachment') -{ - $id = 'undefined'; - if (preg_match('/^rcmfile(\w+)$/', $_POST['_file'], $regs)) - $id = $regs[1]; - if ($attachment = $COMPOSE['attachments'][$id]) - $attachment = $RCMAIL->plugins->exec_hook('attachment_delete', $attachment); - if ($attachment['status']) { - if (is_array($COMPOSE['attachments'][$id])) { - $RCMAIL->session->remove($SESSION_KEY.'.attachments.'.$id); - $OUTPUT->command('remove_from_attachment_list', "rcmfile$id"); +if ($RCMAIL->action=='remove-attachment') { + $id = 'undefined'; + + if (preg_match('/^rcmfile(\w+)$/', $_POST['_file'], $regs)) { + $id = $regs[1]; + } + + if ($attachment = $COMPOSE['attachments'][$id]) { + $attachment = $RCMAIL->plugins->exec_hook('attachment_delete', $attachment); } - } - $OUTPUT->send(); - exit; + if ($attachment['status']) { + if (is_array($COMPOSE['attachments'][$id])) { + $RCMAIL->session->remove($SESSION_KEY.'.attachments.'.$id); + $OUTPUT->command('remove_from_attachment_list', "rcmfile$id"); + } + } + + $OUTPUT->send(); + exit; } -if ($RCMAIL->action=='display-attachment') -{ - $id = 'undefined'; - if (preg_match('/^rcmfile(\w+)$/', $_GET['_file'], $regs)) - $id = $regs[1]; - if ($attachment = $COMPOSE['attachments'][$id]) - $attachment = $RCMAIL->plugins->exec_hook('attachment_display', $attachment); - - if ($attachment['status']) { - if (empty($attachment['size'])) - $attachment['size'] = $attachment['data'] ? strlen($attachment['data']) : @filesize($attachment['path']); - - header('Content-Type: ' . $attachment['mimetype']); - header('Content-Length: ' . $attachment['size']); - - if ($attachment['data']) - echo $attachment['data']; - else if ($attachment['path']) - readfile($attachment['path']); - } - exit; +if ($RCMAIL->action=='display-attachment') { + $id = 'undefined'; + + if (preg_match('/^rcmfile(\w+)$/', $_GET['_file'], $regs)) { + $id = $regs[1]; + } + + if ($attachment = $COMPOSE['attachments'][$id]) { + $attachment = $RCMAIL->plugins->exec_hook('attachment_display', $attachment); + } + + if ($attachment['status']) { + if (empty($attachment['size'])) { + $attachment['size'] = $attachment['data'] ? strlen($attachment['data']) : @filesize($attachment['path']); + } + + header('Content-Type: ' . $attachment['mimetype']); + header('Content-Length: ' . $attachment['size']); + + if ($attachment['data']) { + echo $attachment['data']; + } + else if ($attachment['path']) { + readfile($attachment['path']); + } + } + + exit; } /***** attachment upload action *****/ @@ -84,93 +95,97 @@ if ($RCMAIL->action=='display-attachment') // clear all stored output properties (like scripts and env vars) $OUTPUT->reset(); -$uploadid = get_input_value('_uploadid', RCUBE_INPUT_GET); +$uploadid = rcube_utils::get_input_value('_uploadid', rcube_utils::INPUT_GET); if (is_array($_FILES['_attachments']['tmp_name'])) { - $multiple = count($_FILES['_attachments']['tmp_name']) > 1; - - foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) { - // Process uploaded attachment if there is no error - $err = $_FILES['_attachments']['error'][$i]; - - if (!$err) { - $attachment = array( - 'path' => $filepath, - 'size' => $_FILES['_attachments']['size'][$i], - 'name' => $_FILES['_attachments']['name'][$i], - 'mimetype' => rc_mime_content_type($filepath, $_FILES['_attachments']['name'][$i], $_FILES['_attachments']['type'][$i]), - 'group' => $COMPOSE_ID, - ); - - $attachment = $RCMAIL->plugins->exec_hook('attachment_upload', $attachment); + $multiple = count($_FILES['_attachments']['tmp_name']) > 1; + + foreach ($_FILES['_attachments']['tmp_name'] as $i => $filepath) { + // Process uploaded attachment if there is no error + $err = $_FILES['_attachments']['error'][$i]; + + if (!$err) { + $attachment = $RCMAIL->plugins->exec_hook('attachment_upload', array( + 'path' => $filepath, + 'size' => $_FILES['_attachments']['size'][$i], + 'name' => $_FILES['_attachments']['name'][$i], + 'mimetype' => rcube_mime::file_content_type($filepath, $_FILES['_attachments']['name'][$i], $_FILES['_attachments']['type'][$i]), + 'group' => $COMPOSE_ID, + )); + } + + if (!$err && $attachment['status'] && !$attachment['abort']) { + $id = $attachment['id']; + + // store new attachment in session + unset($attachment['status'], $attachment['abort']); + $RCMAIL->session->append($SESSION_KEY.'.attachments', $id, $attachment); + + if (($icon = $COMPOSE['deleteicon']) && is_file($icon)) { + $button = html::img(array( + 'src' => $icon, + 'alt' => $RCMAIL->gettext('delete') + )); + } + else if ($COMPOSE['textbuttons']) { + $button = rcube::Q($RCMAIL->gettext('delete')); + } + else { + $button = ''; + } + + $content = html::a(array( + 'href' => "#delete", + 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", rcmail_output::JS_OBJECT_NAME, $id), + 'title' => $RCMAIL->gettext('delete'), + 'class' => 'delete', + ), $button); + + $content .= rcube::Q($attachment['name']); + + $OUTPUT->command('add2attachment_list', "rcmfile$id", array( + 'html' => $content, + 'name' => $attachment['name'], + 'mimetype' => $attachment['mimetype'], + 'classname' => rcube_utils::file2class($attachment['mimetype'], $attachment['name']), + 'complete' => true), $uploadid); + } + else { // upload failed + if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) { + $size = $RCMAIL->show_bytes(parse_bytes(ini_get('upload_max_filesize'))); + $msg = $RCMAIL->gettext(array('name' => 'filesizeerror', 'vars' => array('size' => $size))); + } + else if ($attachment['error']) { + $msg = $attachment['error']; + } + else { + $msg = $RCMAIL->gettext('fileuploaderror'); + } + + if ($attachment['error'] || $err != UPLOAD_ERR_NO_FILE) { + $OUTPUT->command('display_message', $msg, 'error'); + $OUTPUT->command('remove_from_attachment_list', $uploadid); + } + } } - - if (!$err && $attachment['status'] && !$attachment['abort']) { - $id = $attachment['id']; - - // store new attachment in session - unset($attachment['status'], $attachment['abort']); - $RCMAIL->session->append($SESSION_KEY.'.attachments', $id, $attachment); - - if (($icon = $COMPOSE['deleteicon']) && is_file($icon)) { - $button = html::img(array( - 'src' => $icon, - 'alt' => rcube_label('delete') +} +else if ($_SERVER['REQUEST_METHOD'] == 'POST') { + // if filesize exceeds post_max_size then $_FILES array is empty, + // show filesizeerror instead of fileuploaderror + if ($maxsize = ini_get('post_max_size')) { + $msg = $RCMAIL->gettext(array( + 'name' => 'filesizeerror', + 'vars' => array('size' => $RCMAIL->show_bytes(parse_bytes($maxsize))) )); - } - else if ($COMPOSE['textbuttons']) { - $button = Q(rcube_label('delete')); - } - else { - $button = ''; - } - - $content = html::a(array( - 'href' => "#delete", - 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id), - 'title' => rcube_label('delete'), - 'class' => 'delete', - ), $button); - - $content .= Q($attachment['name']); - - $OUTPUT->command('add2attachment_list', "rcmfile$id", array( - 'html' => $content, - 'name' => $attachment['name'], - 'mimetype' => $attachment['mimetype'], - 'classname' => rcmail_filetype2classname($attachment['mimetype'], $attachment['name']), - 'complete' => true), $uploadid); } - else { // upload failed - if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) { - $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize')))))); - } - else if ($attachment['error']) { - $msg = $attachment['error']; - } - else { - $msg = rcube_label('fileuploaderror'); - } - - if ($attachment['error'] || $err != UPLOAD_ERR_NO_FILE) { - $OUTPUT->command('display_message', $msg, 'error'); - $OUTPUT->command('remove_from_attachment_list', $uploadid); - } + else { + $msg = $RCMAIL->gettext('fileuploaderror'); } - } -} -else if ($_SERVER['REQUEST_METHOD'] == 'POST') { - // if filesize exceeds post_max_size then $_FILES array is empty, - // show filesizeerror instead of fileuploaderror - if ($maxsize = ini_get('post_max_size')) - $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes($maxsize))))); - else - $msg = rcube_label('fileuploaderror'); - $OUTPUT->command('display_message', $msg, 'error'); - $OUTPUT->command('remove_from_attachment_list', $uploadid); + + $OUTPUT->command('display_message', $msg, 'error'); + $OUTPUT->command('remove_from_attachment_list', $uploadid); } // send html page with JS calls as response $OUTPUT->command('auto_save_start', false); $OUTPUT->send('iframe'); - diff --git a/program/steps/mail/autocomplete.inc b/program/steps/mail/autocomplete.inc index c34133a28..5b8b49dba 100644 --- a/program/steps/mail/autocomplete.inc +++ b/program/steps/mail/autocomplete.inc @@ -5,8 +5,8 @@ | program/steps/mail/autocomplete.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2008-2011, Roundcube Dev Team | - | Copyright (C) 2011, Kolab Systems AG | + | Copyright (C) 2008-2013, Roundcube Dev Team | + | Copyright (C) 2011-2013, Kolab Systems AG | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -21,124 +21,137 @@ */ if ($RCMAIL->action == 'group-expand') { - $abook = $RCMAIL->get_address_book(get_input_value('_source', RCUBE_INPUT_GPC)); - if ($gid = get_input_value('_gid', RCUBE_INPUT_GPC)) { - $members = array(); - $abook->set_group($gid); - $abook->set_pagesize(1000); // TODO: limit number of group members by config - $result = $abook->list_records($RCMAIL->config->get('contactlist_fields')); - while ($result && ($sql_arr = $result->iterate())) { - foreach ((array)$sql_arr['email'] as $email) { - $members[] = format_email_recipient($email, rcube_addressbook::compose_list_name($sql_arr)); - break; // only expand one email per contact - } - } + $abook = $RCMAIL->get_address_book(rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC)); + if ($gid = rcube_utils::get_input_value('_gid', rcube_utils::INPUT_GPC)) { + $abook->set_group($gid); + $abook->set_pagesize(1000); // TODO: limit number of group members by config + + $separator = trim($RCMAIL->config->get('recipients_separator', ',')) . ' '; + $result = $abook->list_records($RCMAIL->config->get('contactlist_fields')); + $members = array(); + + while ($result && ($sql_arr = $result->iterate())) { + $emails = (array) $abook->get_col_values('email', $sql_arr, true); + if (!empty($emails) && ($email = array_shift($emails))) { + $members[] = format_email_recipient($email, rcube_addressbook::compose_list_name($sql_arr)); + } + } - $separator = trim($RCMAIL->config->get('recipients_separator', ',')) . ' '; - $OUTPUT->command('replace_group_recipients', $gid, join($separator, array_unique($members))); - } + $OUTPUT->command('replace_group_recipients', $gid, join($separator, array_unique($members))); + } - $OUTPUT->send(); + $OUTPUT->send(); } $MAXNUM = (int) $RCMAIL->config->get('autocomplete_max', 15); $mode = (int) $RCMAIL->config->get('addressbook_search_mode'); $single = (bool) $RCMAIL->config->get('autocomplete_single'); -$search = get_input_value('_search', RCUBE_INPUT_GPC, true); -$source = get_input_value('_source', RCUBE_INPUT_GPC); -$reqid = get_input_value('_reqid', RCUBE_INPUT_GPC); +$search = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC, true); +$source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); +$reqid = rcube_utils::get_input_value('_reqid', rcube_utils::INPUT_GPC); -if (strlen($source)) - $book_types = array($source); -else - $book_types = (array) $RCMAIL->config->get('autocomplete_addressbooks', 'sql'); +if (strlen($source)) { + $book_types = array($source); +} +else { + $book_types = (array) $RCMAIL->config->get('autocomplete_addressbooks', 'sql'); +} if (!empty($book_types) && strlen($search)) { - $contacts = array(); - $sort_keys = array(); - $books_num = count($book_types); - $search_lc = mb_strtolower($search); - - foreach ($book_types as $id) { - $abook = $RCMAIL->get_address_book($id); - $abook->set_pagesize($MAXNUM); - - if ($result = $abook->search($RCMAIL->config->get('contactlist_fields'), $search, $mode, true, true, 'email')) { - while ($sql_arr = $result->iterate()) { - // Contact can have more than one e-mail address - $email_arr = (array)$abook->get_col_values('email', $sql_arr, true); - $email_cnt = count($email_arr); - $idx = 0; - foreach ($email_arr as $email) { - if (empty($email)) { - continue; - } - - $sql_arr['name'] = rcube_addressbook::compose_list_name($sql_arr); - $contact = format_email_recipient($email, $sql_arr['name']); - - // skip entries that don't match - if ($email_cnt > 1 && strpos(mb_strtolower($contact), $search_lc) === false) { - continue; - } - - // skip duplicates - if (!in_array($contact, $contacts)) { - $contacts[] = $contact; - $sort_keys[] = sprintf('%s %03d', $sql_arr['name'] , $idx++); - - if (count($contacts) >= $MAXNUM) - break 2; - } - - // skip redundant entries (show only first email address) - if ($single) { - break; - } + $contacts = array(); + $sort_keys = array(); + $books_num = count($book_types); + $search_lc = mb_strtolower($search); + + foreach ($book_types as $id) { + $abook = $RCMAIL->get_address_book($id); + $abook->set_pagesize($MAXNUM); + + if ($result = $abook->search($RCMAIL->config->get('contactlist_fields'), $search, $mode, true, true, 'email')) { + while ($sql_arr = $result->iterate()) { + // Contact can have more than one e-mail address + $email_arr = (array)$abook->get_col_values('email', $sql_arr, true); + $email_cnt = count($email_arr); + $idx = 0; + + foreach ($email_arr as $email) { + if (empty($email)) { + continue; + } + + $name = rcube_addressbook::compose_list_name($sql_arr); + $contact = format_email_recipient($email, $name); + + // skip entries that don't match + if ($email_cnt > 1 && strpos(mb_strtolower($contact), $search_lc) === false) { + continue; + } + + // skip duplicates + if (!in_array($contact, $contacts)) { + $contacts[] = $contact; + $sort_keys[] = sprintf('%s %03d', $sql_arr['name'] , $idx++); + + if (count($contacts) >= $MAXNUM) { + break 2; + } + } + + // skip redundant entries (show only first email address) + if ($single) { + break; + } + } + } } - } - } - // also list matching contact groups - if ($abook->groups && count($contacts) < $MAXNUM) { - foreach ($abook->list_groups($search, $mode) as $group) { - $abook->reset(); - $abook->set_group($group['ID']); - $group_prop = $abook->get_group($group['ID']); - - // group (distribution list) with email address(es) - if ($group_prop['email']) { - $idx = 0; - foreach ((array)$group_prop['email'] as $email) { - $contacts[] = format_email_recipient($email, $group['name']); - $sort_keys[] = sprintf('%s %03d', $group['name'] , $idx++); - - if (count($contacts) >= $MAXNUM) - break 2; + // also list matching contact groups + if ($abook->groups && count($contacts) < $MAXNUM) { + foreach ($abook->list_groups($search, $mode) as $group) { + $abook->reset(); + $abook->set_group($group['ID']); + + $group_prop = $abook->get_group($group['ID']); + + // group (distribution list) with email address(es) + if ($group_prop['email']) { + $idx = 0; + foreach ((array)$group_prop['email'] as $email) { + $contacts[] = format_email_recipient($email, $group['name']); + $sort_keys[] = sprintf('%s %03d', $group['name'] , $idx++); + + if (count($contacts) >= $MAXNUM) { + break 2; + } + } + } + // show group with count + else if (($result = $abook->count()) && $result->count) { + $sort_keys[] = $group['name']; + $contacts[] = array( + 'name' => $group['name'] . ' (' . intval($result->count) . ')', + 'id' => $group['ID'], + 'source' => $id + ); + + if (count($contacts) >= $MAXNUM) { + break; + } + } } } - // show group with count - else if (($result = $abook->count()) && $result->count) { - $contacts[] = array('name' => $group['name'] . ' (' . intval($result->count) . ')', 'id' => $group['ID'], 'source' => $id); - $sort_keys[] = $group['name']; + } - if (count($contacts) >= $MAXNUM) - break; + if (count($contacts)) { + // sort contacts index + asort($sort_keys, SORT_LOCALE_STRING); + // re-sort contacts according to index + foreach ($sort_keys as $idx => $val) { + $sort_keys[$idx] = $contacts[$idx]; } - } - } - } - - if (count($contacts)) { - // sort contacts index - asort($sort_keys, SORT_LOCALE_STRING); - // re-sort contacts according to index - foreach ($sort_keys as $idx => $val) { - $sort_keys[$idx] = $contacts[$idx]; + $contacts = array_values($sort_keys); } - $contacts = array_values($sort_keys); - } } $OUTPUT->command('ksearch_query_results', $contacts, $search, $reqid); diff --git a/program/steps/mail/check_recent.inc b/program/steps/mail/check_recent.inc index 8c0b1ffc0..d2d27a2ca 100644 --- a/program/steps/mail/check_recent.inc +++ b/program/steps/mail/check_recent.inc @@ -25,6 +25,7 @@ if (empty($_REQUEST['_folderlist']) && empty($_REQUEST['_list'])) { return; } +$trash = $RCMAIL->config->get('trash_mbox'); $current = $RCMAIL->storage->get_folder(); $check_all = $RCMAIL->action != 'refresh' || (bool)$RCMAIL->config->get('check_all_folders'); @@ -65,7 +66,7 @@ foreach ($a_mailboxes as $mbox_name) { if ($status && $is_current) { // refresh saved search set - $search_request = get_input_value('_search', RCUBE_INPUT_GPC); + $search_request = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC); if ($search_request && isset($_SESSION['search']) && $_SESSION['search_request'] == $search_request ) { @@ -73,7 +74,7 @@ foreach ($a_mailboxes as $mbox_name) { } if (!empty($_GET['_quota'])) - $OUTPUT->command('set_quota', rcmail_quota_content()); + $OUTPUT->command('set_quota', $RCMAIL->quota_content()); $OUTPUT->set_env('exists', $RCMAIL->storage->count($mbox_name, 'EXISTS')); @@ -114,6 +115,29 @@ foreach ($a_mailboxes as $mbox_name) { $OUTPUT->command('update_selection'); } } + // handle flag updates + else if ($is_current && ($uids = rcube_utils::get_input_value('_uids', rcube_utils::INPUT_GPC))) { + $data = $RCMAIL->storage->folder_data($mbox_name); + + if (empty($_SESSION['list_mod_seq']) || $_SESSION['list_mod_seq'] != $data['HIGHESTMODSEQ']) { + $flags = $RCMAIL->storage->list_flags($mbox_name, explode(',', $uids), $_SESSION['list_mod_seq']); + foreach ($flags as $idx => $row) { + $flags[$idx] = array_change_key_case(array_map('intval', $row)); + } + + // remember last HIGHESTMODSEQ value (if supported) + if (!empty($data['HIGHESTMODSEQ'])) { + $_SESSION['list_mod_seq'] = $data['HIGHESTMODSEQ']; + } + + $RCMAIL->output->set_env('recent_flags', $flags); + } + } + + // set trash folder state + if ($mbox_name === $trash) { + $OUTPUT->command('set_trash_count', $RCMAIL->storage->count($mbox_name, 'EXISTS')); + } } // trigger refresh hook diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index dc2452506..db001d54e 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -5,7 +5,7 @@ | program/steps/mail/compose.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2012, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -26,7 +26,7 @@ define('RCUBE_COMPOSE_DRAFT', 'draft'); define('RCUBE_COMPOSE_EDIT', 'edit'); $MESSAGE_FORM = null; -$COMPOSE_ID = get_input_value('_id', RCUBE_INPUT_GET); +$COMPOSE_ID = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GET); $COMPOSE = null; if ($COMPOSE_ID && $_SESSION['compose_data_'.$COMPOSE_ID]) @@ -35,73 +35,74 @@ if ($COMPOSE_ID && $_SESSION['compose_data_'.$COMPOSE_ID]) // give replicated session storage some time to synchronize $retries = 0; while ($COMPOSE_ID && !is_array($COMPOSE) && $RCMAIL->db->is_replicated() && $retries++ < 5) { - usleep(500000); - $RCMAIL->session->reload(); - if ($_SESSION['compose_data_'.$COMPOSE_ID]) - $COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; + usleep(500000); + $RCMAIL->session->reload(); + if ($_SESSION['compose_data_'.$COMPOSE_ID]) { + $COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; + } } // Nothing below is called during message composition, only at "new/forward/reply/draft" initialization or // if a compose-ID is given (i.e. when the compose step is opened in a new window/tab). -if (!is_array($COMPOSE)) -{ - // Infinite redirect prevention in case of broken session (#1487028) - if ($COMPOSE_ID) - raise_error(array('code' => 500, 'type' => 'php', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Invalid compose ID"), true, true); - - $COMPOSE_ID = uniqid(mt_rand()); - $_SESSION['compose_data_'.$COMPOSE_ID] = array( - 'id' => $COMPOSE_ID, - 'param' => rcube_utils::request2param(RCUBE_INPUT_GET, 'task|action', true), - 'mailbox' => $RCMAIL->storage->get_folder(), - ); - $COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; +if (!is_array($COMPOSE)) { + // Infinite redirect prevention in case of broken session (#1487028) + if ($COMPOSE_ID) { + rcube::raise_error(array('code' => 500, 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Invalid compose ID"), true, true); + } - rcmail_process_compose_params($COMPOSE); - - // add attachments listed by message_compose hook - if (is_array($plugin['attachments'])) { - foreach ($plugin['attachments'] as $attach) { - // we have structured data - if (is_array($attach)) { - $attachment = $attach; - } - // only a file path is given - else { - $filename = basename($attach); - $attachment = array( - 'group' => $COMPOSE_ID, - 'name' => $filename, - 'mimetype' => rc_mime_content_type($attach, $filename), - 'path' => $attach, - ); - } - - // save attachment if valid - if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) { - $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); - } - - if ($attachment['status'] && !$attachment['abort']) { - unset($attachment['data'], $attachment['status'], $attachment['abort']); - $COMPOSE['attachments'][$attachment['id']] = $attachment; - } - } - } - - // check if folder for saving sent messages exists and is subscribed (#1486802) - if ($sent_folder = $COMPOSE['param']['sent_mbox']) { - rcmail_check_sent_folder($sent_folder, true); - } - - // redirect to a unique URL with all parameters stored in session - $OUTPUT->redirect(array( - '_action' => 'compose', - '_id' => $COMPOSE['id'], - '_search' => $_REQUEST['_search'], - )); + $COMPOSE_ID = uniqid(mt_rand()); + $_SESSION['compose_data_'.$COMPOSE_ID] = array( + 'id' => $COMPOSE_ID, + 'param' => rcube_utils::request2param(rcube_utils::INPUT_GET, 'task|action', true), + 'mailbox' => $RCMAIL->storage->get_folder(), + ); + $COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; + + rcmail_process_compose_params($COMPOSE); + + // add attachments listed by message_compose hook + if (is_array($plugin['attachments'])) { + foreach ($plugin['attachments'] as $attach) { + // we have structured data + if (is_array($attach)) { + $attachment = $attach; + } + // only a file path is given + else { + $filename = basename($attach); + $attachment = array( + 'group' => $COMPOSE_ID, + 'name' => $filename, + 'mimetype' => rcube_mime::file_content_type($attach, $filename), + 'path' => $attach, + ); + } + + // save attachment if valid + if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) { + $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); + } + + if ($attachment['status'] && !$attachment['abort']) { + unset($attachment['data'], $attachment['status'], $attachment['abort']); + $COMPOSE['attachments'][$attachment['id']] = $attachment; + } + } + } + + // check if folder for saving sent messages exists and is subscribed (#1486802) + if ($sent_folder = $COMPOSE['param']['sent_mbox']) { + rcmail_check_sent_folder($sent_folder, true); + } + + // redirect to a unique URL with all parameters stored in session + $OUTPUT->redirect(array( + '_action' => 'compose', + '_id' => $COMPOSE['id'], + '_search' => $_REQUEST['_search'], + )); } @@ -109,147 +110,165 @@ if (!is_array($COMPOSE)) $OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning', 'cancel', 'nobodywarning', 'notsentwarning', 'notuploadedwarning', 'savingmessage', 'sendingmessage', 'messagesaved', 'converting', 'editorwarning', 'searching', 'uploading', 'uploadingmany', - 'fileuploaderror', 'sendmessage'); + 'fileuploaderror', 'sendmessage', 'savenewresponse', 'responsename', 'responsetext', 'save', + 'savingresponse', 'restoresavedcomposedata', 'restoremessage', 'delete', 'restore', 'ignore'); -$OUTPUT->set_env('compose_id', $COMPOSE['id']); -$OUTPUT->set_pagetitle(rcube_label('compose')); +$OUTPUT->set_pagetitle($RCMAIL->gettext('compose')); -// add config parameters to client script -if (!empty($CONFIG['drafts_mbox'])) { - $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']); - $OUTPUT->set_env('draft_autosave', $CONFIG['draft_autosave']); -} -// set current mailbox in client environment +$OUTPUT->set_env('compose_id', $COMPOSE['id']); +$OUTPUT->set_env('session_id', session_id()); $OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder()); $OUTPUT->set_env('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0); $OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ','))); +$drafts_mbox = $RCMAIL->config->get('drafts_mbox'); +$config_show_sig = $RCMAIL->config->get('show_sig', 1); + +// add config parameters to client script +if (strlen($drafts_mbox)) { + $OUTPUT->set_env('drafts_mailbox', $drafts_mbox); + $OUTPUT->set_env('draft_autosave', $RCMAIL->config->get('draft_autosave')); +} + // default font for HTML editor -$font = rcube_fontdefs($RCMAIL->config->get('default_font')); +$font = rcmail::font_defs($RCMAIL->config->get('default_font')); if ($font && !is_array($font)) { - $OUTPUT->set_env('default_font', $font); + $OUTPUT->set_env('default_font', $font); } // default font size for HTML editor if ($font_size = $RCMAIL->config->get('default_font_size')) { - $OUTPUT->set_env('default_font_size', $font_size); + $OUTPUT->set_env('default_font_size', $font_size); } // get reference message and set compose mode if ($msg_uid = $COMPOSE['param']['draft_uid']) { - $compose_mode = RCUBE_COMPOSE_DRAFT; - $OUTPUT->set_env('draft_id', $msg_uid); - $RCMAIL->storage->set_folder($CONFIG['drafts_mbox']); + $compose_mode = RCUBE_COMPOSE_DRAFT; + $OUTPUT->set_env('draft_id', $msg_uid); + $RCMAIL->storage->set_folder($drafts_mbox); } else if ($msg_uid = $COMPOSE['param']['reply_uid']) { - $compose_mode = RCUBE_COMPOSE_REPLY; + $compose_mode = RCUBE_COMPOSE_REPLY; } else if ($msg_uid = $COMPOSE['param']['forward_uid']) { - $compose_mode = RCUBE_COMPOSE_FORWARD; - $COMPOSE['forward_uid'] = $msg_uid; - $COMPOSE['as_attachment'] = !empty($COMPOSE['param']['attachment']); + $compose_mode = RCUBE_COMPOSE_FORWARD; + $COMPOSE['forward_uid'] = $msg_uid; + $COMPOSE['as_attachment'] = !empty($COMPOSE['param']['attachment']); } else if ($msg_uid = $COMPOSE['param']['uid']) { - $compose_mode = RCUBE_COMPOSE_EDIT; + $compose_mode = RCUBE_COMPOSE_EDIT; } $COMPOSE['mode'] = $compose_mode; $OUTPUT->set_env('compose_mode', $compose_mode); -$config_show_sig = $RCMAIL->config->get('show_sig', 1); if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) { - // don't add signature in draft/edit mode, we'll also not remove the old-one - // but only on page display, later we should be able to change identity/sig (#1489229) - if ($config_show_sig == 1 || $config_show_sig == 2) - $OUTPUT->set_env('show_sig_later', true); + // don't add signature in draft/edit mode, we'll also not remove the old-one + // but only on page display, later we should be able to change identity/sig (#1489229) + if ($config_show_sig == 1 || $config_show_sig == 2) { + $OUTPUT->set_env('show_sig_later', true); + } } else if ($config_show_sig == 1) - $OUTPUT->set_env('show_sig', true); + $OUTPUT->set_env('show_sig', true); else if ($config_show_sig == 2 && empty($compose_mode)) - $OUTPUT->set_env('show_sig', true); + $OUTPUT->set_env('show_sig', true); else if ($config_show_sig == 3 && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD)) - $OUTPUT->set_env('show_sig', true); + $OUTPUT->set_env('show_sig', true); // set line length for body wrapping $LINE_LENGTH = $RCMAIL->config->get('line_length', 72); -if (!empty($msg_uid) && empty($COMPOSE['as_attachment'])) -{ - $mbox_name = $RCMAIL->storage->get_folder(); - - // set format before rcube_message construction - // use the same format as for the message view - if (isset($_SESSION['msg_formats'][$mbox_name.':'.$msg_uid])) { - $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$msg_uid]); - } - else { - $prefer_html = $CONFIG['prefer_html'] || $CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT; - $RCMAIL->config->set('prefer_html', $prefer_html); - } - - $MESSAGE = new rcube_message($msg_uid); - - // make sure message is marked as read - if ($MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) - $RCMAIL->storage->set_flag($msg_uid, 'SEEN'); - - if (!empty($MESSAGE->headers->charset)) - $RCMAIL->storage->set_charset($MESSAGE->headers->charset); - - if (!$MESSAGE->headers) { - // error - } - else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - $COMPOSE['reply_uid'] = $msg_uid; - $COMPOSE['reply_msgid'] = $MESSAGE->headers->messageID; - $COMPOSE['references'] = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID); - - if (!empty($COMPOSE['param']['all'])) - $MESSAGE->reply_all = $COMPOSE['param']['all']; - - // Save the sent message in the same folder of the message being replied to - if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $COMPOSE['mailbox']) - && rcmail_check_sent_folder($sent_folder, false) - ) { - $COMPOSE['param']['sent_mbox'] = $sent_folder; +if (!empty($msg_uid) && empty($COMPOSE['as_attachment'])) { + $mbox_name = $RCMAIL->storage->get_folder(); + + // set format before rcube_message construction + // use the same format as for the message view + if (isset($_SESSION['msg_formats'][$mbox_name.':'.$msg_uid])) { + $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$msg_uid]); + } + else { + $prefer_html = $RCMAIL->config->get('prefer_html') || $RCMAIL->config->get('htmleditor') + || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT; + + $RCMAIL->config->set('prefer_html', $prefer_html); + } + + $MESSAGE = new rcube_message($msg_uid); + + // make sure message is marked as read + if ($MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) { + $RCMAIL->storage->set_flag($msg_uid, 'SEEN'); + } + + if (!empty($MESSAGE->headers->charset)) { + $RCMAIL->storage->set_charset($MESSAGE->headers->charset); } - } - else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { - if ($compose_mode == RCUBE_COMPOSE_DRAFT && ($draft_info = $MESSAGE->headers->get('x-draft-info'))) { - // get reply_uid/forward_uid to flag the original message when sending - $info = rcmail_draftinfo_decode($draft_info); - if ($info['type'] == 'reply') - $COMPOSE['reply_uid'] = $info['uid']; - else if ($info['type'] == 'forward') - $COMPOSE['forward_uid'] = $info['uid']; + if (!$MESSAGE->headers) { + // error + } + else if ($compose_mode == RCUBE_COMPOSE_REPLY) { + $COMPOSE['reply_uid'] = $msg_uid; + $COMPOSE['reply_msgid'] = $MESSAGE->headers->messageID; + $COMPOSE['references'] = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID); - $COMPOSE['mailbox'] = $info['folder']; + if (!empty($COMPOSE['param']['all'])) { + $MESSAGE->reply_all = $COMPOSE['param']['all']; + } - // Save the sent message in the same folder of the message being replied to - if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $info['folder']) - && rcmail_check_sent_folder($sent_folder, false) - ) { - $COMPOSE['param']['sent_mbox'] = $sent_folder; - } + // Save the sent message in the same folder of the message being replied to + if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $COMPOSE['mailbox']) + && rcmail_check_sent_folder($sent_folder, false) + ) { + $COMPOSE['param']['sent_mbox'] = $sent_folder; + } } + else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { + if ($compose_mode == RCUBE_COMPOSE_DRAFT) { + if ($draft_info = $MESSAGE->headers->get('x-draft-info')) { + // get reply_uid/forward_uid to flag the original message when sending + $info = rcmail_draftinfo_decode($draft_info); + + if ($info['type'] == 'reply') + $COMPOSE['reply_uid'] = $info['uid']; + else if ($info['type'] == 'forward') + $COMPOSE['forward_uid'] = $info['uid']; + + $COMPOSE['mailbox'] = $info['folder']; + + // Save the sent message in the same folder of the message being replied to + if ($RCMAIL->config->get('reply_same_folder') && ($sent_folder = $info['folder']) + && rcmail_check_sent_folder($sent_folder, false) + ) { + $COMPOSE['param']['sent_mbox'] = $sent_folder; + } + } - if ($in_reply_to = $MESSAGE->headers->get('in-reply-to')) - $COMPOSE['reply_msgid'] = '<' . $in_reply_to . '>'; + $COMPOSE['param']['message-id'] = $MESSAGE->headers->get('message-id'); - $COMPOSE['references'] = $MESSAGE->headers->references; - } + // use message UID as draft_id + $OUTPUT->set_env('draft_id', $msg_uid); + } + + if ($in_reply_to = $MESSAGE->headers->get('in-reply-to')) { + $COMPOSE['reply_msgid'] = '<' . $in_reply_to . '>'; + } + + $COMPOSE['references'] = $MESSAGE->headers->references; + } } else { - $MESSAGE = new stdClass(); - - // apply mailto: URL parameters - if (!empty($COMPOSE['param']['in-reply-to'])) { - $COMPOSE['reply_msgid'] = '<' . $COMPOSE['param']['in-reply-to'] . '>'; - } - if (!empty($COMPOSE['param']['references'])) { - $COMPOSE['references'] = $COMPOSE['param']['references']; - } + $MESSAGE = new stdClass(); + + // apply mailto: URL parameters + if (!empty($COMPOSE['param']['in-reply-to'])) { + $COMPOSE['reply_msgid'] = '<' . $COMPOSE['param']['in-reply-to'] . '>'; + } + + if (!empty($COMPOSE['param']['references'])) { + $COMPOSE['references'] = $COMPOSE['param']['references']; + } } $MESSAGE->compose = array(); @@ -259,142 +278,141 @@ $MESSAGE->identities = $RCMAIL->user->list_identities(null, true); // Set From field value if (!empty($_POST['_from'])) { - $MESSAGE->compose['from'] = get_input_value('_from', RCUBE_INPUT_POST); + $MESSAGE->compose['from'] = rcube_utils::get_input_value('_from', rcube_utils::INPUT_POST); } else if (!empty($COMPOSE['param']['from'])) { - $MESSAGE->compose['from'] = $COMPOSE['param']['from']; + $MESSAGE->compose['from'] = $COMPOSE['param']['from']; } else if (count($MESSAGE->identities)) { - $ident = rcmail_identity_select($MESSAGE, $MESSAGE->identities, $compose_mode); + $ident = rcmail_identity_select($MESSAGE, $MESSAGE->identities, $compose_mode); - $MESSAGE->compose['from_email'] = $ident['email']; - $MESSAGE->compose['from'] = $ident['identity_id']; + $MESSAGE->compose['from_email'] = $ident['email']; + $MESSAGE->compose['from'] = $ident['identity_id']; } // Set other headers $a_recipients = array(); $parts = array('to', 'cc', 'bcc', 'replyto', 'followupto'); $separator = trim($RCMAIL->config->get('recipients_separator', ',')) . ' '; +$from_email = @mb_strtolower($MESSAGE->compose['from_email']); foreach ($parts as $header) { - $fvalue = ''; - $decode_header = true; - - // we have a set of recipients stored is session - if ($header == 'to' && ($mailto_id = $COMPOSE['param']['mailto']) - && $_SESSION['mailto'][$mailto_id] - ) { - $fvalue = urldecode($_SESSION['mailto'][$mailto_id]); - $decode_header = false; - - // make session to not grow up too much - unset($_SESSION['mailto'][$mailto_id]); - $COMPOSE['param']['to'] = $fvalue; - } - else if (!empty($_POST['_'.$header])) { - $fvalue = get_input_value('_'.$header, RCUBE_INPUT_POST, TRUE); - } - else if (!empty($COMPOSE['param'][$header])) { - $fvalue = $COMPOSE['param'][$header]; - } - else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - // get recipent address(es) out of the message headers - if ($header == 'to') { - $mailfollowup = $MESSAGE->headers->others['mail-followup-to']; - $mailreplyto = $MESSAGE->headers->others['mail-reply-to']; - - // Reply to mailing list... - if ($MESSAGE->reply_all == 'list' && $mailfollowup) - $fvalue = $mailfollowup; - else if ($MESSAGE->reply_all == 'list' - && preg_match('/<mailto:([^>]+)>/i', $MESSAGE->headers->others['list-post'], $m)) - $fvalue = $m[1]; - // Reply to... - else if ($MESSAGE->reply_all && $mailfollowup) - $fvalue = $mailfollowup; - else if ($mailreplyto) - $fvalue = $mailreplyto; - else if (!empty($MESSAGE->headers->replyto)) - $fvalue = $MESSAGE->headers->replyto; - else if (!empty($MESSAGE->headers->from)) - $fvalue = $MESSAGE->headers->from; - - // Reply to message sent by yourself (#1487074, #1489230) - if (!empty($ident) && in_array($ident['ident'], array($fvalue, $MESSAGE->headers->from))) { - $fvalue = $MESSAGE->headers->to; - } - } - // add recipient of original message if reply to all - else if ($header == 'cc' && !empty($MESSAGE->reply_all) && $MESSAGE->reply_all != 'list') { - if ($v = $MESSAGE->headers->to) - $fvalue .= $v; - if ($v = $MESSAGE->headers->cc) - $fvalue .= (!empty($fvalue) ? $separator : '') . $v; - // Use Sender header (#1489011) - if (($v = $MESSAGE->headers->get('Sender', false)) && strpos($v, '-bounces@') === false) - $fvalue .= (!empty($fvalue) ? $separator : '') . $v; - - // When To: and Reply-To: are the same we add From: address to the list (#1489037) - if ($v = $MESSAGE->headers->from) { - $from = rcube_mime::decode_address_list($v, null, false, $MESSAGE->headers->charset, true); - $to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, false, $MESSAGE->headers->charset, true); - $replyto = rcube_mime::decode_address_list($MESSAGE->headers->replyto, null, false, $MESSAGE->headers->charset, true); - - if (count($replyto) && !count(array_diff($to, $replyto)) && count(array_diff($from, $to))) { - $fvalue .= (!empty($fvalue) ? $separator : '') . $v; - } - } - } - } - else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { - // get drafted headers - if ($header=='to' && !empty($MESSAGE->headers->to)) - $fvalue = $MESSAGE->get_header('to', true); - else if ($header=='cc' && !empty($MESSAGE->headers->cc)) - $fvalue = $MESSAGE->get_header('cc', true); - else if ($header=='bcc' && !empty($MESSAGE->headers->bcc)) - $fvalue = $MESSAGE->get_header('bcc', true); - else if ($header=='replyto' && !empty($MESSAGE->headers->others['mail-reply-to'])) - $fvalue = $MESSAGE->get_header('mail-reply-to'); - else if ($header=='replyto' && !empty($MESSAGE->headers->replyto)) - $fvalue = $MESSAGE->get_header('reply-to'); - else if ($header=='followupto' && !empty($MESSAGE->headers->others['mail-followup-to'])) - $fvalue = $MESSAGE->get_header('mail-followup-to'); - } - - // split recipients and put them back together in a unique way - if (!empty($fvalue) && in_array($header, array('to', 'cc', 'bcc'))) { - $to_addresses = rcube_mime::decode_address_list($fvalue, null, $decode_header, $MESSAGE->headers->charset); - $fvalue = array(); - - foreach ($to_addresses as $addr_part) { - if (empty($addr_part['mailto'])) - continue; - - $mailto = format_email(rcube_idn_to_utf8($addr_part['mailto'])); - - if (!in_array($mailto, $a_recipients) - && ( - $header == 'to' - || $compose_mode != RCUBE_COMPOSE_REPLY - || empty($MESSAGE->compose['from_email']) - || $mailto != $MESSAGE->compose['from_email'] - ) - ) { - if ($addr_part['name'] && $addr_part['mailto'] != $addr_part['name']) - $string = format_email_recipient($mailto, $addr_part['name']); - else - $string = $mailto; + $fvalue = ''; + $decode_header = true; + + // we have a set of recipients stored is session + if ($header == 'to' && ($mailto_id = $COMPOSE['param']['mailto']) + && $_SESSION['mailto'][$mailto_id] + ) { + $fvalue = urldecode($_SESSION['mailto'][$mailto_id]); + $decode_header = false; - $fvalue[] = $string; - $a_recipients[] = $addr_part['mailto']; - } + // make session to not grow up too much + unset($_SESSION['mailto'][$mailto_id]); + $COMPOSE['param']['to'] = $fvalue; + } + else if (!empty($_POST['_'.$header])) { + $fvalue = rcube_utils::get_input_value('_'.$header, rcube_utils::INPUT_POST, TRUE); + } + else if (!empty($COMPOSE['param'][$header])) { + $fvalue = $COMPOSE['param'][$header]; } + else if ($compose_mode == RCUBE_COMPOSE_REPLY) { + // get recipent address(es) out of the message headers + if ($header == 'to') { + $mailfollowup = $MESSAGE->headers->others['mail-followup-to']; + $mailreplyto = $MESSAGE->headers->others['mail-reply-to']; + + // Reply to mailing list... + if ($MESSAGE->reply_all == 'list' && $mailfollowup) + $fvalue = $mailfollowup; + else if ($MESSAGE->reply_all == 'list' + && preg_match('/<mailto:([^>]+)>/i', $MESSAGE->headers->others['list-post'], $m)) + $fvalue = $m[1]; + // Reply to... + else if ($MESSAGE->reply_all && $mailfollowup) + $fvalue = $mailfollowup; + else if ($mailreplyto) + $fvalue = $mailreplyto; + else if (!empty($MESSAGE->headers->replyto)) + $fvalue = $MESSAGE->headers->replyto; + else if (!empty($MESSAGE->headers->from)) + $fvalue = $MESSAGE->headers->from; + + // Reply to message sent by yourself (#1487074, #1489230) + if (!empty($ident) && in_array($ident['ident'], array($fvalue, $MESSAGE->headers->from))) { + $fvalue = $MESSAGE->headers->to; + } + } + // add recipient of original message if reply to all + else if ($header == 'cc' && !empty($MESSAGE->reply_all) && $MESSAGE->reply_all != 'list') { + if ($v = $MESSAGE->headers->to) + $fvalue .= $v; + if ($v = $MESSAGE->headers->cc) + $fvalue .= (!empty($fvalue) ? $separator : '') . $v; + // Use Sender header (#1489011) + if (($v = $MESSAGE->headers->get('Sender', false)) && strpos($v, '-bounces@') === false) + $fvalue .= (!empty($fvalue) ? $separator : '') . $v; + + // When To: and Reply-To: are the same we add From: address to the list (#1489037) + if ($v = $MESSAGE->headers->from) { + $from = rcube_mime::decode_address_list($v, null, false, $MESSAGE->headers->charset, true); + $to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, false, $MESSAGE->headers->charset, true); + $replyto = rcube_mime::decode_address_list($MESSAGE->headers->replyto, null, false, $MESSAGE->headers->charset, true); + + if (count($replyto) && !count(array_diff($to, $replyto)) && count(array_diff($from, $to))) { + $fvalue .= (!empty($fvalue) ? $separator : '') . $v; + } + } + } + } + else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { + // get drafted headers + if ($header=='to' && !empty($MESSAGE->headers->to)) + $fvalue = $MESSAGE->get_header('to', true); + else if ($header=='cc' && !empty($MESSAGE->headers->cc)) + $fvalue = $MESSAGE->get_header('cc', true); + else if ($header=='bcc' && !empty($MESSAGE->headers->bcc)) + $fvalue = $MESSAGE->get_header('bcc', true); + else if ($header=='replyto' && !empty($MESSAGE->headers->others['mail-reply-to'])) + $fvalue = $MESSAGE->get_header('mail-reply-to'); + else if ($header=='replyto' && !empty($MESSAGE->headers->replyto)) + $fvalue = $MESSAGE->get_header('reply-to'); + else if ($header=='followupto' && !empty($MESSAGE->headers->others['mail-followup-to'])) + $fvalue = $MESSAGE->get_header('mail-followup-to'); + } + + // split recipients and put them back together in a unique way + if (!empty($fvalue) && in_array($header, array('to', 'cc', 'bcc'))) { + $to_addresses = rcube_mime::decode_address_list($fvalue, null, $decode_header, $MESSAGE->headers->charset); + $fvalue = array(); - $fvalue = implode($separator, $fvalue); - } + foreach ($to_addresses as $addr_part) { + if (empty($addr_part['mailto'])) { + continue; + } - $MESSAGE->compose[$header] = $fvalue; + // According to RFC5321 local part of email address is case-sensitive + // however, here it is better to compare addresses in case-insensitive manner + $mailto = format_email(rcube_utils::idn_to_utf8($addr_part['mailto'])); + $mailto_lc = mb_strtolower($addr_part['mailto']); + + if (($header == 'to' || $compose_mode != RCUBE_COMPOSE_REPLY || $mailto_lc != $from_email) + && !in_array($mailto_lc, $a_recipients) + ) { + if ($addr_part['name'] && $mailto != $addr_part['name']) { + $mailto = format_email_recipient($mailto, $addr_part['name']); + } + + $fvalue[] = $mailto; + $a_recipients[] = $mailto_lc; + } + } + + $fvalue = implode($separator, $fvalue); + } + + $MESSAGE->compose[$header] = $fvalue; } unset($a_recipients); @@ -402,322 +420,354 @@ unset($a_recipients); $MESSAGE_BODY = rcmail_prepare_message_body(); +// register UI objects +$OUTPUT->add_handlers(array( + 'composeheaders' => 'rcmail_compose_headers', + 'composesubject' => 'rcmail_compose_subject', + 'composebody' => 'rcmail_compose_body', + 'composeattachmentlist' => 'rcmail_compose_attachment_list', + 'composeattachmentform' => 'rcmail_compose_attachment_form', + 'composeattachment' => 'rcmail_compose_attachment_field', + 'filedroparea' => 'compose_file_drop_area', + 'priorityselector' => 'rcmail_priority_selector', + 'editorselector' => 'rcmail_editor_selector', + 'receiptcheckbox' => 'rcmail_receipt_checkbox', + 'dsncheckbox' => 'rcmail_dsn_checkbox', + 'storetarget' => 'rcmail_store_target_selection', + 'addressbooks' => 'rcmail_addressbook_list', + 'addresslist' => 'rcmail_contacts_list', + 'responseslist' => 'rcmail_compose_responses_list', +)); + +$OUTPUT->send('compose'); + + /****** compose mode functions ********/ // process compose request parameters function rcmail_process_compose_params(&$COMPOSE) { - if ($COMPOSE['param']['to']) { - $mailto = explode('?', $COMPOSE['param']['to'], 2); + if ($COMPOSE['param']['to']) { + $mailto = explode('?', $COMPOSE['param']['to'], 2); - // #1486037: remove "mailto:" prefix - $COMPOSE['param']['to'] = preg_replace('/^mailto:/i', '', $mailto[0]); + // #1486037: remove "mailto:" prefix + $COMPOSE['param']['to'] = preg_replace('/^mailto:/i', '', $mailto[0]); - // Supported case-insensitive tokens in mailto URL - $url_tokens = array('to', 'cc', 'bcc', 'reply-to', 'in-reply-to', 'references', 'subject', 'body'); + // Supported case-insensitive tokens in mailto URL + $url_tokens = array('to', 'cc', 'bcc', 'reply-to', 'in-reply-to', 'references', 'subject', 'body'); - if (!empty($mailto[1])) { - parse_str($mailto[1], $query); - foreach ($query as $f => $val) { - if (($key = array_search(strtolower($f), $url_tokens)) !== false) { - $f = $url_tokens[$key]; - } + if (!empty($mailto[1])) { + parse_str($mailto[1], $query); + foreach ($query as $f => $val) { + if (($key = array_search(strtolower($f), $url_tokens)) !== false) { + $f = $url_tokens[$key]; + } - // merge mailto: addresses with addresses from 'to' parameter - if ($f == 'to' && !empty($COMPOSE['param']['to'])) { - $to_addresses = rcube_mime::decode_address_list($COMPOSE['param']['to'], null, true, null, true); - $add_addresses = rcube_mime::decode_address_list($val, null, true); - foreach ($add_addresses as $addr) { - if (!in_array($addr['mailto'], $to_addresses)) { - $to_addresses[] = $addr['mailto']; - $COMPOSE['param']['to'] = (!empty($to_addresses) ? ', ' : '') . $addr['string']; + // merge mailto: addresses with addresses from 'to' parameter + if ($f == 'to' && !empty($COMPOSE['param']['to'])) { + $to_addresses = rcube_mime::decode_address_list($COMPOSE['param']['to'], null, true, null, true); + $add_addresses = rcube_mime::decode_address_list($val, null, true); + + foreach ($add_addresses as $addr) { + if (!in_array($addr['mailto'], $to_addresses)) { + $to_addresses[] = $addr['mailto']; + $COMPOSE['param']['to'] = (!empty($to_addresses) ? ', ' : '') . $addr['string']; + } + } + } + else { + $COMPOSE['param'][$f] = $val; + } } - } - } - else { - $COMPOSE['param'][$f] = $val; } - } } - } - $RCMAIL = rcmail::get_instance(); + // clean HTML message body which can be submitted by URL + if (!empty($COMPOSE['param']['body'])) { + $COMPOSE['param']['body'] = rcmail_wash_html($COMPOSE['param']['body'], array('safe' => false, 'inline_html' => true), array()); + } + + $RCMAIL = rcmail::get_instance(); - // select folder where to save the sent message - $COMPOSE['param']['sent_mbox'] = $RCMAIL->config->get('sent_mbox'); + // select folder where to save the sent message + $COMPOSE['param']['sent_mbox'] = $RCMAIL->config->get('sent_mbox'); - // pipe compose parameters thru plugins - $plugin = $RCMAIL->plugins->exec_hook('message_compose', $COMPOSE); - $COMPOSE['param'] = array_merge($COMPOSE['param'], $plugin['param']); + // pipe compose parameters thru plugins + $plugin = $RCMAIL->plugins->exec_hook('message_compose', $COMPOSE); + $COMPOSE['param'] = array_merge($COMPOSE['param'], $plugin['param']); } function rcmail_compose_headers($attrib) { - global $MESSAGE; + global $RCMAIL, $MESSAGE; - list($form_start,) = get_form_tags($attrib); + list($form_start,) = get_form_tags($attrib); - $out = ''; - $part = strtolower($attrib['part']); + $out = ''; + $part = strtolower($attrib['part']); - switch ($part) - { + switch ($part) { case 'from': - return $form_start . rcmail_compose_header_from($attrib); + return $form_start . rcmail_compose_header_from($attrib); case 'to': case 'cc': case 'bcc': - $fname = '_' . $part; - $header = $param = $part; + $fname = '_' . $part; + $header = $param = $part; - $allow_attrib = array('id', 'class', 'style', 'cols', 'rows', 'tabindex'); - $field_type = 'html_textarea'; - break; + $allow_attrib = array('id', 'class', 'style', 'cols', 'rows', 'tabindex'); + $field_type = 'html_textarea'; + break; case 'replyto': case 'reply-to': - $fname = '_replyto'; - $param = 'replyto'; - $header = 'reply-to'; + $fname = '_replyto'; + $param = 'replyto'; + $header = 'reply-to'; case 'followupto': case 'followup-to': - if (!$fname) { - $fname = '_followupto'; - $param = 'followupto'; - $header = 'mail-followup-to'; - } - - $allow_attrib = array('id', 'class', 'style', 'size', 'tabindex'); - $field_type = 'html_inputfield'; - break; - } - - if ($fname && $field_type) - { - // pass the following attributes to the form class - $field_attrib = array('name' => $fname, 'spellcheck' => 'false'); - foreach ($attrib as $attr => $value) - if (in_array($attr, $allow_attrib)) - $field_attrib[$attr] = $value; + if (!$fname) { + $fname = '_followupto'; + $param = 'followupto'; + $header = 'mail-followup-to'; + } - // create teaxtarea object - $input = new $field_type($field_attrib); - $out = $input->show($MESSAGE->compose[$param]); - } + $allow_attrib = array('id', 'class', 'style', 'size', 'tabindex'); + $field_type = 'html_inputfield'; + break; + } - if ($form_start) - $out = $form_start.$out; + if ($fname && $field_type) { + // pass the following attributes to the form class + $field_attrib = array('name' => $fname, 'spellcheck' => 'false'); + foreach ($attrib as $attr => $value) { + if (in_array($attr, $allow_attrib)) { + $field_attrib[$attr] = $value; + } + } - // configure autocompletion - rcube_autocomplete_init(); + // create teaxtarea object + $input = new $field_type($field_attrib); + $out = $input->show($MESSAGE->compose[$param]); + } + + if ($form_start) { + $out = $form_start . $out; + } - return $out; + // configure autocompletion + $RCMAIL->autocomplete_init(); + + return $out; } function rcmail_compose_header_from($attrib) { - global $MESSAGE, $OUTPUT, $RCMAIL, $COMPOSE, $compose_mode; - - // pass the following attributes to the form class - $field_attrib = array('name' => '_from'); - foreach ($attrib as $attr => $value) - if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex'))) - $field_attrib[$attr] = $value; - - if (count($MESSAGE->identities)) - { - $a_signatures = array(); - $identities = array(); - $separator = intval($RCMAIL->config->get('reply_mode')) > 0 - && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- '; - - $field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)"; - $select_from = new html_select($field_attrib); - - // create SELECT element - foreach ($MESSAGE->identities as $sql_arr) - { - $identity_id = $sql_arr['identity_id']; - $select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $identity_id); - - // add signature to array - if (!empty($sql_arr['signature']) && empty($COMPOSE['param']['nosig'])) - { - $text = $html = $sql_arr['signature']; - - if ($sql_arr['html_signature']) { - $h2t = new rcube_html2text($sql_arr['signature'], false, false); - $text = trim($h2t->get_text()); - } - else { - $html = htmlentities($html, ENT_NOQUOTES, RCMAIL_CHARSET); - } + global $MESSAGE, $OUTPUT, $RCMAIL, $COMPOSE, $compose_mode; - if (!preg_match('/^--[ -]\r?\n/m', $text)) { - $text = $separator . "\n" . $text; - $html = $separator . "<br>" . $html; + // pass the following attributes to the form class + $field_attrib = array('name' => '_from'); + foreach ($attrib as $attr => $value) { + if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex'))) { + $field_attrib[$attr] = $value; } + } + + if (count($MESSAGE->identities)) { + $a_signatures = array(); + $identities = array(); + $separator = intval($RCMAIL->config->get('reply_mode')) > 0 + && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- '; + + $field_attrib['onchange'] = rcmail_output::JS_OBJECT_NAME.".change_identity(this)"; + $select_from = new html_select($field_attrib); + + // create SELECT element + foreach ($MESSAGE->identities as $sql_arr) { + $identity_id = $sql_arr['identity_id']; + $select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $identity_id); + + // add signature to array + if (!empty($sql_arr['signature']) && empty($COMPOSE['param']['nosig'])) { + $text = $html = $sql_arr['signature']; + + if ($sql_arr['html_signature']) { + $h2t = new rcube_html2text($sql_arr['signature'], false, false); + $text = trim($h2t->get_text()); + } + else { + $html = htmlentities($html, ENT_NOQUOTES, RCUBE_CHARSET); + } - if (!$sql_arr['html_signature']) { - $html = "<pre>" . $html . "</pre>"; + if (!preg_match('/^--[ -]\r?\n/m', $text)) { + $text = $separator . "\n" . $text; + $html = $separator . "<br>" . $html; + } + + if (!$sql_arr['html_signature']) { + $html = "<pre>" . $html . "</pre>"; + } + + $a_signatures[$identity_id]['text'] = $text; + $a_signatures[$identity_id]['html'] = $html; + } + + // add bcc and reply-to + if (!empty($sql_arr['reply-to'])) { + $identities[$identity_id]['replyto'] = $sql_arr['reply-to']; + } + if (!empty($sql_arr['bcc'])) { + $identities[$identity_id]['bcc'] = $sql_arr['bcc']; + } } - $a_signatures[$identity_id]['text'] = $text; - $a_signatures[$identity_id]['html'] = $html; - } - - // add bcc and reply-to - if (!empty($sql_arr['reply-to'])) { - $identities[$identity_id]['replyto'] = $sql_arr['reply-to']; - } - if (!empty($sql_arr['bcc'])) { - $identities[$identity_id]['bcc'] = $sql_arr['bcc']; - } - } - - $out = $select_from->show($MESSAGE->compose['from']); - - // add signatures to client - $OUTPUT->set_env('signatures', $a_signatures); - $OUTPUT->set_env('identities', $identities); - } - // no identities, display text input field - else { - $field_attrib['class'] = 'from_address'; - $input_from = new html_inputfield($field_attrib); - $out = $input_from->show($MESSAGE->compose['from']); - } - - return $out; + $out = $select_from->show($MESSAGE->compose['from']); + + // add signatures to client + $OUTPUT->set_env('signatures', $a_signatures); + $OUTPUT->set_env('identities', $identities); + } + // no identities, display text input field + else { + $field_attrib['class'] = 'from_address'; + $input_from = new html_inputfield($field_attrib); + $out = $input_from->show($MESSAGE->compose['from']); + } + + return $out; } function rcmail_compose_editor_mode() { - global $RCMAIL, $compose_mode; - static $useHtml; + global $RCMAIL, $compose_mode; + static $useHtml; - if ($useHtml !== null) - return $useHtml; + if ($useHtml !== null) { + return $useHtml; + } + + $html_editor = intval($RCMAIL->config->get('htmleditor')); + + if (isset($_POST['_is_html'])) { + $useHtml = !empty($_POST['_is_html']); + } + else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { + $useHtml = rcmail_message_is_html(); + } + else if ($compose_mode == RCUBE_COMPOSE_REPLY) { + $useHtml = ($html_editor == 1 || ($html_editor >= 2 && rcmail_message_is_html())); + } + else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { + $useHtml = ($html_editor == 1 || ($html_editor == 3 && rcmail_message_is_html())); + } + else { + $useHtml = ($html_editor == 1); + } - $html_editor = intval($RCMAIL->config->get('htmleditor')); - - if (isset($_POST['_is_html'])) { - $useHtml = !empty($_POST['_is_html']); - } - else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { - $useHtml = rcmail_message_is_html(); - } - else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - $useHtml = ($html_editor == 1 || ($html_editor >= 2 && rcmail_message_is_html())); - } - else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { - $useHtml = ($html_editor == 1 || ($html_editor == 3 && rcmail_message_is_html())); - } - else { - $useHtml = ($html_editor == 1); - } - - return $useHtml; + return $useHtml; } function rcmail_message_is_html() { global $RCMAIL, $MESSAGE; + return $RCMAIL->config->get('prefer_html') && ($MESSAGE instanceof rcube_message) && $MESSAGE->has_html_part(true); } function rcmail_prepare_message_body() { - global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $HTML_MODE; - - // use posted message body - if (!empty($_POST['_message'])) { - $body = get_input_value('_message', RCUBE_INPUT_POST, true); - $isHtml = (bool) get_input_value('_is_html', RCUBE_INPUT_POST); - } - else if ($COMPOSE['param']['body']) { - $body = $COMPOSE['param']['body']; - $isHtml = false; - } - // forward as attachment - else if ($compose_mode == RCUBE_COMPOSE_FORWARD && $COMPOSE['as_attachment']) { - $isHtml = rcmail_compose_editor_mode(); - $body = ''; - rcmail_write_forward_attachments(); - } - // reply/edit/draft/forward - else if ($compose_mode && ($compose_mode != RCUBE_COMPOSE_REPLY || intval($RCMAIL->config->get('reply_mode')) != -1)) { - $isHtml = rcmail_compose_editor_mode(); - $messages = array(); + global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $HTML_MODE; - if (!empty($MESSAGE->parts)) { - // collect IDs of message/rfc822 parts - if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) { - foreach ($MESSAGE->attachments as $part) { - if ($part->mimetype == 'message/rfc822') { - $messages[] = $part->mime_id; - } - } - } + // use posted message body + if (!empty($_POST['_message'])) { + $body = rcube_utils::get_input_value('_message', rcube_utils::INPUT_POST, true); + $isHtml = (bool) rcube_utils::get_input_value('_is_html', rcube_utils::INPUT_POST); + } + else if ($COMPOSE['param']['body']) { + $body = $COMPOSE['param']['body']; + $isHtml = (bool) $COMPOSE['param']['html']; + } + // forward as attachment + else if ($compose_mode == RCUBE_COMPOSE_FORWARD && $COMPOSE['as_attachment']) { + $isHtml = rcmail_compose_editor_mode(); + $body = ''; - foreach ($MESSAGE->parts as $part) { - // skip no-content and attachment parts (#1488557) - if ($part->type != 'content' || !$part->size || $MESSAGE->is_attachment($part)) { - continue; - } + rcmail_write_forward_attachments(); + } + // reply/edit/draft/forward + else if ($compose_mode && ($compose_mode != RCUBE_COMPOSE_REPLY || intval($RCMAIL->config->get('reply_mode')) != -1)) { + $isHtml = rcmail_compose_editor_mode(); + $messages = array(); + + if (!empty($MESSAGE->parts)) { + // collect IDs of message/rfc822 parts + if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) { + foreach ($MESSAGE->attachments as $part) { + if ($part->mimetype == 'message/rfc822') { + $messages[] = $part->mime_id; + } + } + } + + foreach ($MESSAGE->parts as $part) { + // skip no-content and attachment parts (#1488557) + if ($part->type != 'content' || !$part->size || $MESSAGE->is_attachment($part)) { + continue; + } - // skip all content parts inside the message/rfc822 part in DRAFT/EDIT mode - foreach ($messages as $mimeid) { - if (strpos($part->mime_id, $mimeid . '.') === 0) { - continue 2; - } + // skip all content parts inside the message/rfc822 part in DRAFT/EDIT mode + foreach ($messages as $mimeid) { + if (strpos($part->mime_id, $mimeid . '.') === 0) { + continue 2; + } + } + + if ($part_body = rcmail_compose_part_body($part, $isHtml)) { + $body .= ($body ? ($isHtml ? '<br/>' : "\n") : '') . $part_body; + } + } + } + else { + $body = rcmail_compose_part_body($MESSAGE, $isHtml); } - if ($part_body = rcmail_compose_part_body($part, $isHtml)) { - $body .= ($body ? ($isHtml ? '<br/>' : "\n") : '') . $part_body; + // compose reply-body + if ($compose_mode == RCUBE_COMPOSE_REPLY) + $body = rcmail_create_reply_body($body, $isHtml); + // forward message body inline + else if ($compose_mode == RCUBE_COMPOSE_FORWARD) + $body = rcmail_create_forward_body($body, $isHtml); + // load draft message body + else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) + $body = rcmail_create_draft_body($body, $isHtml); + } + else { // new message + $isHtml = rcmail_compose_editor_mode(); + } + + $plugin = $RCMAIL->plugins->exec_hook('message_compose_body', + array('body' => $body, 'html' => $isHtml, 'mode' => $compose_mode)); + + $body = $plugin['body']; + unset($plugin); + + // add blocked.gif attachment (#1486516) + if ($isHtml && preg_match('#<img src="\./program/resources/blocked\.gif"#', $body)) { + if ($attachment = rcmail_save_image('program/resources/blocked.gif', 'image/gif')) { + $COMPOSE['attachments'][$attachment['id']] = $attachment; + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); + $body = preg_replace('#\./program/resources/blocked\.gif#', $url, $body); } - } } - else { - $body = rcmail_compose_part_body($MESSAGE, $isHtml); - } - - // compose reply-body - if ($compose_mode == RCUBE_COMPOSE_REPLY) - $body = rcmail_create_reply_body($body, $isHtml); - // forward message body inline - else if ($compose_mode == RCUBE_COMPOSE_FORWARD) - $body = rcmail_create_forward_body($body, $isHtml); - // load draft message body - else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) - $body = rcmail_create_draft_body($body, $isHtml); - } - else { // new message - $isHtml = rcmail_compose_editor_mode(); - } - - $plugin = $RCMAIL->plugins->exec_hook('message_compose_body', - array('body' => $body, 'html' => $isHtml, 'mode' => $compose_mode)); - $body = $plugin['body']; - unset($plugin); - - // add blocked.gif attachment (#1486516) - if ($isHtml && preg_match('#<img src="\./program/resources/blocked\.gif"#', $body)) { - if ($attachment = rcmail_save_image('program/resources/blocked.gif', 'image/gif')) { - $COMPOSE['attachments'][$attachment['id']] = $attachment; - $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', - $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); - $body = preg_replace('#\./program/resources/blocked\.gif#', $url, $body); - } - } - - $HTML_MODE = $isHtml; - - return $body; + + $HTML_MODE = $isHtml; + + return $body; } function rcmail_compose_part_body($part, $isHtml = false) @@ -726,7 +776,7 @@ function rcmail_compose_part_body($part, $isHtml = false) // Check if we have enough memory to handle the message in it // #1487424: we need up to 10x more memory than the body - if (!rcmail_mem_check($part->size * 10)) { + if (!rcube_utils::mem_check($part->size * 10)) { return ''; } @@ -803,892 +853,903 @@ function rcmail_compose_part_body($part, $isHtml = false) function rcmail_compose_body($attrib) { - global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $HTML_MODE, $MESSAGE_BODY; + global $RCMAIL, $OUTPUT, $HTML_MODE, $MESSAGE_BODY; - list($form_start, $form_end) = get_form_tags($attrib); - unset($attrib['form']); + list($form_start, $form_end) = get_form_tags($attrib); + unset($attrib['form']); - if (empty($attrib['id'])) - $attrib['id'] = 'rcmComposeBody'; + if (empty($attrib['id'])) + $attrib['id'] = 'rcmComposeBody'; - $attrib['name'] = '_message'; + $attrib['name'] = '_message'; - $isHtml = $HTML_MODE; + $isHtml = $HTML_MODE; - $out = $form_start ? "$form_start\n" : ''; + $out = $form_start ? "$form_start\n" : ''; - $saveid = new html_hiddenfield(array('name' => '_draft_saveid', 'value' => $compose_mode==RCUBE_COMPOSE_DRAFT ? str_replace(array('<','>'), "", $MESSAGE->headers->messageID) : '')); - $out .= $saveid->show(); + $saveid = new html_hiddenfield(array('name' => '_draft_saveid', 'value' => $RCMAIL->output->get_env('draft_id'))); + $out .= $saveid->show(); - $drafttoggle = new html_hiddenfield(array('name' => '_draft', 'value' => 'yes')); - $out .= $drafttoggle->show(); + $drafttoggle = new html_hiddenfield(array('name' => '_draft', 'value' => 'yes')); + $out .= $drafttoggle->show(); - $msgtype = new html_hiddenfield(array('name' => '_is_html', 'value' => ($isHtml?"1":"0"))); - $out .= $msgtype->show(); + $msgtype = new html_hiddenfield(array('name' => '_is_html', 'value' => ($isHtml ? "1" : "0"))); + $out .= $msgtype->show(); - // If desired, set this textarea to be editable by TinyMCE - if ($isHtml) { - $MESSAGE_BODY = htmlentities($MESSAGE_BODY, ENT_NOQUOTES, RCMAIL_CHARSET); - $attrib['class'] = 'mce_editor'; - $attrib['is_escaped'] = true; - $textarea = new html_textarea($attrib); - $out .= $textarea->show($MESSAGE_BODY); - } - else { - $textarea = new html_textarea($attrib); - $out .= $textarea->show(''); - // quote plain text, inject into textarea - $table = get_html_translation_table(HTML_SPECIALCHARS); - $MESSAGE_BODY = strtr($MESSAGE_BODY, $table); - $out = substr($out, 0, -11) . $MESSAGE_BODY . '</textarea>'; - } + $framed = new html_hiddenfield(array('name' => '_framed', 'value' => '1')); + $out .= $framed->show(); - $out .= $form_end ? "\n$form_end" : ''; + // If desired, set this textarea to be editable by TinyMCE + if ($isHtml) { + $MESSAGE_BODY = htmlentities($MESSAGE_BODY, ENT_NOQUOTES, RCUBE_CHARSET); + $attrib['class'] = 'mce_editor'; + $attrib['is_escaped'] = true; + $textarea = new html_textarea($attrib); + $out .= $textarea->show($MESSAGE_BODY); + } + else { + $textarea = new html_textarea($attrib); + $out .= $textarea->show(''); - $OUTPUT->set_env('composebody', $attrib['id']); + // quote plain text, inject into textarea + $table = get_html_translation_table(HTML_SPECIALCHARS); + $MESSAGE_BODY = strtr($MESSAGE_BODY, $table); + $out = substr($out, 0, -11) . $MESSAGE_BODY . '</textarea>'; + } + + $out .= $form_end ? "\n$form_end" : ''; + + $OUTPUT->set_env('composebody', $attrib['id']); - // include HTML editor - rcube_html_editor(); + // include HTML editor + $RCMAIL->html_editor(); - // Set language list - if (!empty($CONFIG['enable_spellcheck'])) { - $engine = $RCMAIL->config->get('spellcheck_engine','googie'); - $dictionary = (bool) $RCMAIL->config->get('spellcheck_dictionary'); - $spellcheck_langs = (array) $RCMAIL->config->get('spellcheck_languages', - array('da'=>'Dansk', 'de'=>'Deutsch', 'en' => 'English', 'es'=>'Español', - 'fr'=>'Français', 'it'=>'Italiano', 'nl'=>'Nederlands', 'pl'=>'Polski', - 'pt'=>'Português', 'ru'=>'Русский', 'fi'=>'Suomi', 'sv'=>'Svenska')); + // Set language list + if ($RCMAIL->config->get('enable_spellcheck')) { + $engine = new rcube_spellchecker(); + $dictionary = (bool) $RCMAIL->config->get('spellcheck_dictionary'); + $spellcheck_langs = $engine->languages(); + $lang = $_SESSION['language']; - // googie works only with two-letter codes - if ($engine == 'googie') { - $lang = strtolower(substr($_SESSION['language'], 0, 2)); + // if not found in the list, try with two-letter code + if (!$spellcheck_langs[$lang]) { + $lang = strtolower(substr($lang, 0, 2)); + } + + if (!$spellcheck_langs[$lang]) { + $lang = 'en'; + } - $spellcheck_langs_googie = array(); - foreach ($spellcheck_langs as $key => $name) - $spellcheck_langs_googie[strtolower(substr($key,0,2))] = $name; - $spellcheck_langs = $spellcheck_langs_googie; + $OUTPUT->set_env('spell_langs', $spellcheck_langs); + $OUTPUT->set_env('spell_lang', $lang); + + $editor_lang_set = array(); + foreach ($spellcheck_langs as $key => $name) { + $editor_lang_set[] = ($key == $lang ? '+' : '') . rcube::JQ($name).'='.rcube::JQ($key); + } + + // include GoogieSpell + $OUTPUT->include_script('googiespell.js'); + $OUTPUT->add_script(sprintf( + "var googie = new GoogieSpell('%s/images/googiespell/','%s&lang=', %s);\n". + "googie.lang_chck_spell = \"%s\";\n". + "googie.lang_rsm_edt = \"%s\";\n". + "googie.lang_close = \"%s\";\n". + "googie.lang_revert = \"%s\";\n". + "googie.lang_no_error_found = \"%s\";\n". + "googie.lang_learn_word = \"%s\";\n". + "googie.setLanguages(%s);\n". + "googie.setCurrentLanguage('%s');\n". + "googie.setDecoration(false);\n". + "googie.decorateTextarea('%s');\n". + "%s.set_env('spellcheck', googie);", + $RCMAIL->output->get_skin_path(), + $RCMAIL->url(array('_task' => 'utils', '_action' => 'spell', '_remote' => 1)), + !empty($dictionary) ? 'true' : 'false', + rcube::JQ(rcube::Q($RCMAIL->gettext('checkspelling'))), + rcube::JQ(rcube::Q($RCMAIL->gettext('resumeediting'))), + rcube::JQ(rcube::Q($RCMAIL->gettext('close'))), + rcube::JQ(rcube::Q($RCMAIL->gettext('revertto'))), + rcube::JQ(rcube::Q($RCMAIL->gettext('nospellerrors'))), + rcube::JQ(rcube::Q($RCMAIL->gettext('addtodict'))), + rcube_output::json_serialize($spellcheck_langs), + $lang, + $attrib['id'], + rcmail_output::JS_OBJECT_NAME), 'foot'); + + $OUTPUT->add_label('checking'); + $OUTPUT->set_env('spellcheck_langs', join(',', $editor_lang_set)); } - else { - $lang = $_SESSION['language']; - - // if not found in the list, try with two-letter code - if (!$spellcheck_langs[$lang]) - $lang = strtolower(substr($lang, 0, 2)); - } - - if (!$spellcheck_langs[$lang]) - $lang = 'en'; - - $OUTPUT->set_env('spell_langs', $spellcheck_langs); - $OUTPUT->set_env('spell_lang', $lang); - - $editor_lang_set = array(); - foreach ($spellcheck_langs as $key => $name) { - $editor_lang_set[] = ($key == $lang ? '+' : '') . JQ($name).'='.JQ($key); - } - - // include GoogieSpell - $OUTPUT->include_script('googiespell.js'); - $OUTPUT->add_script(sprintf( - "var googie = new GoogieSpell('%s/images/googiespell/','%s&lang=', %s);\n". - "googie.lang_chck_spell = \"%s\";\n". - "googie.lang_rsm_edt = \"%s\";\n". - "googie.lang_close = \"%s\";\n". - "googie.lang_revert = \"%s\";\n". - "googie.lang_no_error_found = \"%s\";\n". - "googie.lang_learn_word = \"%s\";\n". - "googie.setLanguages(%s);\n". - "googie.setCurrentLanguage('%s');\n". - "googie.setDecoration(false);\n". - "googie.decorateTextarea('%s');\n". - "%s.set_env('spellcheck', googie);", - $RCMAIL->output->get_skin_path(), - $RCMAIL->url(array('_task' => 'utils', '_action' => 'spell', '_remote' => 1)), - !empty($dictionary) ? 'true' : 'false', - JQ(Q(rcube_label('checkspelling'))), - JQ(Q(rcube_label('resumeediting'))), - JQ(Q(rcube_label('close'))), - JQ(Q(rcube_label('revertto'))), - JQ(Q(rcube_label('nospellerrors'))), - JQ(Q(rcube_label('addtodict'))), - json_serialize($spellcheck_langs), - $lang, - $attrib['id'], - JS_OBJECT_NAME), 'foot'); - - $OUTPUT->add_label('checking'); - $OUTPUT->set_env('spellcheck_langs', join(',', $editor_lang_set)); - } - - $out .= "\n".'<iframe name="savetarget" src="program/resources/blank.gif" style="width:0;height:0;border:none;visibility:hidden;"></iframe>'; - - return $out; + + $out .= "\n".'<iframe name="savetarget" src="program/resources/blank.gif" style="width:0;height:0;border:none;visibility:hidden;"></iframe>'; + + return $out; } function rcmail_create_reply_body($body, $bodyIsHtml) { - global $RCMAIL, $MESSAGE, $LINE_LENGTH; - - // build reply prefix - $from = array_pop(rcube_mime::decode_address_list($MESSAGE->get_header('from'), 1, false, $MESSAGE->headers->charset)); - $prefix = rcube_label(array( - 'name' => 'mailreplyintro', - 'vars' => array( - 'date' => format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long')), - 'sender' => $from['name'] ? $from['name'] : rcube_idn_to_utf8($from['mailto']), - ) - )); - - if (!$bodyIsHtml) { - $body = preg_replace('/\r?\n/', "\n", $body); - $body = trim($body, "\n"); - - // soft-wrap and quote message text - $body = rcmail_wrap_and_quote($body, $LINE_LENGTH); - - $prefix .= "\n"; - $suffix = ''; - - if (intval($RCMAIL->config->get('reply_mode')) > 0) { // top-posting - $prefix = "\n\n\n" . $prefix; - } - } - else { - // save inline images to files - $cid_map = rcmail_write_inline_attachments($MESSAGE); - // set is_safe flag (we need this for html body washing) - rcmail_check_safe($MESSAGE); - // clean up html tags - $body = rcmail_wash_html($body, array('safe' => $MESSAGE->is_safe), $cid_map); - - // build reply (quote content) - $prefix = '<p>' . Q($prefix) . "</p>\n"; - $prefix .= '<blockquote>'; - - if (intval($RCMAIL->config->get('reply_mode')) > 0) { // top-posting - $prefix = '<br>' . $prefix; - $suffix = '</blockquote>'; + global $RCMAIL, $MESSAGE, $LINE_LENGTH; + + // build reply prefix + $from = array_pop(rcube_mime::decode_address_list($MESSAGE->get_header('from'), 1, false, $MESSAGE->headers->charset)); + $prefix = $RCMAIL->gettext(array( + 'name' => 'mailreplyintro', + 'vars' => array( + 'date' => $RCMAIL->format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long')), + 'sender' => $from['name'] ? $from['name'] : rcube_utils::idn_to_utf8($from['mailto']), + ) + )); + + if (!$bodyIsHtml) { + $body = preg_replace('/\r?\n/', "\n", $body); + $body = trim($body, "\n"); + + // soft-wrap and quote message text + $body = rcmail_wrap_and_quote($body, $LINE_LENGTH); + + $prefix .= "\n"; + $suffix = ''; + + if (intval($RCMAIL->config->get('reply_mode')) > 0) { // top-posting + $prefix = "\n\n\n" . $prefix; + } } else { - $suffix = '</blockquote><p></p>'; + // save inline images to files + $cid_map = rcmail_write_inline_attachments($MESSAGE); + // set is_safe flag (we need this for html body washing) + rcmail_check_safe($MESSAGE); + // clean up html tags + $body = rcmail_wash_html($body, array('safe' => $MESSAGE->is_safe), $cid_map); + + // build reply (quote content) + $prefix = '<p>' . rcube::Q($prefix) . "</p>\n"; + $prefix .= '<blockquote>'; + + if (intval($RCMAIL->config->get('reply_mode')) > 0) { // top-posting + $prefix = '<br>' . $prefix; + $suffix = '</blockquote>'; + } + else { + $suffix = '</blockquote><p></p>'; + } } - } - return $prefix.$body.$suffix; + return $prefix . $body . $suffix; } function rcmail_create_forward_body($body, $bodyIsHtml) { - global $RCMAIL, $MESSAGE, $COMPOSE; - - // add attachments - if (!isset($COMPOSE['forward_attachments']) && is_array($MESSAGE->mime_parts)) - $cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml); - - $date = format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long')); - - if (!$bodyIsHtml) { - $prefix = "\n\n\n-------- " . rcube_label('originalmessage') . " --------\n"; - $prefix .= rcube_label('subject') . ': ' . $MESSAGE->subject . "\n"; - $prefix .= rcube_label('date') . ': ' . $date . "\n"; - $prefix .= rcube_label('from') . ': ' . $MESSAGE->get_header('from') . "\n"; - $prefix .= rcube_label('to') . ': ' . $MESSAGE->get_header('to') . "\n"; - - if ($cc = $MESSAGE->headers->get('cc')) - $prefix .= rcube_label('cc') . ': ' . $cc . "\n"; - if (($replyto = $MESSAGE->headers->get('reply-to')) && $replyto != $MESSAGE->get_header('from')) - $prefix .= rcube_label('replyto') . ': ' . $replyto . "\n"; - - $prefix .= "\n"; - $body = trim($body, "\r\n"); - } - else { - // set is_safe flag (we need this for html body washing) - rcmail_check_safe($MESSAGE); - // clean up html tags - $body = rcmail_wash_html($body, array('safe' => $MESSAGE->is_safe), $cid_map); - - $prefix = sprintf( - "<br /><p>-------- " . rcube_label('originalmessage') . " --------</p>" . - "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody>" . - "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . - "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . - "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . - "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", - rcube_label('subject'), Q($MESSAGE->subject), - rcube_label('date'), Q($date), - rcube_label('from'), Q($MESSAGE->get_header('from'), 'replace'), - rcube_label('to'), Q($MESSAGE->get_header('to'), 'replace')); - - if ($cc = $MESSAGE->headers->get('cc')) - $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", - rcube_label('cc'), Q($cc, 'replace')); - - if (($replyto = $MESSAGE->headers->get('reply-to')) && $replyto != $MESSAGE->get_header('from')) - $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", - rcube_label('replyto'), Q($replyto, 'replace')); - - $prefix .= "</tbody></table><br>"; - } - - return $prefix.$body; + global $RCMAIL, $MESSAGE, $COMPOSE; + + // add attachments + if (!isset($COMPOSE['forward_attachments']) && is_array($MESSAGE->mime_parts)) { + $cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml); + } + + $date = $RCMAIL->format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long')); + + if (!$bodyIsHtml) { + $prefix = "\n\n\n-------- " . $RCMAIL->gettext('originalmessage') . " --------\n"; + $prefix .= $RCMAIL->gettext('subject') . ': ' . $MESSAGE->subject . "\n"; + $prefix .= $RCMAIL->gettext('date') . ': ' . $date . "\n"; + $prefix .= $RCMAIL->gettext('from') . ': ' . $MESSAGE->get_header('from') . "\n"; + $prefix .= $RCMAIL->gettext('to') . ': ' . $MESSAGE->get_header('to') . "\n"; + + if ($cc = $MESSAGE->headers->get('cc')) { + $prefix .= $RCMAIL->gettext('cc') . ': ' . $cc . "\n"; + } + if (($replyto = $MESSAGE->headers->get('reply-to')) && $replyto != $MESSAGE->get_header('from')) { + $prefix .= $RCMAIL->gettext('replyto') . ': ' . $replyto . "\n"; + } + + $prefix .= "\n"; + $body = trim($body, "\r\n"); + } + else { + // set is_safe flag (we need this for html body washing) + rcmail_check_safe($MESSAGE); + + // clean up html tags + $body = rcmail_wash_html($body, array('safe' => $MESSAGE->is_safe), $cid_map); + + $prefix = sprintf( + "<br /><p>-------- " . $RCMAIL->gettext('originalmessage') . " --------</p>" . + "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody>" . + "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . + "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . + "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . + "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", + $RCMAIL->gettext('subject'), rcube::Q($MESSAGE->subject), + $RCMAIL->gettext('date'), rcube::Q($date), + $RCMAIL->gettext('from'), rcube::Q($MESSAGE->get_header('from'), 'replace'), + $RCMAIL->gettext('to'), rcube::Q($MESSAGE->get_header('to'), 'replace')); + + if ($cc = $MESSAGE->headers->get('cc')) + $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", + $RCMAIL->gettext('cc'), rcube::Q($cc, 'replace')); + + if (($replyto = $MESSAGE->headers->get('reply-to')) && $replyto != $MESSAGE->get_header('from')) + $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", + $RCMAIL->gettext('replyto'), rcube::Q($replyto, 'replace')); + + $prefix .= "</tbody></table><br>"; + } + + return $prefix . $body; } function rcmail_create_draft_body($body, $bodyIsHtml) { - global $MESSAGE, $COMPOSE; + global $MESSAGE, $COMPOSE; - /** - * add attachments - * sizeof($MESSAGE->mime_parts can be 1 - e.g. attachment, but no text! - */ - if (empty($COMPOSE['forward_attachments']) - && is_array($MESSAGE->mime_parts) - && count($MESSAGE->mime_parts) > 0) - { - $cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml); - } + // add attachments + // sizeof($MESSAGE->mime_parts can be 1 - e.g. attachment, but no text! + if (empty($COMPOSE['forward_attachments']) + && is_array($MESSAGE->mime_parts) + && count($MESSAGE->mime_parts) > 0 + ) { + $cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml); + } - // clean up HTML tags - XSS prevention (#1489251) - if ($bodyIsHtml) { - $body = rcmail_wash_html($body, array('safe' => 1), $cid_map); + // clean up HTML tags - XSS prevention (#1489251) + if ($bodyIsHtml) { + $body = rcmail_wash_html($body, array('safe' => 1), $cid_map); - // remove comments (produced by washtml) - $body = preg_replace('/<!--[^>]+-->/', '', $body); + // remove comments (produced by washtml) + $body = preg_replace('/<!--[^>]+-->/', '', $body); - // replace cid with href in inline images links - if (!empty($cid_map)) { - $body = str_replace(array_keys($cid_map), array_values($cid_map), $body); + // replace cid with href in inline images links + if (!empty($cid_map)) { + $body = str_replace(array_keys($cid_map), array_values($cid_map), $body); + } } - } - return $body; + return $body; } function rcmail_remove_signature($body) { - global $RCMAIL; + global $RCMAIL; - $body = str_replace("\r\n", "\n", $body); - $len = strlen($body); - $sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15); + $body = str_replace("\r\n", "\n", $body); + $len = strlen($body); + $sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15); - while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) { - if ($sp == 0 || $body[$sp-1] == "\n") { - // do not touch blocks with more that X lines - if (substr_count($body, "\n", $sp) < $sig_max_lines) { - $body = substr($body, 0, max(0, $sp-1)); - } - break; + while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) { + if ($sp == 0 || $body[$sp-1] == "\n") { + // do not touch blocks with more that X lines + if (substr_count($body, "\n", $sp) < $sig_max_lines) { + $body = substr($body, 0, max(0, $sp-1)); + } + break; + } } - } - return $body; + return $body; } function rcmail_write_compose_attachments(&$message, $bodyIsHtml) { - global $RCMAIL, $COMPOSE, $compose_mode; - - $loaded_attachments = array(); - foreach ((array)$COMPOSE['attachments'] as $attachment) { - $loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment; - } - - $cid_map = array(); - $messages = array(); - - foreach ((array)$message->mime_parts as $pid => $part) - { - if ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename) { - // skip parts that aren't valid attachments - if ($part->ctype_primary == 'multipart' || $part->mimetype == 'application/ms-tnef') { - continue; - } - // skip message attachments in reply mode - if ($part->ctype_primary == 'message' && $compose_mode == RCUBE_COMPOSE_REPLY) { - continue; - } - // skip inline images when forwarding in text mode - if ($part->content_id && $part->disposition == 'inline' && !$bodyIsHtml && $compose_mode == RCUBE_COMPOSE_FORWARD) { - continue; - } - - // skip message/rfc822 attachments on forwards (#1489214) - // Thunderbird when forwarding in inline mode displays such attachments - // and skips any attachments from inside of such part, this however - // skipped e.g. images used in HTML body or other attachments. So, - // better to skip .eml attachments but not their content (included files). - if ($part->mimetype == 'message/rfc822') { - if ($compose_mode == RCUBE_COMPOSE_FORWARD) { - continue; - } - $messages[] = $part->mime_id; - } - else if ($compose_mode != RCUBE_COMPOSE_FORWARD) { - // skip attachments included in message/rfc822 attachment (#1486487) - foreach ($messages as $mimeid) - if (strpos($part->mime_id, $mimeid . '.') === 0) { - continue 2; - } - } - - if (($attachment = $loaded_attachments[rcmail_attachment_name($part) . $part->mimetype]) - || ($attachment = rcmail_save_attachment($message, $pid))) { - $COMPOSE['attachments'][$attachment['id']] = $attachment; - if ($bodyIsHtml && ($part->content_id || $part->content_location)) { - $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', - $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); - if ($part->content_id) - $cid_map['cid:'.$part->content_id] = $url; - else - $cid_map[$part->content_location] = $url; + global $RCMAIL, $COMPOSE, $compose_mode; + + $loaded_attachments = array(); + foreach ((array)$COMPOSE['attachments'] as $attachment) { + $loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment; + } + + $cid_map = array(); + $messages = array(); + + foreach ((array)$message->mime_parts as $pid => $part) { + if ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename) { + // skip parts that aren't valid attachments + if ($part->ctype_primary == 'multipart' || $part->mimetype == 'application/ms-tnef') { + continue; + } + + // skip message attachments in reply mode + if ($part->ctype_primary == 'message' && $compose_mode == RCUBE_COMPOSE_REPLY) { + continue; + } + + // skip inline images when forwarding in text mode + if ($part->content_id && $part->disposition == 'inline' && !$bodyIsHtml && $compose_mode == RCUBE_COMPOSE_FORWARD) { + continue; + } + + // skip message/rfc822 attachments on forwards (#1489214) + // Thunderbird when forwarding in inline mode displays such attachments + // and skips any attachments from inside of such part, this however + // skipped e.g. images used in HTML body or other attachments. So, + // better to skip .eml attachments but not their content (included files). + if ($part->mimetype == 'message/rfc822') { + if ($compose_mode == RCUBE_COMPOSE_FORWARD) { + continue; + } + $messages[] = $part->mime_id; + } + else if ($compose_mode != RCUBE_COMPOSE_FORWARD) { + // skip attachments included in message/rfc822 attachment (#1486487) + foreach ($messages as $mimeid) { + if (strpos($part->mime_id, $mimeid . '.') === 0) { + continue 2; + } + } + } + + if (($attachment = $loaded_attachments[rcmail_attachment_name($part) . $part->mimetype]) + || ($attachment = rcmail_save_attachment($message, $pid)) + ) { + $COMPOSE['attachments'][$attachment['id']] = $attachment; + + if ($bodyIsHtml && ($part->content_id || $part->content_location)) { + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); + + if ($part->content_id) + $cid_map['cid:'.$part->content_id] = $url; + else + $cid_map[$part->content_location] = $url; + } + } } - } } - } - $COMPOSE['forward_attachments'] = true; + $COMPOSE['forward_attachments'] = true; - return $cid_map; + return $cid_map; } function rcmail_write_inline_attachments(&$message) { - global $RCMAIL, $COMPOSE; - - $cid_map = array(); - foreach ((array)$message->mime_parts as $pid => $part) { - if (($part->content_id || $part->content_location) && $part->filename) { - if ($attachment = rcmail_save_attachment($message, $pid)) { - $COMPOSE['attachments'][$attachment['id']] = $attachment; - $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', - $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); - if ($part->content_id) - $cid_map['cid:'.$part->content_id] = $url; - else - $cid_map[$part->content_location] = $url; - } + global $RCMAIL, $COMPOSE; + + $cid_map = array(); + foreach ((array)$message->mime_parts as $pid => $part) { + if (($part->content_id || $part->content_location) && $part->filename) { + if ($attachment = rcmail_save_attachment($message, $pid)) { + $COMPOSE['attachments'][$attachment['id']] = $attachment; + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); + + if ($part->content_id) + $cid_map['cid:'.$part->content_id] = $url; + else + $cid_map[$part->content_location] = $url; + } + } } - } - return $cid_map; + return $cid_map; } // Creates attachment(s) from the forwarded message(s) function rcmail_write_forward_attachments() { - global $RCMAIL, $COMPOSE, $MESSAGE; + global $RCMAIL, $COMPOSE, $MESSAGE; - $storage = $RCMAIL->get_storage(); - $mem_limit = parse_bytes(ini_get('memory_limit')); - $curr_mem = function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024; // safe value: 16MB - $names = array(); + $storage = $RCMAIL->get_storage(); + $names = array(); - $loaded_attachments = array(); - foreach ((array)$COMPOSE['attachments'] as $attachment) { - $loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment; - } + $loaded_attachments = array(); + foreach ((array)$COMPOSE['attachments'] as $attachment) { + $loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment; + } - if ($COMPOSE['forward_uid'] == '*') { - $index = $storage->index(null, rcmail_sort_column(), rcmail_sort_order()); - $COMPOSE['forward_uid'] = $index->get(); - } - else { - $COMPOSE['forward_uid'] = explode(',', $COMPOSE['forward_uid']); - } + if ($COMPOSE['forward_uid'] == '*') { + $index = $storage->index(null, rcmail_sort_column(), rcmail_sort_order()); + $COMPOSE['forward_uid'] = $index->get(); + } + else { + $COMPOSE['forward_uid'] = explode(',', $COMPOSE['forward_uid']); + } - foreach ((array)$COMPOSE['forward_uid'] as $uid) { - $message = new rcube_message($uid); + foreach ((array)$COMPOSE['forward_uid'] as $uid) { + $message = new rcube_message($uid); - if (empty($message->headers)) { - continue; - } + if (empty($message->headers)) { + continue; + } - if (!empty($message->headers->charset)) { - $storage->set_charset($message->headers->charset); - } + if (!empty($message->headers->charset)) { + $storage->set_charset($message->headers->charset); + } - if (empty($MESSAGE->subject)) { - $MESSAGE->subject = $message->subject; - } + if (empty($MESSAGE->subject)) { + $MESSAGE->subject = $message->subject; + } - // generate (unique) attachment name - $name = strlen($message->subject) ? mb_substr($message->subject, 0, 64) : 'message_rfc822'; - if (!empty($names[$name])) { - $names[$name]++; - $name .= '_' . $names[$name]; - } - $names[$name] = 1; - $name .= '.eml'; + // generate (unique) attachment name + $name = strlen($message->subject) ? mb_substr($message->subject, 0, 64) : 'message_rfc822'; + if (!empty($names[$name])) { + $names[$name]++; + $name .= '_' . $names[$name]; + } + $names[$name] = 1; + $name .= '.eml'; - $data = $path = null; + $data = $path = null; - if (!empty($loaded_attachments[$name . 'message/rfc822'])) { - continue; + if (!empty($loaded_attachments[$name . 'message/rfc822'])) { + continue; + } + + // don't load too big attachments into memory + if (!rcube_utils::mem_check($message->size)) { + $temp_dir = unslashify($RCMAIL->config->get('temp_dir')); + $path = tempnam($temp_dir, 'rcmAttmnt'); + if ($fp = fopen($path, 'w')) { + $storage->get_raw_body($message->uid, $fp); + fclose($fp); + } + else { + return false; + } + } + else { + $data = $storage->get_raw_body($message->uid); + $curr_mem += $message->size; + } + + $attachment = array( + 'group' => $COMPOSE['id'], + 'name' => $name, + 'mimetype' => 'message/rfc822', + 'data' => $data, + 'path' => $path, + 'size' => $path ? filesize($path) : strlen($data), + ); + + $attachment = $RCMAIL->plugins->exec_hook('attachment_save', $attachment); + + if ($attachment['status']) { + unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); + $COMPOSE['attachments'][$attachment['id']] = $attachment; + } + else if ($path) { + @unlink($path); + } } +} + + +function rcmail_save_attachment(&$message, $pid) +{ + global $COMPOSE; + + $rcmail = rcmail::get_instance(); + $part = $message->mime_parts[$pid]; + $data = $path = null; // don't load too big attachments into memory - if ($mem_limit > 0 && $message->size > $mem_limit - $curr_mem) { - $temp_dir = unslashify($RCMAIL->config->get('temp_dir')); - $path = tempnam($temp_dir, 'rcmAttmnt'); - if ($fp = fopen($path, 'w')) { - $storage->get_raw_body($message->uid, $fp); - fclose($fp); - } - else { - return false; - } + if (!rcube_utils::mem_check($part->size)) { + $temp_dir = unslashify($rcmail->config->get('temp_dir')); + $path = tempnam($temp_dir, 'rcmAttmnt'); + + if ($fp = fopen($path, 'w')) { + $message->get_part_content($pid, $fp, true, 0, false); + fclose($fp); + } + else { + return false; + } } else { - $data = $storage->get_raw_body($message->uid); - $curr_mem += $message->size; + $data = $message->get_part_content($pid, null, true, 0, false); } + $mimetype = $part->ctype_primary . '/' . $part->ctype_secondary; + $filename = rcmail_attachment_name($part); + $attachment = array( - 'group' => $COMPOSE['id'], - 'name' => $name, - 'mimetype' => 'message/rfc822', - 'data' => $data, - 'path' => $path, - 'size' => $path ? filesize($path) : strlen($data), + 'group' => $COMPOSE['id'], + 'name' => $filename, + 'mimetype' => $mimetype, + 'content_id' => $part->content_id, + 'data' => $data, + 'path' => $path, + 'size' => $path ? filesize($path) : strlen($data), ); - $attachment = $RCMAIL->plugins->exec_hook('attachment_save', $attachment); + $attachment = $rcmail->plugins->exec_hook('attachment_save', $attachment); if ($attachment['status']) { - unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); - $COMPOSE['attachments'][$attachment['id']] = $attachment; + unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); + return $attachment; } else if ($path) { - @unlink($path); + @unlink($path); } - } -} - -function rcmail_save_attachment(&$message, $pid) -{ - global $COMPOSE; - - $rcmail = rcmail::get_instance(); - $part = $message->mime_parts[$pid]; - $mem_limit = parse_bytes(ini_get('memory_limit')); - $curr_mem = function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024; // safe value: 16MB - $data = $path = null; - - // don't load too big attachments into memory - if ($mem_limit > 0 && $part->size > $mem_limit - $curr_mem) { - $temp_dir = unslashify($rcmail->config->get('temp_dir')); - $path = tempnam($temp_dir, 'rcmAttmnt'); - if ($fp = fopen($path, 'w')) { - $message->get_part_content($pid, $fp); - fclose($fp); - } else - return false; - } else { - $data = $message->get_part_content($pid); - } - - $mimetype = $part->ctype_primary . '/' . $part->ctype_secondary; - $filename = rcmail_attachment_name($part); - - $attachment = array( - 'group' => $COMPOSE['id'], - 'name' => $filename, - 'mimetype' => $mimetype, - 'content_id' => $part->content_id, - 'data' => $data, - 'path' => $path, - 'size' => $path ? filesize($path) : strlen($data), - ); - - $attachment = $rcmail->plugins->exec_hook('attachment_save', $attachment); - - if ($attachment['status']) { - unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); - return $attachment; - } else if ($path) { - @unlink($path); - } - - return false; + return false; } function rcmail_save_image($path, $mimetype='') { - global $COMPOSE; + global $COMPOSE; - // handle attachments in memory - $data = file_get_contents($path); - $name = rcmail_basename($path); + // handle attachments in memory + $data = file_get_contents($path); + $name = rcmail_basename($path); - $attachment = array( - 'group' => $COMPOSE['id'], - 'name' => $name, - 'mimetype' => $mimetype ? $mimetype : rc_mime_content_type($path, $name), - 'data' => $data, - 'size' => strlen($data), - ); + $attachment = array( + 'group' => $COMPOSE['id'], + 'name' => $name, + 'mimetype' => $mimetype ? $mimetype : rcube_mime::file_content_type($path, $name), + 'data' => $data, + 'size' => strlen($data), + ); - $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); + $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); - if ($attachment['status']) { - unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); - return $attachment; - } + if ($attachment['status']) { + unset($attachment['data'], $attachment['status'], $attachment['content_id'], $attachment['abort']); + return $attachment; + } - return false; + return false; } function rcmail_basename($filename) { - // basename() is not unicode safe and locale dependent - if (stristr(PHP_OS, 'win') || stristr(PHP_OS, 'netware')) { - return preg_replace('/^.*[\\\\\\/]/', '', $filename); - } else { - return preg_replace('/^.*[\/]/', '', $filename); - } + // basename() is not unicode safe and locale dependent + if (stristr(PHP_OS, 'win') || stristr(PHP_OS, 'netware')) { + return preg_replace('/^.*[\\\\\\/]/', '', $filename); + } + else { + return preg_replace('/^.*[\/]/', '', $filename); + } } function rcmail_compose_subject($attrib) { - global $MESSAGE, $COMPOSE, $compose_mode; + global $MESSAGE, $COMPOSE, $compose_mode; - list($form_start, $form_end) = get_form_tags($attrib); - unset($attrib['form']); + list($form_start, $form_end) = get_form_tags($attrib); + unset($attrib['form']); - $attrib['name'] = '_subject'; - $attrib['spellcheck'] = 'true'; - $textfield = new html_inputfield($attrib); + $attrib['name'] = '_subject'; + $attrib['spellcheck'] = 'true'; - $subject = ''; + $textfield = new html_inputfield($attrib); + $subject = ''; - // use subject from post - if (isset($_POST['_subject'])) { - $subject = get_input_value('_subject', RCUBE_INPUT_POST, TRUE); - } - // create a reply-subject - else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - if (preg_match('/^re:/i', $MESSAGE->subject)) - $subject = $MESSAGE->subject; - else - $subject = 'Re: '.$MESSAGE->subject; - } - // create a forward-subject - else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { - if (preg_match('/^fwd:/i', $MESSAGE->subject)) - $subject = $MESSAGE->subject; - else - $subject = 'Fwd: '.$MESSAGE->subject; - } - // creeate a draft-subject - else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { - $subject = $MESSAGE->subject; - } - else if (!empty($COMPOSE['param']['subject'])) { - $subject = $COMPOSE['param']['subject']; - } - - $out = $form_start ? "$form_start\n" : ''; - $out .= $textfield->show($subject); - $out .= $form_end ? "\n$form_end" : ''; - - return $out; + // use subject from post + if (isset($_POST['_subject'])) { + $subject = rcube_utils::get_input_value('_subject', rcube_utils::INPUT_POST, TRUE); + } + // create a reply-subject + else if ($compose_mode == RCUBE_COMPOSE_REPLY) { + if (preg_match('/^re:/i', $MESSAGE->subject)) + $subject = $MESSAGE->subject; + else + $subject = 'Re: '.$MESSAGE->subject; + } + // create a forward-subject + else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { + if (preg_match('/^fwd:/i', $MESSAGE->subject)) + $subject = $MESSAGE->subject; + else + $subject = 'Fwd: '.$MESSAGE->subject; + } + // creeate a draft-subject + else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { + $subject = $MESSAGE->subject; + } + else if (!empty($COMPOSE['param']['subject'])) { + $subject = $COMPOSE['param']['subject']; + } + + $out = $form_start ? "$form_start\n" : ''; + $out .= $textfield->show($subject); + $out .= $form_end ? "\n$form_end" : ''; + + return $out; } function rcmail_compose_attachment_list($attrib) { - global $OUTPUT, $CONFIG, $COMPOSE; - - // add ID if not given - if (!$attrib['id']) - $attrib['id'] = 'rcmAttachmentList'; - - $out = "\n"; - $jslist = array(); - $button = ''; - - if (is_array($COMPOSE['attachments'])) { - if ($attrib['deleteicon']) { - $button = html::img(array( - 'src' => $CONFIG['skin_path'] . $attrib['deleteicon'], - 'alt' => rcube_label('delete') - )); - } - else if (rcube_utils::get_boolean($attrib['textbuttons'])) { - $button = Q(rcube_label('delete')); - } - - foreach ($COMPOSE['attachments'] as $id => $a_prop) { - if (empty($a_prop)) - continue; - - $out .= html::tag('li', - array( - 'id' => 'rcmfile'.$id, - 'class' => rcmail_filetype2classname($a_prop['mimetype'], $a_prop['name']), - 'onmouseover' => "rcube_webmail.long_subject_title_ex(this, 0)", - ), - html::a(array( - 'href' => "#delete", - 'title' => rcube_label('delete'), - 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id), - 'class' => 'delete' - ), - $button - ) . Q($a_prop['name']) - ); - - $jslist['rcmfile'.$id] = array('name' => $a_prop['name'], 'complete' => true, 'mimetype' => $a_prop['mimetype']); - } - } - - if ($attrib['deleteicon']) - $COMPOSE['deleteicon'] = $CONFIG['skin_path'] . $attrib['deleteicon']; - else if (rcube_utils::get_boolean($attrib['textbuttons'])) - $COMPOSE['textbuttons'] = true; - if ($attrib['cancelicon']) - $OUTPUT->set_env('cancelicon', $CONFIG['skin_path'] . $attrib['cancelicon']); - if ($attrib['loadingicon']) - $OUTPUT->set_env('loadingicon', $CONFIG['skin_path'] . $attrib['loadingicon']); - - $OUTPUT->set_env('attachments', $jslist); - $OUTPUT->add_gui_object('attachmentlist', $attrib['id']); - - return html::tag('ul', $attrib, $out, html::$common_attrib); + global $RCMAIL, $OUTPUT, $COMPOSE; + + // add ID if not given + if (!$attrib['id']) + $attrib['id'] = 'rcmAttachmentList'; + + $out = "\n"; + $jslist = array(); + $button = ''; + $skin_path = $RCMAIL->config->get('skin_path'); + + if (is_array($COMPOSE['attachments'])) { + if ($attrib['deleteicon']) { + $button = html::img(array( + 'src' => $skin_path . $attrib['deleteicon'], + 'alt' => $RCMAIL->gettext('delete') + )); + } + else if (rcube_utils::get_boolean($attrib['textbuttons'])) { + $button = rcube::Q($RCMAIL->gettext('delete')); + } + + foreach ($COMPOSE['attachments'] as $id => $a_prop) { + if (empty($a_prop)) { + continue; + } + + $out .= html::tag('li', array( + 'id' => 'rcmfile'.$id, + 'class' => rcube_utils::file2class($a_prop['mimetype'], $a_prop['name']), + 'onmouseover' => "rcube_webmail.long_subject_title_ex(this, 0)", + ), + html::a(array( + 'href' => "#delete", + 'title' => $RCMAIL->gettext('delete'), + 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", rcmail_output::JS_OBJECT_NAME, $id), + 'class' => 'delete' + ), + $button + ) . rcube::Q($a_prop['name']) + ); + + $jslist['rcmfile'.$id] = array( + 'name' => $a_prop['name'], + 'complete' => true, + 'mimetype' => $a_prop['mimetype'] + ); + } + } + + if ($attrib['deleteicon']) + $COMPOSE['deleteicon'] = $skin_path . $attrib['deleteicon']; + else if (rcube_utils::get_boolean($attrib['textbuttons'])) + $COMPOSE['textbuttons'] = true; + if ($attrib['cancelicon']) + $OUTPUT->set_env('cancelicon', $skin_path . $attrib['cancelicon']); + if ($attrib['loadingicon']) + $OUTPUT->set_env('loadingicon', $skin_path . $attrib['loadingicon']); + + $OUTPUT->set_env('attachments', $jslist); + $OUTPUT->add_gui_object('attachmentlist', $attrib['id']); + + return html::tag('ul', $attrib, $out, html::$common_attrib); } function rcmail_compose_attachment_form($attrib) { - global $OUTPUT; + global $OUTPUT, $RCMAIL; - // set defaults - $attrib += array('id' => 'rcmUploadbox', 'buttons' => 'yes'); + // set defaults + $attrib += array('id' => 'rcmUploadbox', 'buttons' => 'yes'); - // Get filesize, enable upload progress bar - $max_filesize = rcube_upload_init(); + // Get filesize, enable upload progress bar + $max_filesize = $RCMAIL->upload_init(); - $button = new html_inputfield(array('type' => 'button')); + $button = new html_inputfield(array('type' => 'button')); + $content = html::div(null, rcmail_compose_attachment_field()) + . html::div('hint', $RCMAIL->gettext(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))); - $out = html::div($attrib, - $OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'name' => 'uploadform', 'method' => 'post', 'enctype' => 'multipart/form-data'), - html::div(null, rcmail_compose_attachment_field()) . - html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) . - (get_boolean($attrib['buttons']) ? html::div('buttons', - $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' . - $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('send-attachment', this.form)")) - ) : '') - ) - ); + if (rcube_utils::get_boolean($attrib['buttons'])) { + $content .= html::div('buttons', + $button->show($RCMAIL->gettext('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' . + $button->show($RCMAIL->gettext('upload'), array('class' => 'button mainaction', 'onclick' => rcmail_output::JS_OBJECT_NAME . ".command('send-attachment', this.form)")) + ); + } + + $out = html::div($attrib, $OUTPUT->form_tag(array( + 'id' => $attrib['id'] . 'Frm', + 'name' => 'uploadform', + 'method' => 'post', + 'enctype' => 'multipart/form-data' + ), $content + )); + + $OUTPUT->add_gui_object('uploadform', $attrib['id'] . 'Frm'); - $OUTPUT->add_gui_object('uploadform', $attrib['id'].'Frm'); - return $out; + return $out; } function rcmail_compose_attachment_field($attrib = array()) { - $attrib['type'] = 'file'; - $attrib['name'] = '_attachments[]'; - $attrib['multiple'] = 'multiple'; + $attrib['type'] = 'file'; + $attrib['name'] = '_attachments[]'; + $attrib['multiple'] = 'multiple'; - $field = new html_inputfield($attrib); - return $field->show(); + $field = new html_inputfield($attrib); + + return $field->show(); } function rcmail_priority_selector($attrib) { - global $MESSAGE; + global $RCMAIL, $MESSAGE; - list($form_start, $form_end) = get_form_tags($attrib); - unset($attrib['form']); + list($form_start, $form_end) = get_form_tags($attrib); + unset($attrib['form']); - $attrib['name'] = '_priority'; - $selector = new html_select($attrib); + $attrib['name'] = '_priority'; + $prio_list = array( + $RCMAIL->gettext('lowest') => 5, + $RCMAIL->gettext('low') => 4, + $RCMAIL->gettext('normal') => 0, + $RCMAIL->gettext('high') => 2, + $RCMAIL->gettext('highest') => 1, + ); - $selector->add(array(rcube_label('lowest'), - rcube_label('low'), - rcube_label('normal'), - rcube_label('high'), - rcube_label('highest')), - array('5', '4', '0', '2', '1')); + $selector = new html_select($attrib); + $selector->add(array_keys($prio_list), array_values($prio_list)); - if (isset($_POST['_priority'])) - $sel = $_POST['_priority']; - else if (isset($MESSAGE->headers->priority) && intval($MESSAGE->headers->priority) != 3) - $sel = $MESSAGE->headers->priority; - else - $sel = 0; + if (isset($_POST['_priority'])) + $sel = $_POST['_priority']; + else if (isset($MESSAGE->headers->priority) && intval($MESSAGE->headers->priority) != 3) + $sel = $MESSAGE->headers->priority; + else + $sel = 0; - $out = $form_start ? "$form_start\n" : ''; - $out .= $selector->show(strval($sel)); - $out .= $form_end ? "\n$form_end" : ''; + $out = $form_start ? "$form_start\n" : ''; + $out .= $selector->show((int) $sel); + $out .= $form_end ? "\n$form_end" : ''; - return $out; + return $out; } function rcmail_receipt_checkbox($attrib) { - global $RCMAIL, $MESSAGE, $compose_mode; + global $RCMAIL, $MESSAGE, $compose_mode; - list($form_start, $form_end) = get_form_tags($attrib); - unset($attrib['form']); + list($form_start, $form_end) = get_form_tags($attrib); + unset($attrib['form']); - if (!isset($attrib['id'])) - $attrib['id'] = 'receipt'; + if (!isset($attrib['id'])) + $attrib['id'] = 'receipt'; - $attrib['name'] = '_receipt'; - $attrib['value'] = '1'; - $checkbox = new html_checkbox($attrib); + $attrib['name'] = '_receipt'; + $attrib['value'] = '1'; - if (isset($_POST['_receipt'])) - $mdn_default = $_POST['_receipt']; - else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) - $mdn_default = (bool) $MESSAGE->headers->mdn_to; - else - $mdn_default = $RCMAIL->config->get('mdn_default'); + $checkbox = new html_checkbox($attrib); - $out = $form_start ? "$form_start\n" : ''; - $out .= $checkbox->show($mdn_default); - $out .= $form_end ? "\n$form_end" : ''; + if (isset($_POST['_receipt'])) + $mdn_default = $_POST['_receipt']; + else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) + $mdn_default = (bool) $MESSAGE->headers->mdn_to; + else + $mdn_default = $RCMAIL->config->get('mdn_default'); - return $out; + $out = $form_start ? "$form_start\n" : ''; + $out .= $checkbox->show($mdn_default); + $out .= $form_end ? "\n$form_end" : ''; + + return $out; } function rcmail_dsn_checkbox($attrib) { - global $RCMAIL; + global $RCMAIL; + + list($form_start, $form_end) = get_form_tags($attrib); + unset($attrib['form']); - list($form_start, $form_end) = get_form_tags($attrib); - unset($attrib['form']); + if (!isset($attrib['id'])) + $attrib['id'] = 'dsn'; - if (!isset($attrib['id'])) - $attrib['id'] = 'dsn'; + $attrib['name'] = '_dsn'; + $attrib['value'] = '1'; - $attrib['name'] = '_dsn'; - $attrib['value'] = '1'; - $checkbox = new html_checkbox($attrib); + $checkbox = new html_checkbox($attrib); - if (isset($_POST['_dsn'])) - $dsn_value = $_POST['_dsn']; - else - $dsn_value = $RCMAIL->config->get('dsn_default'); + if (isset($_POST['_dsn'])) + $dsn_value = (int) $_POST['_dsn']; + else + $dsn_value = $RCMAIL->config->get('dsn_default'); - $out = $form_start ? "$form_start\n" : ''; - $out .= $checkbox->show($dsn_value); - $out .= $form_end ? "\n$form_end" : ''; + $out = $form_start ? "$form_start\n" : ''; + $out .= $checkbox->show($dsn_value); + $out .= $form_end ? "\n$form_end" : ''; - return $out; + return $out; } function rcmail_editor_selector($attrib) { - // determine whether HTML or plain text should be checked - $useHtml = rcmail_compose_editor_mode(); + global $RCMAIL; - if (empty($attrib['editorid'])) - $attrib['editorid'] = 'rcmComposeBody'; + // determine whether HTML or plain text should be checked + $useHtml = rcmail_compose_editor_mode(); - if (empty($attrib['name'])) - $attrib['name'] = 'editorSelect'; + if (empty($attrib['editorid'])) + $attrib['editorid'] = 'rcmComposeBody'; - $attrib['onchange'] = "return rcmail_toggle_editor(this, '".$attrib['editorid']."', '_is_html')"; + if (empty($attrib['name'])) + $attrib['name'] = 'editorSelect'; - $select = new html_select($attrib); + $attrib['onchange'] = "return rcmail_toggle_editor(this, '".$attrib['editorid']."', '_is_html')"; - $select->add(Q(rcube_label('htmltoggle')), 'html'); - $select->add(Q(rcube_label('plaintoggle')), 'plain'); + $select = new html_select($attrib); - return $select->show($useHtml ? 'html' : 'plain'); -/* - foreach ($choices as $value => $text) { - $attrib['id'] = '_' . $value; - $attrib['value'] = $value; - $selector .= $radio->show($chosenvalue, $attrib) . html::label($attrib['id'], Q(rcube_label($text))); - } + $select->add(rcube::Q($RCMAIL->gettext('htmltoggle')), 'html'); + $select->add(rcube::Q($RCMAIL->gettext('plaintoggle')), 'plain'); - return $selector; -*/ + return $select->show($useHtml ? 'html' : 'plain'); } function rcmail_store_target_selection($attrib) { - global $COMPOSE; - - $attrib['name'] = '_store_target'; - $select = rcmail_mailbox_select(array_merge($attrib, array( - 'noselection' => '- '.rcube_label('dontsave').' -', - 'folder_filter' => 'mail', - 'folder_rights' => 'w', - ))); - return $select->show(isset($_POST['_store_target']) ? $_POST['_store_target'] : $COMPOSE['param']['sent_mbox'], $attrib); + global $COMPOSE, $RCMAIL; + + $attrib['name'] = '_store_target'; + $select = $RCMAIL->folder_selector(array_merge($attrib, array( + 'noselection' => '- ' . $RCMAIL->gettext('dontsave') . ' -', + 'folder_filter' => 'mail', + 'folder_rights' => 'w', + ))); + + return $select->show(isset($_POST['_store_target']) ? $_POST['_store_target'] : $COMPOSE['param']['sent_mbox'], $attrib); } function rcmail_check_sent_folder($folder, $create=false) { - global $RCMAIL; + global $RCMAIL; - // we'll not save the message, so it doesn't matter - if ($RCMAIL->config->get('no_save_sent_messages')) { - return true; - } + // we'll not save the message, so it doesn't matter + if ($RCMAIL->config->get('no_save_sent_messages')) { + return true; + } - if ($RCMAIL->storage->folder_exists($folder, true)) { - return true; - } + if ($RCMAIL->storage->folder_exists($folder, true)) { + return true; + } - // folder may exist but isn't subscribed (#1485241) - if ($create) { - if (!$RCMAIL->storage->folder_exists($folder)) - return $RCMAIL->storage->create_folder($folder, true); - else - return $RCMAIL->storage->subscribe($folder); - } + // folder may exist but isn't subscribed (#1485241) + if ($create) { + if (!$RCMAIL->storage->folder_exists($folder)) + return $RCMAIL->storage->create_folder($folder, true); + else + return $RCMAIL->storage->subscribe($folder); + } - return false; + return false; } function get_form_tags($attrib) { - global $RCMAIL, $MESSAGE_FORM, $COMPOSE; + global $RCMAIL, $MESSAGE_FORM, $COMPOSE; - $form_start = ''; - if (!$MESSAGE_FORM) - { - $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task)); - $hiddenfields->add(array('name' => '_action', 'value' => 'send')); - $hiddenfields->add(array('name' => '_id', 'value' => $COMPOSE['id'])); - $hiddenfields->add(array('name' => '_attachments')); + $form_start = ''; + if (!$MESSAGE_FORM) { + $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task)); + $hiddenfields->add(array('name' => '_action', 'value' => 'send')); + $hiddenfields->add(array('name' => '_id', 'value' => $COMPOSE['id'])); + $hiddenfields->add(array('name' => '_attachments')); - $form_start = empty($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : ''; - $form_start .= $hiddenfields->show(); - } + $form_start = empty($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : ''; + $form_start .= $hiddenfields->show(); + } - $form_end = ($MESSAGE_FORM && !strlen($attrib['form'])) ? '</form>' : ''; - $form_name = !empty($attrib['form']) ? $attrib['form'] : 'form'; + $form_end = ($MESSAGE_FORM && !strlen($attrib['form'])) ? '</form>' : ''; + $form_name = !empty($attrib['form']) ? $attrib['form'] : 'form'; - if (!$MESSAGE_FORM) - $RCMAIL->output->add_gui_object('messageform', $form_name); + if (!$MESSAGE_FORM) + $RCMAIL->output->add_gui_object('messageform', $form_name); - $MESSAGE_FORM = $form_name; + $MESSAGE_FORM = $form_name; - return array($form_start, $form_end); + return array($form_start, $form_end); } @@ -1703,11 +1764,11 @@ function rcmail_addressbook_list($attrib = array()) 'id' => 'rcmli%s', 'class' => '%s'), html::a(array('href' => '#list', 'rel' => '%s', - 'onclick' => "return ".JS_OBJECT_NAME.".command('list-adresses','%s',this)"), '%s')); + 'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".command('list-adresses','%s',this)"), '%s')); foreach ($RCMAIL->get_address_sources(false, true) as $j => $source) { $id = strval(strlen($source['id']) ? $source['id'] : $j); - $js_id = JQ($id); + $js_id = rcube::JQ($id); // set class name(s) $class_name = 'addressbook'; @@ -1715,7 +1776,7 @@ function rcmail_addressbook_list($attrib = array()) $class_name .= ' ' . $source['class_name']; $out .= sprintf($line_templ, - html_identifier($id,true), + rcube_utils::html_identifier($id,true), $class_name, $source['id'], $js_id, (!empty($source['name']) ? $source['name'] : $id)); @@ -1729,7 +1790,7 @@ function rcmail_addressbook_list($attrib = array()) // return the contacts list as HTML table function rcmail_contacts_list($attrib = array()) { - global $OUTPUT; + global $RCMAIL, $OUTPUT; $attrib += array('id' => 'rcmAddressList'); @@ -1739,7 +1800,7 @@ function rcmail_contacts_list($attrib = array()) $OUTPUT->set_env('current_page', 0); $OUTPUT->include_script('list.js'); - return rcube_table_output($attrib, array(), array('name'), 'ID'); + return $RCMAIL->table_output($attrib, array(), array('name'), 'ID'); } @@ -1757,22 +1818,33 @@ function compose_file_drop_area($attrib) } -// register UI objects -$OUTPUT->add_handlers(array( - 'composeheaders' => 'rcmail_compose_headers', - 'composesubject' => 'rcmail_compose_subject', - 'composebody' => 'rcmail_compose_body', - 'composeattachmentlist' => 'rcmail_compose_attachment_list', - 'composeattachmentform' => 'rcmail_compose_attachment_form', - 'composeattachment' => 'rcmail_compose_attachment_field', - 'filedroparea' => 'compose_file_drop_area', - 'priorityselector' => 'rcmail_priority_selector', - 'editorselector' => 'rcmail_editor_selector', - 'receiptcheckbox' => 'rcmail_receipt_checkbox', - 'dsncheckbox' => 'rcmail_dsn_checkbox', - 'storetarget' => 'rcmail_store_target_selection', - 'addressbooks' => 'rcmail_addressbook_list', - 'addresslist' => 'rcmail_contacts_list', -)); +/** + * + */ +function rcmail_compose_responses_list($attrib) +{ + global $RCMAIL, $OUTPUT; -$OUTPUT->send('compose'); + $attrib += array('id' => 'rcmresponseslist', 'tagname' => 'ul', 'cols' => 1); + + $jsenv = array(); + $list = new html_table($attrib); + foreach ($RCMAIL->get_compose_responses(true) as $response) { + $key = $response['key']; + $item = html::a(array( + 'href '=> '#'.urlencode($response['name']), + 'class' => rtrim('insertresponse ' . $attrib['itemclass']), + 'unselectable' => 'on', + 'rel' => $key, + ), rcube::Q($response['name'])); + + $jsenv[$key] = $response; + $list->add(array(), $item); + } + + // set client env + $OUTPUT->set_env('textresponses', $jsenv); + $OUTPUT->add_gui_object('responseslist', $attrib['id']); + + return $list->show(); +} diff --git a/program/steps/mail/copy.inc b/program/steps/mail/copy.inc index 0ed0d05a1..0f7b1a03a 100644 --- a/program/steps/mail/copy.inc +++ b/program/steps/mail/copy.inc @@ -5,7 +5,7 @@ | program/steps/mail/copy.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2010, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -20,12 +20,13 @@ */ // only process ajax requests -if (!$OUTPUT->ajax_call) - return; +if (!$OUTPUT->ajax_call) { + return; +} // move messages if (!empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) { - $target = get_input_value('_target_mbox', RCUBE_INPUT_POST, true); + $target = rcube_utils::get_input_value('_target_mbox', rcube_utils::INPUT_POST, true); foreach (rcmail_get_uids() as $mbox => $uids) { $copied += (int)$RCMAIL->storage->copy_message($uids, $target, $mbox); @@ -33,7 +34,7 @@ if (!empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) { if (!$copied) { // send error message - rcmail_display_server_error('errorcopying'); + $RCMAIL->display_server_error('errorcopying'); $OUTPUT->send(); exit; } @@ -43,7 +44,7 @@ if (!empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) { rcmail_send_unread_count($target, true); - $OUTPUT->command('set_quota', rcmail_quota_content()); + $OUTPUT->command('set_quota', $RCMAIL->quota_content()); } // unknown action or missing query param else { diff --git a/program/steps/mail/folders.inc b/program/steps/mail/folders.inc index 574d6e975..519a41fdd 100644 --- a/program/steps/mail/folders.inc +++ b/program/steps/mail/folders.inc @@ -5,7 +5,7 @@ | program/steps/mail/folders.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -20,14 +20,14 @@ */ // only process ajax requests -if (!$OUTPUT->ajax_call) +if (!$OUTPUT->ajax_call) { return; +} -$mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true); +$mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true); // send EXPUNGE command if ($RCMAIL->action == 'expunge') { - $success = $RCMAIL->storage->expunge_folder($mbox); // reload message list if current mailbox @@ -35,26 +35,26 @@ if ($RCMAIL->action == 'expunge') { $OUTPUT->show_message('folderexpunged', 'confirmation'); if (!empty($_REQUEST['_reload'])) { - $OUTPUT->command('set_quota', rcmail_quota_content()); + $OUTPUT->command('set_quota', $RCMAIL->quota_content()); $OUTPUT->command('message_list.clear'); $RCMAIL->action = 'list'; return; } } else { - rcmail_display_server_error(); + $RCMAIL->display_server_error(); } } - // clear mailbox -else if ($RCMAIL->action == 'purge') -{ - $delimiter = $RCMAIL->storage->get_hierarchy_delimiter(); - $trash_regexp = '/^' . preg_quote($CONFIG['trash_mbox'] . $delimiter, '/') . '/'; - $junk_regexp = '/^' . preg_quote($CONFIG['junk_mbox'] . $delimiter, '/') . '/'; +else if ($RCMAIL->action == 'purge') { + $delimiter = $RCMAIL->storage->get_hierarchy_delimiter(); + $trash_mbox = $RCMAIL->config->get('trash_mbox'); + $junk_mbox = $RCMAIL->config->get('junk_mbox'); + $trash_regexp = '/^' . preg_quote($trash_mbox . $delimiter, '/') . '/'; + $junk_regexp = '/^' . preg_quote($junk_mbox . $delimiter, '/') . '/'; // we should only be purging trash and junk (or their subfolders) - if ($mbox == $CONFIG['trash_mbox'] || $mbox == $CONFIG['junk_mbox'] + if ($mbox == $trash_mbox || $mbox == $junk_mbox || preg_match($trash_regexp, $mbox) || preg_match($junk_regexp, $mbox) ) { $success = $RCMAIL->storage->clear_folder($mbox); @@ -69,12 +69,17 @@ else if ($RCMAIL->action == 'purge') $OUTPUT->command('message_list.clear'); $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text(), $mbox); $OUTPUT->command('set_unread_count', $mbox, 0); - $OUTPUT->command('set_quota', rcmail_quota_content()); + $OUTPUT->command('set_quota', $RCMAIL->quota_content()); rcmail_set_unseen_count($mbox, 0); + + // set trash folder state + if ($mbox === $trash_mbox) { + $OUTPUT->command('set_trash_count', 0); + } } } else { - rcmail_display_server_error(); + $RCMAIL->display_server_error(); } } } diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc index 807ec3ce9..3848ec540 100644 --- a/program/steps/mail/func.inc +++ b/program/steps/mail/func.inc @@ -5,7 +5,7 @@ | program/steps/mail/func.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2012, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -16,44 +16,45 @@ | | +-----------------------------------------------------------------------+ | Author: Thomas Bruederli <roundcube@gmail.com> | + | Author: Aleksander Machniak <alec@alec.pl> | +-----------------------------------------------------------------------+ */ -// setup some global vars used by mail steps -$SENT_MBOX = $RCMAIL->config->get('sent_mbox'); -$DRAFTS_MBOX = $RCMAIL->config->get('drafts_mbox'); -$SEARCH_MODS_DEFAULT = array( - '*' => array('subject'=>1, 'from'=>1), - $SENT_MBOX => array('subject'=>1, 'to'=>1), - $DRAFTS_MBOX => array('subject'=>1, 'to'=>1) -); - // always instantiate storage object (but not connect to server yet) $RCMAIL->storage_init(); // set imap properties and session vars -if (strlen(trim($mbox = get_input_value('_mbox', RCUBE_INPUT_GPC, true)))) - $RCMAIL->storage->set_folder(($_SESSION['mbox'] = $mbox)); -else if ($RCMAIL->storage) - $_SESSION['mbox'] = $RCMAIL->storage->get_folder(); +if (strlen(trim($mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true)))) { + $RCMAIL->storage->set_folder(($_SESSION['mbox'] = $mbox)); +} +else if ($RCMAIL->storage) { + $_SESSION['mbox'] = $RCMAIL->storage->get_folder(); +} -if (!empty($_GET['_page'])) - $RCMAIL->storage->set_page(($_SESSION['page'] = intval($_GET['_page']))); +if (!empty($_GET['_page'])) { + $RCMAIL->storage->set_page(($_SESSION['page'] = intval($_GET['_page']))); +} + +$a_threading = $RCMAIL->config->get('message_threading', array()); +$message_sort_col = $RCMAIL->config->get('message_sort_col'); +$message_sort_order = $RCMAIL->config->get('message_sort_col'); // set default sort col/order to session -if (!isset($_SESSION['sort_col'])) - $_SESSION['sort_col'] = !empty($CONFIG['message_sort_col']) ? $CONFIG['message_sort_col'] : ''; -if (!isset($_SESSION['sort_order'])) - $_SESSION['sort_order'] = strtoupper($CONFIG['message_sort_order']) == 'ASC' ? 'ASC' : 'DESC'; +if (!isset($_SESSION['sort_col'])) { + $_SESSION['sort_col'] = $message_sort_col ? $message_sort_col : ''; +} +if (!isset($_SESSION['sort_order'])) { + $_SESSION['sort_order'] = strtoupper($message_sort_order) == 'ASC' ? 'ASC' : 'DESC'; +} // set threads mode -$a_threading = $RCMAIL->config->get('message_threading', array()); if (isset($_GET['_threads'])) { - if ($_GET['_threads']) - $a_threading[$_SESSION['mbox']] = true; - else - unset($a_threading[$_SESSION['mbox']]); - $RCMAIL->user->save_prefs(array('message_threading' => $a_threading)); + if ($_GET['_threads']) + $a_threading[$_SESSION['mbox']] = true; + else + unset($a_threading[$_SESSION['mbox']]); + + $RCMAIL->user->save_prefs(array('message_threading' => $a_threading)); } $RCMAIL->storage->set_threading($a_threading[$_SESSION['mbox']]); @@ -61,9 +62,10 @@ $RCMAIL->storage->set_threading($a_threading[$_SESSION['mbox']]); if (!empty($_REQUEST['_search']) && isset($_SESSION['search']) && $_SESSION['search_request'] == $_REQUEST['_search'] ) { - $RCMAIL->storage->set_search_set($_SESSION['search']); - $OUTPUT->set_env('search_request', $_REQUEST['_search']); - $OUTPUT->set_env('search_text', $_SESSION['last_text_search']); + $RCMAIL->storage->set_search_set($_SESSION['search']); + + $OUTPUT->set_env('search_request', $_REQUEST['_search']); + $OUTPUT->set_env('search_text', $_SESSION['last_text_search']); } // remove mbox part from _uid @@ -83,80 +85,83 @@ if (($_uid = get_input_value('_uid', RCUBE_INPUT_GPC)) && preg_match('/^\d+-[^, // set main env variables, labels and page title if (empty($RCMAIL->action) || $RCMAIL->action == 'list') { - // connect to storage server and trigger error on failure - $RCMAIL->storage_connect(); + // connect to storage server and trigger error on failure + $RCMAIL->storage_connect(); + + $mbox_name = $RCMAIL->storage->get_folder(); + + if (empty($RCMAIL->action)) { + // initialize searching result if search_filter is used + if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') { + $RCMAIL->storage->search($mbox_name, $_SESSION['search_filter'], RCUBE_CHARSET, rcmail_sort_column()); - $mbox_name = $RCMAIL->storage->get_folder(); + $search_request = md5($mbox_name.$_SESSION['search_filter']); + $_SESSION['search'] = $RCMAIL->storage->get_search_set(); + $_SESSION['search_request'] = $search_request; - if (empty($RCMAIL->action)) { - // initialize searching result if search_filter is used - if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') { - $search_request = md5($mbox_name.$_SESSION['search_filter']); + $OUTPUT->set_env('search_request', $search_request); + } - $RCMAIL->storage->search($mbox_name, $_SESSION['search_filter'], RCMAIL_CHARSET, rcmail_sort_column()); - $_SESSION['search'] = $RCMAIL->storage->get_search_set(); - $_SESSION['search_request'] = $search_request; - $OUTPUT->set_env('search_request', $search_request); + $OUTPUT->set_env('search_mods', rcmail_search_mods()); } - $search_mods = $RCMAIL->config->get('search_mods', $SEARCH_MODS_DEFAULT); - $OUTPUT->set_env('search_mods', $search_mods); - } + $threading = (bool) $RCMAIL->storage->get_threading(); + $delimiter = $RCMAIL->storage->get_hierarchy_delimiter(); - $threading = (bool) $RCMAIL->storage->get_threading(); - $delimiter = $RCMAIL->storage->get_hierarchy_delimiter(); - - // set current mailbox and some other vars in client environment - $OUTPUT->set_env('mailbox', $mbox_name); - $OUTPUT->set_env('pagesize', $RCMAIL->storage->get_pagesize()); - $OUTPUT->set_env('delimiter', $delimiter); - $OUTPUT->set_env('threading', $threading); - $OUTPUT->set_env('threads', $threading || $RCMAIL->storage->get_capability('THREAD')); - $OUTPUT->set_env('preview_pane_mark_read', $RCMAIL->config->get('preview_pane_mark_read', 0)); - if ($RCMAIL->storage->get_capability('QUOTA')) { - $OUTPUT->set_env('quota', true); - } + // set current mailbox and some other vars in client environment + $OUTPUT->set_env('mailbox', $mbox_name); + $OUTPUT->set_env('pagesize', $RCMAIL->storage->get_pagesize()); + $OUTPUT->set_env('delimiter', $delimiter); + $OUTPUT->set_env('threading', $threading); + $OUTPUT->set_env('threads', $threading || $RCMAIL->storage->get_capability('THREAD')); + $OUTPUT->set_env('reply_all_mode', (int) $RCMAIL->config->get('reply_all_mode')); + $OUTPUT->set_env('preview_pane_mark_read', $RCMAIL->config->get('preview_pane_mark_read', 0)); - foreach (array('delete_junk','flag_for_deletion','read_when_deleted','skip_deleted','display_next','message_extwin','compose_extwin','forward_attachment') as $prop) { - if ($CONFIG[$prop]) - $OUTPUT->set_env($prop, true); - } + if ($RCMAIL->storage->get_capability('QUOTA')) { + $OUTPUT->set_env('quota', true); + } - if ($CONFIG['trash_mbox']) - $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']); - if ($CONFIG['drafts_mbox']) - $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']); - if ($CONFIG['junk_mbox']) - $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']); + // set special folders + foreach (array('drafts', 'trash', 'junk') as $mbox) { + if ($folder = $RCMAIL->config->get($mbox . '_mbox')) { + $OUTPUT->set_env($mbox . '_mailbox', $folder); + } + } - if (!empty($_SESSION['browser_caps'])) - $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']); + // set configuration + $RCMAIL->set_env_config(array('delete_junk', 'flag_for_deletion', 'read_when_deleted', + 'skip_deleted', 'display_next', 'message_extwin', 'compose_extwin', 'forward_attachment')); - if (!$OUTPUT->ajax_call) - $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', - 'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage', - 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait'); + if (!empty($_SESSION['browser_caps'])) { + $OUTPUT->set_env('browser_capabilities', $_SESSION['browser_caps']); + } + + if (!$OUTPUT->ajax_call) { + $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', + 'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage', + 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait'); + } - $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true); - $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle); + $pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true); + $pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle); - $OUTPUT->set_pagetitle($pagetitle); + $OUTPUT->set_pagetitle($pagetitle); } // register UI objects $OUTPUT->add_handlers(array( - 'mailboxlist' => 'rcmail_mailbox_list', - 'messages' => 'rcmail_message_list', - 'messagecountdisplay' => 'rcmail_messagecount_display', - 'quotadisplay' => 'rcmail_quota_display', - 'mailboxname' => 'rcmail_mailbox_name_display', - 'messageheaders' => 'rcmail_message_headers', - 'messagefullheaders' => 'rcmail_message_full_headers', - 'messagebody' => 'rcmail_message_body', - 'messagecontentframe' => 'rcmail_messagecontent_frame', - 'messageimportform' => 'rcmail_message_import_form', - 'searchfilter' => 'rcmail_search_filter', - 'searchform' => array($OUTPUT, 'search_form'), + 'mailboxlist' => array($RCMAIL, 'folder_list'), + 'quotadisplay' => array($RCMAIL, 'quota_display'), + 'messages' => 'rcmail_message_list', + 'messagecountdisplay' => 'rcmail_messagecount_display', + 'mailboxname' => 'rcmail_mailbox_name_display', + 'messageheaders' => 'rcmail_message_headers', + 'messagefullheaders' => 'rcmail_message_full_headers', + 'messagebody' => 'rcmail_message_body', + 'messagecontentframe' => 'rcmail_messagecontent_frame', + 'messageimportform' => 'rcmail_message_import_form', + 'searchfilter' => 'rcmail_search_filter', + 'searchform' => array($OUTPUT, 'search_form'), )); // register action aliases @@ -205,6 +210,27 @@ function rcmail_get_uids() return $result; } +/** + * Returns default search mods + */ +function rcmail_search_mods() +{ + global $RCMAIL; + + $mods = $RCMAIL->config->get('search_mods'); + + if (empty($mods)) { + $mods = array('*' => array('subject' => 1, 'from' => 1)); + + foreach (array('sent', 'drafts') as $mbox) { + if ($mbox = $RCMAIL->config->get($mbox . '_mbox')) { + $mods[$mbox] = array('subject' => 1, 'to' => 1); + } + } + } + + return $mods; +} /** * Returns 'to' if current folder is configured Sent or Drafts @@ -214,20 +240,20 @@ function rcmail_get_uids() */ function rcmail_message_list_smart_column_name() { - global $RCMAIL; + global $RCMAIL; - $delim = $RCMAIL->storage->get_hierarchy_delimiter(); - $mbox = $RCMAIL->storage->get_folder(); - $sent_mbox = $RCMAIL->config->get('sent_mbox'); - $drafts_mbox = $RCMAIL->config->get('drafts_mbox'); + $delim = $RCMAIL->storage->get_hierarchy_delimiter(); + $mbox = $RCMAIL->storage->get_folder(); + $sent_mbox = $RCMAIL->config->get('sent_mbox'); + $drafts_mbox = $RCMAIL->config->get('drafts_mbox'); - if ((strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0) - && strtoupper($mbox) != 'INBOX' - ) { - return 'to'; - } + if ((strpos($mbox.$delim, $sent_mbox.$delim) === 0 || strpos($mbox.$delim, $drafts_mbox.$delim) === 0) + && strtoupper($mbox) != 'INBOX' + ) { + return 'to'; + } - return 'from'; + return 'from'; } /** @@ -239,21 +265,21 @@ function rcmail_message_list_smart_column_name() */ function rcmail_sort_column() { - global $RCMAIL; + global $RCMAIL; - if (isset($_SESSION['sort_col'])) { - $column = $_SESSION['sort_col']; - } - else { - $column = $RCMAIL->config->get('message_sort_col'); - } + if (isset($_SESSION['sort_col'])) { + $column = $_SESSION['sort_col']; + } + else { + $column = $RCMAIL->config->get('message_sort_col'); + } - // get name of smart From/To column in folder context - if ($column == 'fromto') { - $column = rcmail_message_list_smart_column_name(); - } + // get name of smart From/To column in folder context + if ($column == 'fromto') { + $column = rcmail_message_list_smart_column_name(); + } - return $column; + return $column; } /** @@ -263,13 +289,13 @@ function rcmail_sort_column() */ function rcmail_sort_order() { - global $RCMAIL; + global $RCMAIL; - if (isset($_SESSION['sort_order'])) { - return $_SESSION['sort_order']; - } + if (isset($_SESSION['sort_order'])) { + return $_SESSION['sort_order']; + } - return $RCMAIL->config->get('message_sort_order'); + return $RCMAIL->config->get('message_sort_order'); } /** @@ -277,392 +303,398 @@ function rcmail_sort_order() */ function rcmail_message_list($attrib) { - global $CONFIG, $OUTPUT; + global $RCMAIL, $OUTPUT; - // add some labels to client - $OUTPUT->add_label('from', 'to'); + // add some labels to client + $OUTPUT->add_label('from', 'to'); - // add id to message list table if not specified - if (!strlen($attrib['id'])) - $attrib['id'] = 'rcubemessagelist'; + // add id to message list table if not specified + if (!strlen($attrib['id'])) + $attrib['id'] = 'rcubemessagelist'; - // define list of cols to be displayed based on parameter or config - if (empty($attrib['columns'])) { - $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject'); - $OUTPUT->set_env('col_movable', !in_array('list_cols', (array)$CONFIG['dont_override'])); - } - else { - $a_show_cols = preg_split('/[\s,;]+/', strip_quotes($attrib['columns'])); - $attrib['columns'] = $a_show_cols; - } + // define list of cols to be displayed based on parameter or config + if (empty($attrib['columns'])) { + $list_cols = $RCMAIL->config->get('list_cols'); + $a_show_cols = !empty($list_cols) && is_array($list_cols) ? $list_cols : array('subject'); - // save some variables for use in ajax list - $_SESSION['list_attrib'] = $attrib; - // make sure 'threads' and 'subject' columns are present - if (!in_array('subject', $a_show_cols)) - array_unshift($a_show_cols, 'subject'); - if (!in_array('threads', $a_show_cols)) - array_unshift($a_show_cols, 'threads'); - - $_SESSION['skin_path'] = $CONFIG['skin_path']; - - // set client env - $OUTPUT->add_gui_object('messagelist', $attrib['id']); - $OUTPUT->set_env('autoexpand_threads', intval($CONFIG['autoexpand_threads'])); - $OUTPUT->set_env('sort_col', $_SESSION['sort_col']); - $OUTPUT->set_env('sort_order', $_SESSION['sort_order']); - $OUTPUT->set_env('messages', array()); - $OUTPUT->set_env('coltypes', $a_show_cols); - - $OUTPUT->include_script('list.js'); - - $table = new html_table($attrib); - if (!$attrib['noheader']) { - foreach (rcmail_message_list_head($attrib, $a_show_cols) as $cell) - $table->add_header(array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']); - } + $OUTPUT->set_env('col_movable', !in_array('list_cols', (array)$RCMAIL->config->get('dont_override'))); + } + else { + $a_show_cols = preg_split('/[\s,;]+/', str_replace(array("'", '"'), '', $attrib['columns'])); + $attrib['columns'] = $a_show_cols; + } - return $table->show(); -} + // save some variables for use in ajax list + $_SESSION['list_attrib'] = $attrib; + + // make sure 'threads' and 'subject' columns are present + if (!in_array('subject', $a_show_cols)) + array_unshift($a_show_cols, 'subject'); + if (!in_array('threads', $a_show_cols)) + array_unshift($a_show_cols, 'threads'); + + $_SESSION['skin_path'] = $RCMAIL->config->get('skin_path'); + + // set client env + $OUTPUT->add_gui_object('messagelist', $attrib['id']); + $OUTPUT->set_env('autoexpand_threads', intval($RCMAIL->config->get('autoexpand_threads'))); + $OUTPUT->set_env('sort_col', $_SESSION['sort_col']); + $OUTPUT->set_env('sort_order', $_SESSION['sort_order']); + $OUTPUT->set_env('messages', array()); + $OUTPUT->set_env('coltypes', $a_show_cols); + $OUTPUT->include_script('list.js'); + + $table = new html_table($attrib); + + if (!$attrib['noheader']) { + foreach (rcmail_message_list_head($attrib, $a_show_cols) as $cell) + $table->add_header(array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']); + } + + return $table->show(); +} /** * return javascript commands to add rows to the message list */ function rcmail_js_message_list($a_headers, $insert_top=FALSE, $a_show_cols=null) { - global $CONFIG, $RCMAIL, $OUTPUT; + global $RCMAIL, $OUTPUT; - if (empty($a_show_cols)) { - if (!empty($_SESSION['list_attrib']['columns'])) - $a_show_cols = $_SESSION['list_attrib']['columns']; - else - $a_show_cols = is_array($CONFIG['list_cols']) ? $CONFIG['list_cols'] : array('subject'); - } - else { - if (!is_array($a_show_cols)) - $a_show_cols = preg_split('/[\s,;]+/', strip_quotes($a_show_cols)); - $head_replace = true; - } + if (empty($a_show_cols)) { + if (!empty($_SESSION['list_attrib']['columns'])) + $a_show_cols = $_SESSION['list_attrib']['columns']; + else { + $list_cols = $RCMAIL->config->get('list_cols'); + $a_show_cols = !empty($list_cols) && is_array($list_cols) ? $list_cols : array('subject'); + } + } + else { + if (!is_array($a_show_cols)) { + $a_show_cols = preg_split('/[\s,;]+/', str_replace(array("'", '"'), '', $a_show_cols)); + } + $head_replace = true; + } - $mbox = $RCMAIL->storage->get_folder(); + $mbox = $RCMAIL->storage->get_folder(); - // make sure 'threads' and 'subject' columns are present - if (!in_array('subject', $a_show_cols)) - array_unshift($a_show_cols, 'subject'); - if (!in_array('threads', $a_show_cols)) - array_unshift($a_show_cols, 'threads'); + // make sure 'threads' and 'subject' columns are present + if (!in_array('subject', $a_show_cols)) + array_unshift($a_show_cols, 'subject'); + if (!in_array('threads', $a_show_cols)) + array_unshift($a_show_cols, 'threads'); - $_SESSION['list_attrib']['columns'] = $a_show_cols; + $_SESSION['list_attrib']['columns'] = $a_show_cols; - // Make sure there are no duplicated columns (#1486999) - $a_show_cols = array_unique($a_show_cols); + // Make sure there are no duplicated columns (#1486999) + $a_show_cols = array_unique($a_show_cols); - // Plugins may set header's list_cols/list_flags and other rcube_message_header variables - // and list columns - $plugin = $RCMAIL->plugins->exec_hook('messages_list', - array('messages' => $a_headers, 'cols' => $a_show_cols)); + // Plugins may set header's list_cols/list_flags and other rcube_message_header variables + // and list columns + $plugin = $RCMAIL->plugins->exec_hook('messages_list', + array('messages' => $a_headers, 'cols' => $a_show_cols)); - $a_show_cols = $plugin['cols']; - $a_headers = $plugin['messages']; + $a_show_cols = $plugin['cols']; + $a_headers = $plugin['messages']; - $thead = $head_replace ? rcmail_message_list_head($_SESSION['list_attrib'], $a_show_cols) : NULL; + $thead = $head_replace ? rcmail_message_list_head($_SESSION['list_attrib'], $a_show_cols) : NULL; - // get name of smart From/To column in folder context - if (array_search('fromto', $a_show_cols) !== false) { - $smart_col = rcmail_message_list_smart_column_name(); - } + // get name of smart From/To column in folder context + if (array_search('fromto', $a_show_cols) !== false) { + $smart_col = rcmail_message_list_smart_column_name(); + } - $OUTPUT->command('set_message_coltypes', $a_show_cols, $thead, $smart_col); + $OUTPUT->command('set_message_coltypes', $a_show_cols, $thead, $smart_col); - if (empty($a_headers)) - return; + if (empty($a_headers)) { + return; + } - // remove 'threads', 'attachment', 'flag', 'status' columns, we don't need them here - foreach (array('threads', 'attachment', 'flag', 'status', 'priority') as $col) { - if (($key = array_search($col, $a_show_cols)) !== FALSE) - unset($a_show_cols[$key]); - } + // remove 'threads', 'attachment', 'flag', 'status' columns, we don't need them here + foreach (array('threads', 'attachment', 'flag', 'status', 'priority') as $col) { + if (($key = array_search($col, $a_show_cols)) !== FALSE) { + unset($a_show_cols[$key]); + } + } - // loop through message headers - foreach ($a_headers as $header) { - if (empty($header)) - continue; + // loop through message headers + foreach ($a_headers as $header) { + if (empty($header)) + continue; - $a_msg_cols = array(); - $a_msg_flags = array(); + $a_msg_cols = array(); + $a_msg_flags = array(); - // format each col; similar as in rcmail_message_list() - foreach ($a_show_cols as $col) { - $col_name = $col == 'fromto' ? $smart_col : $col; - - if (in_array($col_name, array('from', 'to', 'cc', 'replyto'))) - $cont = rcmail_address_string($header->$col_name, 3, false, null, $header->charset); - else if ($col == 'subject') { - $cont = trim(rcube_mime::decode_header($header->$col, $header->charset)); - if (!$cont) $cont = rcube_label('nosubject'); - $cont = Q($cont); - } - else if ($col == 'size') - $cont = show_bytes($header->$col); - else if ($col == 'date') - $cont = format_date($header->date); - else if ($col == 'folder') - $cont = Q(rcube_charset::convert($header->folder, 'UTF7-IMAP')); - else - $cont = Q($header->$col); - - $a_msg_cols[$col] = $cont; - } - - $a_msg_flags = array_change_key_case(array_map('intval', (array) $header->flags)); - if ($header->depth) - $a_msg_flags['depth'] = $header->depth; - else if ($header->has_children) - $roots[] = $header->uid; - if ($header->parent_uid) - $a_msg_flags['parent_uid'] = $header->parent_uid; - if ($header->has_children) - $a_msg_flags['has_children'] = $header->has_children; - if ($header->unread_children) - $a_msg_flags['unread_children'] = $header->unread_children; - if ($header->others['list-post']) - $a_msg_flags['ml'] = 1; - if ($header->priority) - $a_msg_flags['prio'] = (int) $header->priority; - - $a_msg_flags['ctype'] = Q($header->ctype); - $a_msg_flags['mbox'] = $header->folder; - - // merge with plugin result (Deprecated, use $header->flags) - if (!empty($header->list_flags) && is_array($header->list_flags)) - $a_msg_flags = array_merge($a_msg_flags, $header->list_flags); - if (!empty($header->list_cols) && is_array($header->list_cols)) - $a_msg_cols = array_merge($a_msg_cols, $header->list_cols); - - $OUTPUT->command('add_message_row', - $header->uid, - $a_msg_cols, - $a_msg_flags, - $insert_top); - } + // format each col; similar as in rcmail_message_list() + foreach ($a_show_cols as $col) { + $col_name = $col == 'fromto' ? $smart_col : $col; - if ($RCMAIL->storage->get_threading()) { - $OUTPUT->command('init_threads', (array) $roots, $mbox); - } -} + if (in_array($col_name, array('from', 'to', 'cc', 'replyto'))) + $cont = rcmail_address_string($header->$col_name, 3, false, null, $header->charset); + else if ($col == 'subject') { + $cont = trim(rcube_mime::decode_header($header->$col, $header->charset)); + if (!$cont) $cont = $RCMAIL->gettext('nosubject'); + $cont = rcube::Q($cont); + } + else if ($col == 'size') + $cont = show_bytes($header->$col); + else if ($col == 'date') + $cont = $RCMAIL->format_date($header->date); + else if ($col == 'folder') + $cont = rcube::Q(rcube_charset::convert($header->folder, 'UTF7-IMAP')); + else + $cont = rcube::Q($header->$col); + + $a_msg_cols[$col] = $cont; + } + $a_msg_flags = array_change_key_case(array_map('intval', (array) $header->flags)); + if ($header->depth) + $a_msg_flags['depth'] = $header->depth; + else if ($header->has_children) + $roots[] = $header->uid; + if ($header->parent_uid) + $a_msg_flags['parent_uid'] = $header->parent_uid; + if ($header->has_children) + $a_msg_flags['has_children'] = $header->has_children; + if ($header->unread_children) + $a_msg_flags['unread_children'] = $header->unread_children; + if ($header->others['list-post']) + $a_msg_flags['ml'] = 1; + if ($header->priority) + $a_msg_flags['prio'] = (int) $header->priority; + + $a_msg_flags['ctype'] = rcube::Q($header->ctype); + $a_msg_flags['mbox'] = $header->folder; + + // merge with plugin result (Deprecated, use $header->flags) + if (!empty($header->list_flags) && is_array($header->list_flags)) + $a_msg_flags = array_merge($a_msg_flags, $header->list_flags); + if (!empty($header->list_cols) && is_array($header->list_cols)) + $a_msg_cols = array_merge($a_msg_cols, $header->list_cols); + + $OUTPUT->command('add_message_row', + $header->uid, + $a_msg_cols, + $a_msg_flags, + $insert_top); + } + + if ($RCMAIL->storage->get_threading()) { + $OUTPUT->command('init_threads', (array) $roots, $mbox); + } +} /* * Creates <THEAD> for message list table */ function rcmail_message_list_head($attrib, $a_show_cols) { - global $RCMAIL; - - $skin_path = $_SESSION['skin_path']; + global $RCMAIL; - // check to see if we have some settings for sorting - $sort_col = $_SESSION['sort_col']; - $sort_order = $_SESSION['sort_order']; + $skin_path = $_SESSION['skin_path']; - $dont_override = (array)$RCMAIL->config->get('dont_override'); - $disabled_sort = in_array('message_sort_col', $dont_override); - $disabled_order = in_array('message_sort_order', $dont_override); + // check to see if we have some settings for sorting + $sort_col = $_SESSION['sort_col']; + $sort_order = $_SESSION['sort_order']; - $RCMAIL->output->set_env('disabled_sort_col', $disabled_sort); - $RCMAIL->output->set_env('disabled_sort_order', $disabled_order); + $dont_override = (array) $RCMAIL->config->get('dont_override'); + $disabled_sort = in_array('message_sort_col', $dont_override); + $disabled_order = in_array('message_sort_order', $dont_override); - // define sortable columns - if ($disabled_sort) - $a_sort_cols = $sort_col && !$disabled_order ? array($sort_col) : array(); - else - $a_sort_cols = array('subject', 'date', 'from', 'to', 'fromto', 'size', 'cc'); + $RCMAIL->output->set_env('disabled_sort_col', $disabled_sort); + $RCMAIL->output->set_env('disabled_sort_order', $disabled_order); - if (!empty($attrib['optionsmenuicon'])) { - $onclick = 'return ' . JS_OBJECT_NAME . ".command('menu-open', 'messagelistmenu')"; - if ($attrib['optionsmenuicon'] === true || $attrib['optionsmenuicon'] == 'true') - $list_menu = html::div(array('onclick' => $onclick, 'class' => 'listmenu', - 'id' => 'listmenulink', 'title' => rcube_label('listoptions'))); + // define sortable columns + if ($disabled_sort) + $a_sort_cols = $sort_col && !$disabled_order ? array($sort_col) : array(); else - $list_menu = html::a(array('href' => '#', 'onclick' => $onclick), - html::img(array('src' => $skin_path . $attrib['optionsmenuicon'], - 'id' => 'listmenulink', 'title' => rcube_label('listoptions'))) - ); - } - else - $list_menu = ''; + $a_sort_cols = array('subject', 'date', 'from', 'to', 'fromto', 'size', 'cc'); - $cells = array(); + if (!empty($attrib['optionsmenuicon'])) { + $onclick = 'return ' . rcmail_output::JS_OBJECT_NAME . ".command('menu-open', 'messagelistmenu')"; + if ($attrib['optionsmenuicon'] === true || $attrib['optionsmenuicon'] == 'true') + $list_menu = html::div(array('onclick' => $onclick, 'class' => 'listmenu', + 'id' => 'listmenulink', 'title' => $RCMAIL->gettext('listoptions'))); + else + $list_menu = html::a(array('href' => '#', 'onclick' => $onclick), + html::img(array('src' => $skin_path . $attrib['optionsmenuicon'], + 'id' => 'listmenulink', 'title' => $RCMAIL->gettext('listoptions')))); + } + else { + $list_menu = ''; + } - // get name of smart From/To column in folder context - if (array_search('fromto', $a_show_cols) !== false) { - $smart_col = rcmail_message_list_smart_column_name(); - } + $cells = array(); - foreach ($a_show_cols as $col) { - // get column name - switch ($col) { - case 'flag': - $col_name = '<span class="flagged"> </span>'; - break; - case 'attachment': - case 'priority': - case 'status': - $col_name = '<span class="' . $col .'"> </span>'; - break; - case 'threads': - $col_name = $list_menu; - break; - case 'fromto': - $col_name = Q(rcube_label($smart_col)); - break; - default: - $col_name = Q(rcube_label($col)); + // get name of smart From/To column in folder context + if (array_search('fromto', $a_show_cols) !== false) { + $smart_col = rcmail_message_list_smart_column_name(); } - // make sort links - if (in_array($col, $a_sort_cols)) - $col_name = html::a(array('href'=>"./#sort", 'onclick' => 'return '.JS_OBJECT_NAME.".command('sort','".$col."',this)", 'title' => rcube_label('sortby')), $col_name); - else if ($col_name[0] != '<') - $col_name = '<span class="' . $col .'">' . $col_name . '</span>'; + foreach ($a_show_cols as $col) { + // get column name + switch ($col) { + case 'flag': + $col_name = '<span class="flagged"> </span>'; + break; + case 'attachment': + case 'priority': + case 'status': + $col_name = '<span class="' . $col .'"> </span>'; + break; + case 'threads': + $col_name = $list_menu; + break; + case 'fromto': + $col_name = rcube::Q($RCMAIL->gettext($smart_col)); + break; + default: + $col_name = rcube::Q($RCMAIL->gettext($col)); + } - $sort_class = $col == $sort_col && !$disabled_order ? " sorted$sort_order" : ''; - $class_name = $col.$sort_class; + // make sort links + if (in_array($col, $a_sort_cols)) { + $col_name = html::a(array( + 'href' => "./#sort", + 'onclick' => 'return '.rcmail_output::JS_OBJECT_NAME.".command('sort','".$col."',this)", + 'title' => $RCMAIL->gettext('sortby') + ), $col_name); + } + else if ($col_name[0] != '<') { + $col_name = '<span class="' . $col .'">' . $col_name . '</span>'; + } - // put it all together - $cells[] = array('className' => $class_name, 'id' => "rcm$col", 'html' => $col_name); - } + $sort_class = $col == $sort_col && !$disabled_order ? " sorted$sort_order" : ''; + $class_name = $col.$sort_class; - return $cells; -} + // put it all together + $cells[] = array('className' => $class_name, 'id' => "rcm$col", 'html' => $col_name); + } + return $cells; +} /** * return an HTML iframe for loading mail content */ function rcmail_messagecontent_frame($attrib) { - global $OUTPUT, $RCMAIL; + global $OUTPUT, $RCMAIL; - if (empty($attrib['id'])) - $attrib['id'] = 'rcmailcontentwindow'; + if (empty($attrib['id'])) + $attrib['id'] = 'rcmailcontentwindow'; - $attrib['name'] = $attrib['id']; + $attrib['name'] = $attrib['id']; - if ($RCMAIL->config->get('preview_pane')) - $OUTPUT->set_env('contentframe', $attrib['id']); - $OUTPUT->set_env('blankpage', $attrib['src'] ? $OUTPUT->abs_url($attrib['src']) : 'program/resources/blank.gif'); + if ($RCMAIL->config->get('preview_pane')) { + $OUTPUT->set_env('contentframe', $attrib['id']); + } - return $OUTPUT->frame($attrib, true); -} + $OUTPUT->set_env('blankpage', $attrib['src'] ? $OUTPUT->abs_url($attrib['src']) : 'program/resources/blank.gif'); + return $OUTPUT->frame($attrib, true); +} function rcmail_messagecount_display($attrib) { - global $RCMAIL; + global $RCMAIL; - if (!$attrib['id']) - $attrib['id'] = 'rcmcountdisplay'; + if (!$attrib['id']) + $attrib['id'] = 'rcmcountdisplay'; - $RCMAIL->output->add_gui_object('countdisplay', $attrib['id']); + $RCMAIL->output->add_gui_object('countdisplay', $attrib['id']); - $content = $RCMAIL->action != 'show' ? rcmail_get_messagecount_text() : rcube_label('loading'); + $content = $RCMAIL->action != 'show' ? rcmail_get_messagecount_text() : $RCMAIL->gettext('loading'); - return html::span($attrib, $content); + return html::span($attrib, $content); } - -function rcmail_get_messagecount_text($count=NULL, $page=NULL) +function rcmail_get_messagecount_text($count = null, $page = null) { - global $RCMAIL; + global $RCMAIL; - if ($page === NULL) { - $page = $RCMAIL->storage->get_page(); - } + if ($page === null) { + $page = $RCMAIL->storage->get_page(); + } - $page_size = $RCMAIL->storage->get_pagesize(); - $start_msg = ($page-1) * $page_size + 1; + $page_size = $RCMAIL->storage->get_pagesize(); + $start_msg = ($page-1) * $page_size + 1; - if ($count!==NULL) - $max = $count; - else if ($RCMAIL->action) - $max = $RCMAIL->storage->count(NULL, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL'); + if ($count !== null) + $max = $count; + else if ($RCMAIL->action) + $max = $RCMAIL->storage->count(NULL, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL'); - if ($max==0) - $out = rcube_label('mailboxempty'); - else - $out = rcube_label(array('name' => $RCMAIL->storage->get_threading() ? 'threadsfromto' : 'messagesfromto', + if ($max == 0) + $out = $RCMAIL->gettext('mailboxempty'); + else + $out = $RCMAIL->gettext(array('name' => $RCMAIL->storage->get_threading() ? 'threadsfromto' : 'messagesfromto', 'vars' => array('from' => $start_msg, 'to' => min($max, $start_msg + $page_size - 1), 'count' => $max))); - return Q($out); + return rcube::Q($out); } - function rcmail_mailbox_name_display($attrib) { - global $RCMAIL; + global $RCMAIL; - if (!$attrib['id']) - $attrib['id'] = 'rcmmailboxname'; + if (!$attrib['id']) + $attrib['id'] = 'rcmmailboxname'; - $RCMAIL->output->add_gui_object('mailboxname', $attrib['id']); + $RCMAIL->output->add_gui_object('mailboxname', $attrib['id']); - return html::span($attrib, rcmail_get_mailbox_name_text()); + return html::span($attrib, rcmail_get_mailbox_name_text()); } - function rcmail_get_mailbox_name_text() { - global $RCMAIL; - return rcmail_localize_foldername($RCMAIL->storage->get_folder()); + global $RCMAIL; + return $RCMAIL->localize_foldername($RCMAIL->storage->get_folder()); } - function rcmail_send_unread_count($mbox_name, $force=false, $count=null, $mark='') { - global $RCMAIL; + global $RCMAIL; - $old_unseen = rcmail_get_unseen_count($mbox_name); + $old_unseen = rcmail_get_unseen_count($mbox_name); - if ($count === null) - $unseen = $RCMAIL->storage->count($mbox_name, 'UNSEEN', $force); - else - $unseen = $count; + if ($count === null) + $unseen = $RCMAIL->storage->count($mbox_name, 'UNSEEN', $force); + else + $unseen = $count; - if ($unseen != $old_unseen || ($mbox_name == 'INBOX')) - $RCMAIL->output->command('set_unread_count', $mbox_name, $unseen, - ($mbox_name == 'INBOX'), $unseen && $mark ? $mark : ''); + if ($unseen != $old_unseen || ($mbox_name == 'INBOX')) + $RCMAIL->output->command('set_unread_count', $mbox_name, $unseen, + ($mbox_name == 'INBOX'), $unseen && $mark ? $mark : ''); - rcmail_set_unseen_count($mbox_name, $unseen); + rcmail_set_unseen_count($mbox_name, $unseen); - return $unseen; + return $unseen; } - function rcmail_set_unseen_count($mbox_name, $count) { - // @TODO: this data is doubled (session and cache tables) if caching is enabled + // @TODO: this data is doubled (session and cache tables) if caching is enabled - // Make sure we have an array here (#1487066) - if (!is_array($_SESSION['unseen_count'])) - $_SESSION['unseen_count'] = array(); + // Make sure we have an array here (#1487066) + if (!is_array($_SESSION['unseen_count'])) { + $_SESSION['unseen_count'] = array(); + } - $_SESSION['unseen_count'][$mbox_name] = $count; + $_SESSION['unseen_count'][$mbox_name] = $count; } - function rcmail_get_unseen_count($mbox_name) { - if (is_array($_SESSION['unseen_count']) && array_key_exists($mbox_name, $_SESSION['unseen_count'])) - return $_SESSION['unseen_count'][$mbox_name]; - else - return null; + if (is_array($_SESSION['unseen_count']) && array_key_exists($mbox_name, $_SESSION['unseen_count'])) { + return $_SESSION['unseen_count'][$mbox_name]; + } } - /** * Sets message is_safe flag according to 'show_images' option value * @@ -670,35 +702,34 @@ function rcmail_get_unseen_count($mbox_name) */ function rcmail_check_safe(&$message) { - global $RCMAIL; - - if (!$message->is_safe - && ($show_images = $RCMAIL->config->get('show_images')) - && $message->has_html_part() - ) { - switch ($show_images) { - case 1: // known senders only - // get default addressbook, like in addcontact.inc - $CONTACTS = $RCMAIL->get_address_book(-1, true); - - if ($CONTACTS) { - $result = $CONTACTS->search('email', $message->sender['mailto'], 1, false); - if ($result->count) { - $message->set_safe(true); - } - } + global $RCMAIL; + + if (!$message->is_safe + && ($show_images = $RCMAIL->config->get('show_images')) + && $message->has_html_part() + ) { + switch ($show_images) { + case 1: // known senders only + // get default addressbook, like in addcontact.inc + $CONTACTS = $RCMAIL->get_address_book(-1, true); + + if ($CONTACTS) { + $result = $CONTACTS->search('email', $message->sender['mailto'], 1, false); + if ($result->count) { + $message->set_safe(true); + } + } - $RCMAIL->plugins->exec_hook('message_check_safe', array('message' => $message)); - break; + $RCMAIL->plugins->exec_hook('message_check_safe', array('message' => $message)); + break; - case 2: // always - $message->set_safe(true); - break; + case 2: // always + $message->set_safe(true); + break; + } } - } } - /** * Cleans up the given message HTML Body (for displaying) * @@ -709,67 +740,68 @@ function rcmail_check_safe(&$message) */ function rcmail_wash_html($html, $p, $cid_replaces) { - global $REMOTE_OBJECTS; + global $REMOTE_OBJECTS; - $p += array('safe' => false, 'inline_html' => true); + $p += array('safe' => false, 'inline_html' => true); - // charset was converted to UTF-8 in rcube_storage::get_message_part(), - // change/add charset specification in HTML accordingly, - // washtml cannot work without that - $meta = '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />'; + // charset was converted to UTF-8 in rcube_storage::get_message_part(), + // change/add charset specification in HTML accordingly, + // washtml cannot work without that + $meta = '<meta http-equiv="Content-Type" content="text/html; charset='.RCUBE_CHARSET.'" />'; - // remove old meta tag and add the new one, making sure - // that it is placed in the head (#1488093) - $html = preg_replace('/<meta[^>]+charset=[a-z0-9-_]+[^>]*>/Ui', '', $html); - $html = preg_replace('/(<head[^>]*>)/Ui', '\\1'.$meta, $html, -1, $rcount); - if (!$rcount) { - $html = '<head>' . $meta . '</head>' . $html; - } + // remove old meta tag and add the new one, making sure + // that it is placed in the head (#1488093) + $html = preg_replace('/<meta[^>]+charset=[a-z0-9-_]+[^>]*>/Ui', '', $html); + $html = preg_replace('/(<head[^>]*>)/Ui', '\\1'.$meta, $html, -1, $rcount); + if (!$rcount) { + $html = '<head>' . $meta . '</head>' . $html; + } - // clean HTML with washhtml by Frederic Motte - $wash_opts = array( - 'show_washed' => false, - 'allow_remote' => $p['safe'], - 'blocked_src' => "./program/resources/blocked.gif", - 'charset' => RCMAIL_CHARSET, - 'cid_map' => $cid_replaces, - 'html_elements' => array('body'), - ); - - if (!$p['inline_html']) { - $wash_opts['html_elements'] = array('html','head','title','body'); - } - if ($p['safe']) { - $wash_opts['html_elements'][] = 'link'; - $wash_opts['html_attribs'] = array('rel','type'); - } + // clean HTML with washhtml by Frederic Motte + $wash_opts = array( + 'show_washed' => false, + 'allow_remote' => $p['safe'], + 'blocked_src' => "./program/resources/blocked.gif", + 'charset' => RCUBE_CHARSET, + 'cid_map' => $cid_replaces, + 'html_elements' => array('body'), + ); - // overwrite washer options with options from plugins - if (isset($p['html_elements'])) - $wash_opts['html_elements'] = $p['html_elements']; - if (isset($p['html_attribs'])) - $wash_opts['html_attribs'] = $p['html_attribs']; + if (!$p['inline_html']) { + $wash_opts['html_elements'] = array('html','head','title','body'); + } + if ($p['safe']) { + $wash_opts['html_elements'][] = 'link'; + $wash_opts['html_attribs'] = array('rel','type'); + } + + // overwrite washer options with options from plugins + if (isset($p['html_elements'])) + $wash_opts['html_elements'] = $p['html_elements']; + if (isset($p['html_attribs'])) + $wash_opts['html_attribs'] = $p['html_attribs']; - // initialize HTML washer - $washer = new rcube_washtml($wash_opts); + // initialize HTML washer + $washer = new rcube_washtml($wash_opts); - if (!$p['skip_washer_form_callback']) - $washer->add_callback('form', 'rcmail_washtml_callback'); + if (!$p['skip_washer_form_callback']) { + $washer->add_callback('form', 'rcmail_washtml_callback'); + } - // allow CSS styles, will be sanitized by rcmail_washtml_callback() - if (!$p['skip_washer_style_callback']) - $washer->add_callback('style', 'rcmail_washtml_callback'); + // allow CSS styles, will be sanitized by rcmail_washtml_callback() + if (!$p['skip_washer_style_callback']) { + $washer->add_callback('style', 'rcmail_washtml_callback'); + } - // Remove non-UTF8 characters (#1487813) - $html = rc_utf8_clean($html); + // Remove non-UTF8 characters (#1487813) + $html = rcube_charset::clean($html); - $html = $washer->wash($html); - $REMOTE_OBJECTS = $washer->extlinks; + $html = $washer->wash($html); + $REMOTE_OBJECTS = $washer->extlinks; - return $html; + return $html; } - /** * Convert the given message part to proper HTML * which can be displayed the message view @@ -780,59 +812,59 @@ function rcmail_wash_html($html, $p, $cid_replaces) */ function rcmail_print_body($part, $p = array()) { - global $RCMAIL; + global $RCMAIL; - // trigger plugin hook - $data = $RCMAIL->plugins->exec_hook('message_part_before', - array('type' => $part->ctype_secondary, 'body' => $part->body, 'id' => $part->mime_id) - + $p + array('safe' => false, 'plain' => false, 'inline_html' => true)); + // trigger plugin hook + $data = $RCMAIL->plugins->exec_hook('message_part_before', + array('type' => $part->ctype_secondary, 'body' => $part->body, 'id' => $part->mime_id) + + $p + array('safe' => false, 'plain' => false, 'inline_html' => true)); - // convert html to text/plain - if ($data['plain'] && ($data['type'] == 'html' || $data['type'] == 'enriched')) { - if ($data['type'] == 'enriched') { - $data['body'] = rcube_enriched::to_html($data['body']); + // convert html to text/plain + if ($data['plain'] && ($data['type'] == 'html' || $data['type'] == 'enriched')) { + if ($data['type'] == 'enriched') { + $data['body'] = rcube_enriched::to_html($data['body']); + } + + $txt = new rcube_html2text($data['body'], false, true); + $body = $txt->get_text(); + $part->ctype_secondary = 'plain'; + } + // text/html + else if ($data['type'] == 'html') { + $body = rcmail_wash_html($data['body'], $data, $part->replaces); + $part->ctype_secondary = $data['type']; + } + // text/enriched + else if ($data['type'] == 'enriched') { + $body = rcube_enriched::to_html($data['body']); + $body = rcmail_wash_html($body, $data, $part->replaces); + $part->ctype_secondary = 'html'; + } + else { + // assert plaintext + $body = $part->body; + $part->ctype_secondary = $data['type'] = 'plain'; } - $txt = new rcube_html2text($data['body'], false, true); - $body = $txt->get_text(); - $part->ctype_secondary = 'plain'; - } - // text/html - else if ($data['type'] == 'html') { - $body = rcmail_wash_html($data['body'], $data, $part->replaces); - $part->ctype_secondary = $data['type']; - } - // text/enriched - else if ($data['type'] == 'enriched') { - $body = rcube_enriched::to_html($data['body']); - $body = rcmail_wash_html($body, $data, $part->replaces); - $part->ctype_secondary = 'html'; - } - else { - // assert plaintext - $body = $part->body; - $part->ctype_secondary = $data['type'] = 'plain'; - } - // free some memory (hopefully) - unset($data['body']); + // free some memory (hopefully) + unset($data['body']); - // plaintext postprocessing - if ($part->ctype_secondary == 'plain') { - if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') { - $body = rcube_mime::unfold_flowed($body); - } + // plaintext postprocessing + if ($part->ctype_secondary == 'plain') { + if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') { + $body = rcube_mime::unfold_flowed($body); + } - $body = rcmail_plain_body($body); - } + $body = rcmail_plain_body($body); + } - // allow post-processing of the message body - $data = $RCMAIL->plugins->exec_hook('message_part_after', - array('type' => $part->ctype_secondary, 'body' => $body, 'id' => $part->mime_id) + $data); + // allow post-processing of the message body + $data = $RCMAIL->plugins->exec_hook('message_part_after', + array('type' => $part->ctype_secondary, 'body' => $body, 'id' => $part->mime_id) + $data); - return $data['type'] == 'html' ? $data['body'] : html::tag('pre', array(), $data['body']); + return $data['type'] == 'html' ? $data['body'] : html::tag('pre', array(), $data['body']); } - /** * Handle links and citation marks in plain text message * @@ -842,232 +874,245 @@ function rcmail_print_body($part, $p = array()) */ function rcmail_plain_body($body) { - global $RCMAIL; - - // make links and email-addresses clickable - $attribs = array('link_attribs' => array('rel' => 'noreferrer', 'target' => '_blank')); - $replacer = new rcmail_string_replacer($attribs); - - // search for patterns like links and e-mail addresses and replace with tokens - $body = $replacer->replace($body); - - // split body into single lines - $body = preg_split('/\r?\n/', $body); - $quote_level = 0; - $last = -1; - - // find/mark quoted lines... - for ($n=0, $cnt=count($body); $n < $cnt; $n++) { - if ($body[$n][0] == '>' && preg_match('/^(>+ {0,1})+/', $body[$n], $regs)) { - $q = substr_count($regs[0], '>'); - $body[$n] = substr($body[$n], strlen($regs[0])); - - if ($q > $quote_level) { - $body[$n] = $replacer->get_replacement($replacer->add( - str_repeat('<blockquote>', $q - $quote_level))) . $body[$n]; - $last = $n; - } - else if ($q < $quote_level) { - $body[$n] = $replacer->get_replacement($replacer->add( - str_repeat('</blockquote>', $quote_level - $q))) . $body[$n]; - $last = $n; - } - } - else { - $q = 0; - if ($quote_level > 0) - $body[$n] = $replacer->get_replacement($replacer->add( - str_repeat('</blockquote>', $quote_level))) . $body[$n]; + global $RCMAIL; + + // make links and email-addresses clickable + $attribs = array('link_attribs' => array('rel' => 'noreferrer', 'target' => '_blank')); + $replacer = new rcmail_string_replacer($attribs); + + // search for patterns like links and e-mail addresses and replace with tokens + $body = $replacer->replace($body); + + // split body into single lines + $body = preg_split('/\r?\n/', $body); + $quote_level = 0; + $last = -1; + + // find/mark quoted lines... + for ($n=0, $cnt=count($body); $n < $cnt; $n++) { + if ($body[$n][0] == '>' && preg_match('/^(>+ {0,1})+/', $body[$n], $regs)) { + $q = substr_count($regs[0], '>'); + $body[$n] = substr($body[$n], strlen($regs[0])); + + if ($q > $quote_level) { + $body[$n] = $replacer->get_replacement($replacer->add( + str_repeat('<blockquote>', $q - $quote_level))) . $body[$n]; + $last = $n; + } + else if ($q < $quote_level) { + $body[$n] = $replacer->get_replacement($replacer->add( + str_repeat('</blockquote>', $quote_level - $q))) . $body[$n]; + $last = $n; + } + } + else { + $q = 0; + if ($quote_level > 0) + $body[$n] = $replacer->get_replacement($replacer->add( + str_repeat('</blockquote>', $quote_level))) . $body[$n]; + } + + $quote_level = $q; } - $quote_level = $q; - } + $body = join("\n", $body); + + // quote plain text (don't use rcube::Q() here, to display entities "as is") + $table = get_html_translation_table(HTML_SPECIALCHARS); + unset($table['?']); + $body = strtr($body, $table); - $body = join("\n", $body); + // colorize signature (up to <sig_max_lines> lines) + $len = strlen($body); + $sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15); - // quote plain text (don't use Q() here, to display entities "as is") - $table = get_html_translation_table(HTML_SPECIALCHARS); - unset($table['?']); - $body = strtr($body, $table); + while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) { + if ($sp == 0 || $body[$sp-1] == "\n") { + // do not touch blocks with more that X lines + if (substr_count($body, "\n", $sp) < $sig_max_lines) { + $body = substr($body, 0, max(0, $sp)) + . '<span class="sig">'.substr($body, $sp).'</span>'; + } - // colorize signature (up to <sig_max_lines> lines) - $len = strlen($body); - $sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15); - while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) { - if ($sp == 0 || $body[$sp-1] == "\n") { - // do not touch blocks with more that X lines - if (substr_count($body, "\n", $sp) < $sig_max_lines) - $body = substr($body, 0, max(0, $sp)) - .'<span class="sig">'.substr($body, $sp).'</span>'; - break; + break; + } } - } - // insert url/mailto links and citation tags - $body = $replacer->resolve($body); + // insert url/mailto links and citation tags + $body = $replacer->resolve($body); - return $body; + return $body; } - /** * Callback function for washtml cleaning class */ function rcmail_washtml_callback($tagname, $attrib, $content, $washtml) { - switch ($tagname) { + switch ($tagname) { case 'form': - $out = html::div('form', $content); - break; + $out = html::div('form', $content); + break; case 'style': - // decode all escaped entities and reduce to ascii strings - $stripped = preg_replace('/[^a-zA-Z\(:;]/', '', rcmail_xss_entity_decode($content)); - - // now check for evil strings like expression, behavior or url() - if (!preg_match('/expression|behavior|javascript:|import[^a]/i', $stripped)) { - if (!$washtml->get_config('allow_remote') && stripos($stripped, 'url(')) - $washtml->extlinks = true; - else - $out = html::tag('style', array('type' => 'text/css'), $content); - break; - } + // decode all escaped entities and reduce to ascii strings + $stripped = preg_replace('/[^a-zA-Z\(:;]/', '', rcube_utils::xss_entity_decode($content)); + + // now check for evil strings like expression, behavior or url() + if (!preg_match('/expression|behavior|javascript:|import[^a]/i', $stripped)) { + if (!$washtml->get_config('allow_remote') && stripos($stripped, 'url(')) + $washtml->extlinks = true; + else + $out = html::tag('style', array('type' => 'text/css'), $content); + break; + } default: - $out = ''; - } + $out = ''; + } - return $out; + return $out; } - /** * return table with message headers */ function rcmail_message_headers($attrib, $headers=null) { - global $MESSAGE, $PRINT_MODE, $RCMAIL; - static $sa_attrib; - - // keep header table attrib - if (is_array($attrib) && !$sa_attrib && !$attrib['valueof']) - $sa_attrib = $attrib; - else if (!is_array($attrib) && is_array($sa_attrib)) - $attrib = $sa_attrib; - - if (!isset($MESSAGE)) - return FALSE; - - // get associative array of headers object - if (!$headers) { - $headers_obj = $MESSAGE->headers; - $headers = get_object_vars($MESSAGE->headers); - } - else if (is_object($headers)) { - $headers_obj = $headers; - $headers = get_object_vars($headers_obj); - } - else { - $headers_obj = rcube_message_header::from_array($headers); - } + global $MESSAGE, $PRINT_MODE, $RCMAIL; + static $sa_attrib; - // show these headers - $standard_headers = array('subject', 'from', 'sender', 'to', 'cc', 'bcc', 'replyto', - 'mail-reply-to', 'mail-followup-to', 'date', 'priority'); - $exclude_headers = $attrib['exclude'] ? explode(',', $attrib['exclude']) : array(); - $output_headers = array(); - - foreach ($standard_headers as $hkey) { - $ishtml = false; - - if ($headers[$hkey]) - $value = $headers[$hkey]; - else if ($headers['others'][$hkey]) - $value = $headers['others'][$hkey]; - else if (!$attrib['valueof']) - continue; - - if (in_array($hkey, $exclude_headers)) - continue; - - $header_title = rcube_label(preg_replace('/(^mail-|-)/', '', $hkey)); - - if ($hkey == 'date') { - if ($PRINT_MODE) - $header_value = format_date($value, $RCMAIL->config->get('date_long', 'x')); - else - $header_value = format_date($value); - } - else if ($hkey == 'priority') { - if ($value) { - $header_value = html::span('prio' . $value, rcmail_localized_priority($value)); - } - else - continue; - } - else if ($hkey == 'replyto') { - if ($headers['replyto'] != $headers['from']) { - $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title); - $ishtml = true; - } - else - continue; - } - else if ($hkey == 'mail-reply-to') { - if ($headers['mail-replyto'] != $headers['reply-to'] - && $headers['reply-to'] != $headers['from'] - ) { - $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title); - $ishtml = true; - } - else - continue; - } - else if ($hkey == 'sender') { - if ($headers['sender'] != $headers['from']) { - $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title); - $ishtml = true; - } - else - continue; - } - else if ($hkey == 'mail-followup-to') { - $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title); - $ishtml = true; - } - else if (in_array($hkey, array('from', 'to', 'cc', 'bcc'))) { - $header_value = rcmail_address_string($value, $attrib['max'], true, $attrib['addicon'], $headers['charset'], $header_title); - $ishtml = true; - } - else if ($hkey == 'subject' && empty($value)) - $header_value = rcube_label('nosubject'); - else - $header_value = trim(rcube_mime::decode_header($value, $headers['charset'])); + // keep header table attrib + if (is_array($attrib) && !$sa_attrib && !$attrib['valueof']) + $sa_attrib = $attrib; + else if (!is_array($attrib) && is_array($sa_attrib)) + $attrib = $sa_attrib; - $output_headers[$hkey] = array( - 'title' => $header_title, - 'value' => $header_value, - 'raw' => $value, - 'html' => $ishtml, - ); - } + if (!isset($MESSAGE)) { + return false; + } + + // get associative array of headers object + if (!$headers) { + $headers_obj = $MESSAGE->headers; + $headers = get_object_vars($MESSAGE->headers); + } + else if (is_object($headers)) { + $headers_obj = $headers; + $headers = get_object_vars($headers_obj); + } + else { + $headers_obj = rcube_message_header::from_array($headers); + } - $plugin = $RCMAIL->plugins->exec_hook('message_headers_output', - array('output' => $output_headers, 'headers' => $headers_obj, 'exclude' => $exclude_headers)); + // show these headers + $standard_headers = array('subject', 'from', 'sender', 'to', 'cc', 'bcc', 'replyto', + 'mail-reply-to', 'mail-followup-to', 'date', 'priority'); + $exclude_headers = $attrib['exclude'] ? explode(',', $attrib['exclude']) : array(); + $output_headers = array(); - // single header value is requested - if (!empty($attrib['valueof'])) - return Q($plugin['output'][$attrib['valueof']]['value'], ($attrib['valueof'] == 'subject' ? 'strict' : 'show')); + foreach ($standard_headers as $hkey) { + $ishtml = false; - // compose html table - $table = new html_table(array('cols' => 2)); + if ($headers[$hkey]) + $value = $headers[$hkey]; + else if ($headers['others'][$hkey]) + $value = $headers['others'][$hkey]; + else if (!$attrib['valueof']) + continue; - foreach ($plugin['output'] as $hkey => $row) { - $table->add(array('class' => 'header-title'), Q($row['title'])); - $table->add(array('class' => 'header '.$hkey), $row['html'] ? $row['value'] : Q($row['value'], ($hkey == 'subject' ? 'strict' : 'show'))); - } + if (in_array($hkey, $exclude_headers)) + continue; + + $header_title = $RCMAIL->gettext(preg_replace('/(^mail-|-)/', '', $hkey)); + + if ($hkey == 'date') { + if ($PRINT_MODE) + $header_value = $RCMAIL->format_date($value, $RCMAIL->config->get('date_long', 'x')); + else + $header_value = $RCMAIL->format_date($value); + } + else if ($hkey == 'priority') { + if ($value) { + $header_value = html::span('prio' . $value, rcmail_localized_priority($value)); + } + else + continue; + } + else if ($hkey == 'replyto') { + if ($headers['replyto'] != $headers['from']) { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else + continue; + } + else if ($hkey == 'mail-reply-to') { + if ($headers['mail-replyto'] != $headers['reply-to'] + && $headers['reply-to'] != $headers['from'] + ) { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else + continue; + } + else if ($hkey == 'sender') { + if ($headers['sender'] != $headers['from']) { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else + continue; + } + else if ($hkey == 'mail-followup-to') { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else if (in_array($hkey, array('from', 'to', 'cc', 'bcc'))) { + $header_value = rcmail_address_string($value, $attrib['max'], true, + $attrib['addicon'], $headers['charset'], $header_title); + $ishtml = true; + } + else if ($hkey == 'subject' && empty($value)) + $header_value = $RCMAIL->gettext('nosubject'); + else + $header_value = trim(rcube_mime::decode_header($value, $headers['charset'])); + + $output_headers[$hkey] = array( + 'title' => $header_title, + 'value' => $header_value, + 'raw' => $value, + 'html' => $ishtml, + ); + } - return $table->show($attrib); + $plugin = $RCMAIL->plugins->exec_hook('message_headers_output', array( + 'output' => $output_headers, + 'headers' => $headers_obj, + 'exclude' => $exclude_headers + )); + + // single header value is requested + if (!empty($attrib['valueof'])) { + return rcube::Q($plugin['output'][$attrib['valueof']]['value'], ($attrib['valueof'] == 'subject' ? 'strict' : 'show')); + } + + // compose html table + $table = new html_table(array('cols' => 2)); + + foreach ($plugin['output'] as $hkey => $row) { + $val = $row['html'] ? $row['value'] : rcube::Q($row['value'], ($hkey == 'subject' ? 'strict' : 'show')); + + $table->add(array('class' => 'header-title'), rcube::Q($row['title'])); + $table->add(array('class' => 'header '.$hkey), $val); + } + + return $table->show($attrib); } /** @@ -1075,18 +1120,21 @@ function rcmail_message_headers($attrib, $headers=null) */ function rcmail_localized_priority($value) { - $labels_map = array( - '1' => 'highest', - '2' => 'high', - '3' => 'normal', - '4' => 'low', - '5' => 'lowest', - ); - - if ($value && $labels_map[$value]) - return rcube_label($labels_map[$value]); - - return ''; + global $RCMAIL; + + $labels_map = array( + '1' => 'highest', + '2' => 'high', + '3' => 'normal', + '4' => 'low', + '5' => 'lowest', + ); + + if ($value && $labels_map[$value]) { + return $RCMAIL->gettext($labels_map[$value]); + } + + return ''; } /** @@ -1094,18 +1142,21 @@ function rcmail_localized_priority($value) */ function rcmail_message_full_headers($attrib, $headers=NULL) { - global $OUTPUT; + global $OUTPUT, $RCMAIL; - $html = html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), html::div(array('id' => 'headers-source'), '')); - $html .= html::div(array('class' => "more-headers show-headers", 'onclick' => "return ".JS_OBJECT_NAME.".command('show-headers','',this)", 'title' => rcube_label('togglefullheaders')), ''); + $html = html::div(array('id' => "all-headers", 'class' => "all", 'style' => 'display:none'), html::div(array('id' => 'headers-source'), '')); + $html .= html::div(array( + 'class' => "more-headers show-headers", + 'onclick' => "return ".rcmail_output::JS_OBJECT_NAME.".command('show-headers','',this)", + 'title' => $RCMAIL->gettext('togglefullheaders') + ), ''); - $OUTPUT->add_gui_object('all_headers_row', 'all-headers'); - $OUTPUT->add_gui_object('all_headers_box', 'headers-source'); + $OUTPUT->add_gui_object('all_headers_row', 'all-headers'); + $OUTPUT->add_gui_object('all_headers_box', 'headers-source'); - return html::div($attrib, $html); + return html::div($attrib, $html); } - /** * Handler for the 'messagebody' GUI object * @@ -1114,518 +1165,530 @@ function rcmail_message_full_headers($attrib, $headers=NULL) */ function rcmail_message_body($attrib) { - global $CONFIG, $OUTPUT, $MESSAGE, $RCMAIL, $REMOTE_OBJECTS; + global $OUTPUT, $MESSAGE, $RCMAIL, $REMOTE_OBJECTS; - if (!is_array($MESSAGE->parts) && empty($MESSAGE->body)) - return ''; + if (!is_array($MESSAGE->parts) && empty($MESSAGE->body)) { + return ''; + } - if (!$attrib['id']) - $attrib['id'] = 'rcmailMsgBody'; - - $safe_mode = $MESSAGE->is_safe || intval($_GET['_safe']); - $out = ''; - - $header_attrib = array(); - foreach ($attrib as $attr => $value) - if (preg_match('/^headertable([a-z]+)$/i', $attr, $regs)) - $header_attrib[$regs[1]] = $value; - - if (!empty($MESSAGE->parts)) { - foreach ($MESSAGE->parts as $part) { - if ($part->type == 'headers') { - $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers)); - } - else if ($part->type == 'content') { - // unsupported (e.g. encrypted) - if ($part->realtype) { - if ($part->realtype == 'multipart/encrypted' || $part->realtype == 'application/pkcs7-mime') { - $out .= html::span('part-notice', rcube_label('encryptedmessage')); - } - continue; - } - else if (!$part->size) { - continue; - } - // Check if we have enough memory to handle the message in it - // #1487424: we need up to 10x more memory than the body - else if (!rcmail_mem_check($part->size * 10)) { - $out .= html::span('part-notice', rcube_label('messagetoobig'). ' ' - . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id - .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download'))); - continue; + if (!$attrib['id']) + $attrib['id'] = 'rcmailMsgBody'; + + $safe_mode = $MESSAGE->is_safe || intval($_GET['_safe']); + $out = ''; + + $header_attrib = array(); + foreach ($attrib as $attr => $value) { + if (preg_match('/^headertable([a-z]+)$/i', $attr, $regs)) { + $header_attrib[$regs[1]] = $value; } + } - if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset'])) - $part->ctype_parameters['charset'] = $MESSAGE->headers->charset; + if (!empty($MESSAGE->parts)) { + foreach ($MESSAGE->parts as $part) { + if ($part->type == 'headers') { + $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers)); + } + else if ($part->type == 'content') { + // unsupported (e.g. encrypted) + if ($part->realtype) { + if ($part->realtype == 'multipart/encrypted' || $part->realtype == 'application/pkcs7-mime') { + $out .= html::span('part-notice', $RCMAIL->gettext('encryptedmessage')); + } + continue; + } + else if (!$part->size) { + continue; + } - // fetch part if not available - if (!isset($part->body)) - $part->body = $MESSAGE->get_part_content($part->mime_id); + // Check if we have enough memory to handle the message in it + // #1487424: we need up to 10x more memory than the body + else if (!rcube_utils::mem_check($part->size * 10)) { + $out .= html::span('part-notice', $RCMAIL->gettext('messagetoobig'). ' ' + . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id + .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), $RCMAIL->gettext('download'))); + continue; + } - // extract headers from message/rfc822 parts - if ($part->mimetype == 'message/rfc822') { - $msgpart = rcube_mime::parse_message($part->body); - if (!empty($msgpart->headers)) { - $part = $msgpart; - $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers)); - } - } + if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset'])) { + $part->ctype_parameters['charset'] = $MESSAGE->headers->charset; + } - // message is cached but not exists (#1485443), or other error - if ($part->body === false) { - rcmail_message_error($MESSAGE->uid); - } + // fetch part if not available + if (!isset($part->body)) { + $part->body = $MESSAGE->get_part_content($part->mime_id); + } + + // extract headers from message/rfc822 parts + if ($part->mimetype == 'message/rfc822') { + $msgpart = rcube_mime::parse_message($part->body); + if (!empty($msgpart->headers)) { + $part = $msgpart; + $out .= html::div('message-partheaders', rcmail_message_headers(sizeof($header_attrib) ? $header_attrib : null, $part->headers)); + } + } - $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', array( - 'part' => $part, 'prefix' => '')); + // message is cached but not exists (#1485443), or other error + if ($part->body === false) { + rcmail_message_error($MESSAGE->uid); + } + + $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', + array('part' => $part, 'prefix' => '')); - $body = rcmail_print_body($part, array('safe' => $safe_mode, 'plain' => !$CONFIG['prefer_html'])); + $body = rcmail_print_body($part, array('safe' => $safe_mode, 'plain' => !$RCMAIL->config->get('prefer_html'))); - if ($part->ctype_secondary == 'html') { - $body = rcmail_html4inline($body, $attrib['id'], 'rcmBody', $attrs, $safe_mode); - $div_attr = array('class' => 'message-htmlpart'); - $style = array(); + if ($part->ctype_secondary == 'html') { + $body = rcmail_html4inline($body, $attrib['id'], 'rcmBody', $attrs, $safe_mode); + $div_attr = array('class' => 'message-htmlpart'); + $style = array(); - if (!empty($attrs)) { - foreach ($attrs as $a_idx => $a_val) - $style[] = $a_idx . ': ' . $a_val; - if (!empty($style)) - $div_attr['style'] = implode('; ', $style); - } + if (!empty($attrs)) { + foreach ($attrs as $a_idx => $a_val) + $style[] = $a_idx . ': ' . $a_val; + if (!empty($style)) + $div_attr['style'] = implode('; ', $style); + } - $out .= html::div($div_attr, $plugin['prefix'] . $body); + $out .= html::div($div_attr, $plugin['prefix'] . $body); + } + else + $out .= html::div('message-part', $plugin['prefix'] . $body); + } } - else - $out .= html::div('message-part', $plugin['prefix'] . $body); - } - } - } - else { - // Check if we have enough memory to handle the message in it - // #1487424: we need up to 10x more memory than the body - if (!rcmail_mem_check(strlen($MESSAGE->body) * 10)) { - $out .= html::span('part-notice', rcube_label('messagetoobig'). ' ' - . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part=0' - .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download'))); } else { - $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', array( - 'part' => $MESSAGE, 'prefix' => '')); + // Check if we have enough memory to handle the message in it + // #1487424: we need up to 10x more memory than the body + if (!rcube_utils::mem_check(strlen($MESSAGE->body) * 10)) { + $out .= html::span('part-notice', $RCMAIL->gettext('messagetoobig'). ' ' + . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part=0' + .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), $RCMAIL->gettext('download'))); + } + else { + $plugin = $RCMAIL->plugins->exec_hook('message_body_prefix', + array('part' => $MESSAGE, 'prefix' => '')); - $out .= html::div('message-part', $plugin['prefix'] . html::tag('pre', array(), - rcmail_plain_body(Q($MESSAGE->body, 'strict', false)))); + $out .= html::div('message-part', $plugin['prefix'] . html::tag('pre', array(), + rcmail_plain_body(rcube::Q($MESSAGE->body, 'strict', false)))); + } } - } - // list images after mail body - if ($RCMAIL->config->get('inline_images', true) && !empty($MESSAGE->attachments)) { - $thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240); - $client_mimetypes = (array)$RCMAIL->config->get('client_mimetypes'); - - foreach ($MESSAGE->attachments as $attach_prop) { - // skip inline images - if ($attach_prop->content_id && $attach_prop->disposition == 'inline') { - continue; - } - - // Content-Type: image/*... - if ($mimetype = rcmail_part_image_type($attach_prop)) { - // display thumbnails - if ($thumbnail_size) { - $show_link = array( - 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false), - 'onclick' => sprintf( - 'return %s.command(\'load-attachment\',\'%s\',this)', - JS_OBJECT_NAME, - $attach_prop->mime_id) - ); - $out .= html::p('image-attachment', - html::a($show_link + array('class' => 'image-link', 'style' => sprintf('width:%dpx', $thumbnail_size)), - html::img(array( - 'class' => 'image-thumbnail', - 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, 'image') . '&_thumb=1', - 'title' => $attach_prop->filename, - 'alt' => $attach_prop->filename, - 'style' => sprintf('max-width:%dpx; max-height:%dpx', $thumbnail_size, $thumbnail_size), - )) - ) . - html::span('image-filename', Q($attach_prop->filename)) . - html::span('image-filesize', Q($RCMAIL->message_part_size($attach_prop))) . - html::span('attachment-links', - (in_array($mimetype, $client_mimetypes) ? html::a($show_link, rcube_label('showattachment')) . ' ' : '') . - html::a($show_link['href'] . '&_download=1', rcube_label('download')) - ) . - html::br(array('style' => 'clear:both')) - ); - } - else { - $out .= html::tag('fieldset', 'image-attachment', - html::tag('legend', 'image-filename', Q($attach_prop->filename)) . - html::p(array('align' => "center"), - html::img(array( - 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, 'image'), - 'title' => $attach_prop->filename, - 'alt' => $attach_prop->filename, - ))) - ); + // list images after mail body + if ($RCMAIL->config->get('inline_images', true) && !empty($MESSAGE->attachments)) { + $thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240); + $client_mimetypes = (array)$RCMAIL->config->get('client_mimetypes'); + + foreach ($MESSAGE->attachments as $attach_prop) { + // skip inline images + if ($attach_prop->content_id && $attach_prop->disposition == 'inline') { + continue; + } + + // Content-Type: image/*... + if ($mimetype = rcmail_part_image_type($attach_prop)) { + // display thumbnails + if ($thumbnail_size) { + $show_link = array( + 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false), + 'onclick' => sprintf( + 'return %s.command(\'load-attachment\',\'%s\',this)', + rcmail_output::JS_OBJECT_NAME, + $attach_prop->mime_id) + ); + $out .= html::p('image-attachment', + html::a($show_link + array('class' => 'image-link', 'style' => sprintf('width:%dpx', $thumbnail_size)), + html::img(array( + 'class' => 'image-thumbnail', + 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, 'image') . '&_thumb=1', + 'title' => $attach_prop->filename, + 'alt' => $attach_prop->filename, + 'style' => sprintf('max-width:%dpx; max-height:%dpx', $thumbnail_size, $thumbnail_size), + )) + ) . + html::span('image-filename', rcube::Q($attach_prop->filename)) . + html::span('image-filesize', rcube::Q($RCMAIL->message_part_size($attach_prop))) . + html::span('attachment-links', + (in_array($mimetype, $client_mimetypes) ? html::a($show_link, $RCMAIL->gettext('showattachment')) . ' ' : '') . + html::a($show_link['href'] . '&_download=1', $RCMAIL->gettext('download')) + ) . + html::br(array('style' => 'clear:both')) + ); + } + else { + $out .= html::tag('fieldset', 'image-attachment', + html::tag('legend', 'image-filename', rcube::Q($attach_prop->filename)) . + html::p(array('align' => 'center'), + html::img(array( + 'src' => $MESSAGE->get_part_url($attach_prop->mime_id, 'image'), + 'title' => $attach_prop->filename, + 'alt' => $attach_prop->filename, + ))) + ); + } + } } - } } - } - // tell client that there are blocked remote objects - if ($REMOTE_OBJECTS && !$safe_mode) - $OUTPUT->set_env('blockedobjects', true); + // tell client that there are blocked remote objects + if ($REMOTE_OBJECTS && !$safe_mode) { + $OUTPUT->set_env('blockedobjects', true); + } - return html::div($attrib, $out); + return html::div($attrib, $out); } function rcmail_part_image_type($part) { - $rcmail = rcmail::get_instance(); + $rcmail = rcmail::get_instance(); - // Skip TIFF images if browser doesn't support this format... - $tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']); - // until we can convert them to JPEG - $tiff_support = $tiff_support || $rcmail->config->get('im_convert_path'); + // Skip TIFF images if browser doesn't support this format... + $tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']); + // until we can convert them to JPEG + $tiff_support = $tiff_support || $rcmail->config->get('im_convert_path'); - // Content-type regexp - $mime_regex = $tiff_support ? '/^image\//i' : '/^image\/(?!tif)/i'; + // Content-type regexp + $mime_regex = $tiff_support ? '/^image\//i' : '/^image\/(?!tif)/i'; - // Content-Type: image/*... - if (preg_match($mime_regex, $part->mimetype)) { - return rcmail_fix_mimetype($part->mimetype); - } + // Content-Type: image/*... + if (preg_match($mime_regex, $part->mimetype)) { + return rcmail_fix_mimetype($part->mimetype); + } - // Many clients use application/octet-stream, we'll detect mimetype - // by checking filename extension - - // Supported image filename extensions to image type map - $types = array( - 'jpg' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'png' => 'image/png', - 'gif' => 'image/gif', - 'bmp' => 'image/bmp', - ); - if ($tiff_support) { - $types['tif'] = 'image/tiff'; - $types['tiff'] = 'image/tiff'; - } + // Many clients use application/octet-stream, we'll detect mimetype + // by checking filename extension - if ($part->filename - && preg_match('/^application\/octet-stream$/i', $part->mimetype) - && preg_match('/\.([^.]+)$/i', $part->filename, $m) - && ($extension = strtolower($m[1])) - && isset($types[$extension]) - ) { - return $types[$extension]; - } -} + // Supported image filename extensions to image type map + $types = array( + 'jpg' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'png' => 'image/png', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + ); + if ($tiff_support) { + $types['tif'] = 'image/tiff'; + $types['tiff'] = 'image/tiff'; + } + if ($part->filename + && preg_match('/^application\/octet-stream$/i', $part->mimetype) + && preg_match('/\.([^.]+)$/i', $part->filename, $m) + && ($extension = strtolower($m[1])) + && isset($types[$extension]) + ) { + return $types[$extension]; + } +} /** * modify a HTML message that it can be displayed inside a HTML page */ function rcmail_html4inline($body, $container_id, $body_id='', &$attributes=null, $allow_remote=false) { - $last_style_pos = 0; - $cont_id = $container_id.($body_id ? ' div.'.$body_id : ''); + $last_style_pos = 0; + $cont_id = $container_id.($body_id ? ' div.'.$body_id : ''); - // find STYLE tags - while (($pos = stripos($body, '<style', $last_style_pos)) && ($pos2 = stripos($body, '</style>', $pos))) - { - $pos = strpos($body, '>', $pos) + 1; - $len = $pos2 - $pos; + // find STYLE tags + while (($pos = stripos($body, '<style', $last_style_pos)) && ($pos2 = stripos($body, '</style>', $pos))) { + $pos = strpos($body, '>', $pos) + 1; + $len = $pos2 - $pos; - // replace all css definitions with #container [def] - $styles = substr($body, $pos, $len); - $styles = rcmail_mod_css_styles($styles, $cont_id, $allow_remote); + // replace all css definitions with #container [def] + $styles = substr($body, $pos, $len); + $styles = rcube_utils::mod_css_styles($styles, $cont_id, $allow_remote); - $body = substr_replace($body, $styles, $pos, $len); - $last_style_pos = $pos2 + strlen($styles) - $len; - } + $body = substr_replace($body, $styles, $pos, $len); + $last_style_pos = $pos2 + strlen($styles) - $len; + } + + // modify HTML links to open a new window if clicked + $GLOBALS['rcmail_html_container_id'] = $container_id; + $body = preg_replace_callback('/<(a|link|area)\s+([^>]+)>/Ui', 'rcmail_alter_html_link', $body); + unset($GLOBALS['rcmail_html_container_id']); + + $body = preg_replace(array( + // add comments arround html and other tags + '/(<!DOCTYPE[^>]*>)/i', + '/(<\?xml[^>]*>)/i', + '/(<\/?html[^>]*>)/i', + '/(<\/?head[^>]*>)/i', + '/(<title[^>]*>.*<\/title>)/Ui', + '/(<\/?meta[^>]*>)/i', + // quote <? of php and xml files that are specified as text/html + '/<\?/', + '/\?>/', + // replace <body> with <div> + '/<body([^>]*)>/i', + '/<\/body>/i', + ), + array( + '<!--\\1-->', + '<!--\\1-->', + '<!--\\1-->', + '<!--\\1-->', + '<!--\\1-->', + '<!--\\1-->', + '<?', + '?>', + '<div class="'.$body_id.'"\\1>', + '</div>', + ), + $body); + + $attributes = array(); + + // Handle body attributes that doesn't play nicely with div elements + $regexp = '/<div class="' . preg_quote($body_id, '/') . '"([^>]*)/'; + if (preg_match($regexp, $body, $m)) { + $attrs = $m[0]; - // modify HTML links to open a new window if clicked - $GLOBALS['rcmail_html_container_id'] = $container_id; - $body = preg_replace_callback('/<(a|link|area)\s+([^>]+)>/Ui', 'rcmail_alter_html_link', $body); - unset($GLOBALS['rcmail_html_container_id']); - - $body = preg_replace(array( - // add comments arround html and other tags - '/(<!DOCTYPE[^>]*>)/i', - '/(<\?xml[^>]*>)/i', - '/(<\/?html[^>]*>)/i', - '/(<\/?head[^>]*>)/i', - '/(<title[^>]*>.*<\/title>)/Ui', - '/(<\/?meta[^>]*>)/i', - // quote <? of php and xml files that are specified as text/html - '/<\?/', - '/\?>/', - // replace <body> with <div> - '/<body([^>]*)>/i', - '/<\/body>/i', - ), - array( - '<!--\\1-->', - '<!--\\1-->', - '<!--\\1-->', - '<!--\\1-->', - '<!--\\1-->', - '<!--\\1-->', - '<?', - '?>', - '<div class="'.$body_id.'"\\1>', - '</div>', - ), - $body); - - $attributes = array(); - - // Handle body attributes that doesn't play nicely with div elements - $regexp = '/<div class="' . preg_quote($body_id, '/') . '"([^>]*)/'; - if (preg_match($regexp, $body, $m)) { - $attrs = $m[0]; - // Get bgcolor, we'll set it as background-color of the message container - if ($m[1] && preg_match('/bgcolor=["\']*([a-z0-9#]+)["\']*/', $attrs, $mb)) { - $attributes['background-color'] = $mb[1]; - $attrs = preg_replace('/bgcolor=["\']*([a-z0-9#]+)["\']*/', '', $attrs); - } - // Get background, we'll set it as background-image of the message container - if ($m[1] && preg_match('/background=["\']*([^"\'>\s]+)["\']*/', $attrs, $mb)) { - $attributes['background-image'] = 'url('.$mb[1].')'; - $attrs = preg_replace('/background=["\']*([^"\'>\s]+)["\']*/', '', $attrs); - } - if (!empty($attributes)) { - $body = preg_replace($regexp, rtrim($attrs), $body, 1); - } - - // handle body styles related to background image - if ($attributes['background-image']) { - // get body style - if (preg_match('/#'.preg_quote($cont_id, '/').'\s+\{([^}]+)}/i', $body, $m)) { - // get background related style - if (preg_match_all('/(background-position|background-repeat)\s*:\s*([^;]+);/i', $m[1], $ma, PREG_SET_ORDER)) { - foreach ($ma as $style) - $attributes[$style[1]] = $style[2]; + // Get bgcolor, we'll set it as background-color of the message container + if ($m[1] && preg_match('/bgcolor=["\']*([a-z0-9#]+)["\']*/i', $attrs, $mb)) { + $attributes['background-color'] = $mb[1]; + $attrs = preg_replace('/bgcolor=["\']*[a-z0-9#]+["\']*/i', '', $attrs); + } + + // Get background, we'll set it as background-image of the message container + if ($m[1] && preg_match('/background=["\']*([^"\'>\s]+)["\']*/', $attrs, $mb)) { + $attributes['background-image'] = 'url('.$mb[1].')'; + $attrs = preg_replace('/background=["\']*([^"\'>\s]+)["\']*/', '', $attrs); + } + + if (!empty($attributes)) { + $body = preg_replace($regexp, rtrim($attrs), $body, 1); + } + + // handle body styles related to background image + if ($attributes['background-image']) { + // get body style + if (preg_match('/#'.preg_quote($cont_id, '/').'\s+\{([^}]+)}/i', $body, $m)) { + // get background related style + $regexp = '/(background-position|background-repeat)\s*:\s*([^;]+);/i'; + if (preg_match_all($regexp, $m[1], $ma, PREG_SET_ORDER)) { + foreach ($ma as $style) { + $attributes[$style[1]] = $style[2]; + } + } + } } - } } - } - // make sure there's 'rcmBody' div, we need it for proper css modification - // its name is hardcoded in rcmail_message_body() also - else { - $body = '<div class="' . $body_id . '">' . $body . '</div>'; - } + // make sure there's 'rcmBody' div, we need it for proper css modification + // its name is hardcoded in rcmail_message_body() also + else { + $body = '<div class="' . $body_id . '">' . $body . '</div>'; + } - return $body; + return $body; } - /** * parse link (a, link, area) attributes and set correct target */ function rcmail_alter_html_link($matches) { - global $RCMAIL; + global $RCMAIL; - $tag = strtolower($matches[1]); - $attrib = parse_attrib_string($matches[2]); - $end = '>'; + $tag = strtolower($matches[1]); + $attrib = html::parse_attrib_string($matches[2]); + $end = '>'; - // Remove non-printable characters in URL (#1487805) - if ($attrib['href']) - $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', $attrib['href']); + // Remove non-printable characters in URL (#1487805) + if ($attrib['href']) + $attrib['href'] = preg_replace('/[\x00-\x1F]/', '', $attrib['href']); - if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href'])) { - $tempurl = 'tmp-' . md5($attrib['href']) . '.css'; - $_SESSION['modcssurls'][$tempurl] = $attrib['href']; - $attrib['href'] = $RCMAIL->url(array('task' => 'utils', 'action' => 'modcss', 'u' => $tempurl, 'c' => $GLOBALS['rcmail_html_container_id'])); - $end = ' />'; - } - else if (preg_match('/^mailto:(.+)/i', $attrib['href'], $mailto)) { - list($mailto, $url) = explode('?', html_entity_decode($mailto[1], ENT_QUOTES, 'UTF-8'), 2); - - $url = urldecode($url); - $mailto = urldecode($mailto); - $addresses = rcube_mime::decode_address_list($mailto, null, true); - $mailto = array(); - - // do sanity checks on recipients - foreach ($addresses as $idx => $addr) { - if (rcube_utils::check_email($addr['mailto'], false)) { - $addresses[$idx] = $addr['mailto']; - $mailto[] = $addr['string']; - } - else { - unset($addresses[$idx]); - } - } - - if (!empty($addresses)) { - $attrib['href'] = 'mailto:' . implode(',', $addresses); - $attrib['onclick'] = sprintf( - "return %s.command('compose','%s',this)", - JS_OBJECT_NAME, - JQ(implode(',', $mailto) . ($url ? "?$url" : ''))); + if ($tag == 'link' && preg_match('/^https?:\/\//i', $attrib['href'])) { + $tempurl = 'tmp-' . md5($attrib['href']) . '.css'; + $_SESSION['modcssurls'][$tempurl] = $attrib['href']; + $attrib['href'] = $RCMAIL->url(array('task' => 'utils', 'action' => 'modcss', 'u' => $tempurl, 'c' => $GLOBALS['rcmail_html_container_id'])); + $end = ' />'; } - else { - $attrib['href'] = '#NOP'; - $attrib['onclick'] = ''; + else if (preg_match('/^mailto:(.+)/i', $attrib['href'], $mailto)) { + list($mailto, $url) = explode('?', html_entity_decode($mailto[1], ENT_QUOTES, 'UTF-8'), 2); + + $url = urldecode($url); + $mailto = urldecode($mailto); + $addresses = rcube_mime::decode_address_list($mailto, null, true); + $mailto = array(); + + // do sanity checks on recipients + foreach ($addresses as $idx => $addr) { + if (rcube_utils::check_email($addr['mailto'], false)) { + $addresses[$idx] = $addr['mailto']; + $mailto[] = $addr['string']; + } + else { + unset($addresses[$idx]); + } + } + + if (!empty($addresses)) { + $attrib['href'] = 'mailto:' . implode(',', $addresses); + $attrib['onclick'] = sprintf( + "return %s.command('compose','%s',this)", + rcmail_output::JS_OBJECT_NAME, + rcube::JQ(implode(',', $mailto) . ($url ? "?$url" : ''))); + } + else { + $attrib['href'] = '#NOP'; + $attrib['onclick'] = ''; + } + } + else if (empty($attrib['href']) && !$attrib['name']) { + $attrib['href'] = './#NOP'; + $attrib['onclick'] = 'return false'; + } + else if (!empty($attrib['href']) && $attrib['href'][0] != '#') { + $attrib['target'] = '_blank'; } - } - else if (empty($attrib['href']) && !$attrib['name']) { - $attrib['href'] = './#NOP'; - $attrib['onclick'] = 'return false'; - } - else if (!empty($attrib['href']) && $attrib['href'][0] != '#') { - $attrib['target'] = '_blank'; - } - // Better security by adding rel="noreferrer" (#1484686) - if (($tag == 'a' || $tag == 'area') && $attrib['href'] && $attrib['href'][0] != '#') { - $attrib['rel'] = 'noreferrer'; - } + // Better security by adding rel="noreferrer" (#1484686) + if (($tag == 'a' || $tag == 'area') && $attrib['href'] && $attrib['href'][0] != '#') { + $attrib['rel'] = 'noreferrer'; + } - // allowed attributes for a|link|area tags - $allow = array('href','name','target','onclick','id','class','style','title', - 'rel','type','media','alt','coords','nohref','hreflang','shape'); + // allowed attributes for a|link|area tags + $allow = array('href','name','target','onclick','id','class','style','title', + 'rel','type','media','alt','coords','nohref','hreflang','shape'); - return "<$tag" . html::attrib_string($attrib, $allow) . $end; + return "<$tag" . html::attrib_string($attrib, $allow) . $end; } - /** * decode address string and re-format it as HTML links */ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null, $default_charset=null, $title=null) { - global $RCMAIL, $PRINT_MODE, $CONFIG; + global $RCMAIL, $PRINT_MODE; + + $a_parts = rcube_mime::decode_address_list($input, null, true, $default_charset); - $a_parts = rcube_mime::decode_address_list($input, null, true, $default_charset); + if (!sizeof($a_parts)) { + return $input; + } - if (!sizeof($a_parts)) - return $input; + $c = count($a_parts); + $j = 0; + $out = ''; + $allvalues = array(); + $show_email = $RCMAIL->config->get('message_show_email'); - $c = count($a_parts); - $j = 0; - $out = ''; - $allvalues = array(); - $show_email = $RCMAIL->config->get('message_show_email'); + if ($addicon && !isset($_SESSION['writeable_abook'])) { + $_SESSION['writeable_abook'] = $RCMAIL->get_address_sources(true) ? true : false; + } - if ($addicon && !isset($_SESSION['writeable_abook'])) { - $_SESSION['writeable_abook'] = $RCMAIL->get_address_sources(true) ? true : false; - } + foreach ($a_parts as $part) { + $j++; - foreach ($a_parts as $part) { - $j++; - $name = $part['name']; - $mailto = $part['mailto']; - $string = $part['string']; - $valid = check_email($mailto, false); - - // phishing email prevention (#1488981), e.g. "valid@email.addr <phishing@email.addr>" - if (!$show_email && $valid && $name && $name != $mailto && strpos($name, '@')) { - $name = ''; - } - - // IDNA ASCII to Unicode - if ($name == $mailto) - $name = rcube_idn_to_utf8($name); - if ($string == $mailto) - $string = rcube_idn_to_utf8($string); - $mailto = rcube_idn_to_utf8($mailto); - - if ($PRINT_MODE) { - $address = sprintf('%s <%s>', Q($name), Q($mailto)); - } - else if ($valid) { - if ($linked) { - $attrs = array( - 'href' => 'mailto:' . $mailto, - 'onclick' => sprintf("return %s.command('compose','%s',this)", JS_OBJECT_NAME, JQ(format_email_recipient($mailto, $name))), - 'class' => "rcmContactAddress", - ); + $name = $part['name']; + $mailto = $part['mailto']; + $string = $part['string']; + $valid = rcube_utils::check_email($mailto, false); - if ($show_email && $name && $mailto) { - $content = Q($name ? sprintf('%s <%s>', $name, $mailto) : $mailto); + // phishing email prevention (#1488981), e.g. "valid@email.addr <phishing@email.addr>" + if (!$show_email && $valid && $name && $name != $mailto && strpos($name, '@')) { + $name = ''; } - else { - $content = Q($name ? $name : $mailto); - $attrs['title'] = $mailto; + + // IDNA ASCII to Unicode + if ($name == $mailto) + $name = rcube_utils::idn_to_utf8($name); + if ($string == $mailto) + $string = rcube_utils::idn_to_utf8($string); + $mailto = rcube_utils::idn_to_utf8($mailto); + + if ($PRINT_MODE) { + $address = sprintf('%s <%s>', rcube::Q($name), rcube::Q($mailto)); } + else if ($valid) { + if ($linked) { + $attrs = array( + 'href' => 'mailto:' . $mailto, + 'class' => 'rcmContactAddress', + 'onclick' => sprintf("return %s.command('compose','%s',this)", + rcmail_output::JS_OBJECT_NAME, rcube::JQ(format_email_recipient($mailto, $name))), + ); + + if ($show_email && $name && $mailto) { + $content = rcube::Q($name ? sprintf('%s <%s>', $name, $mailto) : $mailto); + } + else { + $content = rcube::Q($name ? $name : $mailto); + $attrs['title'] = $mailto; + } - $address = html::a($attrs, $content); - } - else { - $address = html::span(array('title' => $mailto, 'class' => "rcmContactAddress"), - Q($name ? $name : $mailto)); - } - - if ($addicon && $_SESSION['writeable_abook']) { - $address .= html::a(array( - 'href' => "#add", - 'onclick' => sprintf("return %s.command('add-contact','%s',this)", JS_OBJECT_NAME, JQ($string)), - 'title' => rcube_label('addtoaddressbook'), - 'class' => 'rcmaddcontact', - ), - html::img(array( - 'src' => $CONFIG['skin_path'] . $addicon, - 'alt' => "Add contact", - ))); - } - } - else { - $address = ''; - if ($name) - $address .= Q($name); - if ($mailto) - $address = trim($address . ' ' . Q($name ? sprintf('<%s>', $mailto) : $mailto)); - } + $address = html::a($attrs, $content); + } + else { + $address = html::span(array('title' => $mailto, 'class' => "rcmContactAddress"), + rcube::Q($name ? $name : $mailto)); + } - $address = html::span('adr', $address); - $allvalues[] = $address; + if ($addicon && $_SESSION['writeable_abook']) { + $address .= html::a(array( + 'href' => "#add", + 'title' => $RCMAIL->gettext('addtoaddressbook'), + 'class' => 'rcmaddcontact', + 'onclick' => sprintf("return %s.command('add-contact','%s',this)", + rcmail_output::JS_OBJECT_NAME, rcube::JQ($string)), + ), + html::img(array( + 'src' => $RCMAIL->config->get('skin_path') . $addicon, + 'alt' => "Add contact", + ))); + } + } + else { + $address = ''; + if ($name) + $address .= rcube::Q($name); + if ($mailto) + $address = trim($address . ' ' . rcube::Q($name ? sprintf('<%s>', $mailto) : $mailto)); + } - if (!$moreadrs) - $out .= ($out ? ', ' : '') . $address; + $address = html::span('adr', $address); + $allvalues[] = $address; - if ($max && $j == $max && $c > $j) { - if ($linked) { - $moreadrs = $c - $j; - } - else { - $out .= '...'; - break; - } - } - } + if (!$moreadrs) + $out .= ($out ? ', ' : '') . $address; - if ($moreadrs) { - if ($PRINT_MODE) { - $out .= ' ' . html::a(array( - 'href' => '#more', - 'class' => 'morelink', - 'onclick' => '$(this).hide().next().show()', - ), Q(rcube_label(array('name' => 'andnmore', 'vars' => array('nr' => $moreadrs))))) . - html::span(array('style' => 'display:none'), join(', ', $allvalues)); + if ($max && $j == $max && $c > $j) { + if ($linked) { + $moreadrs = $c - $j; + } + else { + $out .= '...'; + break; + } + } } - else { - $out .= ' ' . html::a(array( - 'href' => '#more', - 'class' => 'morelink', - 'onclick' => sprintf("return %s.show_popup_dialog('%s','%s')", - JS_OBJECT_NAME, - JQ(join(', ', $allvalues)), - JQ($title)) - ), - Q(rcube_label(array('name' => 'andnmore', 'vars' => array('nr' => $moreadrs))))); + + if ($moreadrs) { + if ($PRINT_MODE) { + $out .= ' ' . html::a(array( + 'href' => '#more', + 'class' => 'morelink', + 'onclick' => '$(this).hide().next().show()', + ), + rcube::Q($RCMAIL->gettext(array('name' => 'andnmore', 'vars' => array('nr' => $moreadrs))))) + . html::span(array('style' => 'display:none'), join(', ', $allvalues)); + } + else { + $out .= ' ' . html::a(array( + 'href' => '#more', + 'class' => 'morelink', + 'onclick' => sprintf("return %s.show_popup_dialog('%s','%s')", + rcmail_output::JS_OBJECT_NAME, + rcube::JQ(join(', ', $allvalues)), + rcube::JQ($title)) + ), + rcube::Q($RCMAIL->gettext(array('name' => 'andnmore', 'vars' => array('nr' => $moreadrs))))); + } } - } - return $out; + return $out; } - /** * Wrap text to a given number of characters per line * but respect the mail quotation of replies messages (>). @@ -1638,74 +1701,79 @@ function rcmail_address_string($input, $max=null, $linked=false, $addicon=null, */ function rcmail_wrap_and_quote($text, $length = 72) { - // Rebuild the message body with a maximum of $max chars, while keeping quoted message. - $max = max(75, $length + 8); - $lines = preg_split('/\r?\n/', trim($text)); - $out = ''; - - foreach ($lines as $line) { - // don't wrap already quoted lines - if ($line[0] == '>') - $line = '>' . rtrim($line); - else if (mb_strlen($line) > $max) { - $newline = ''; - foreach (explode("\n", rc_wordwrap($line, $length - 2)) as $l) { - if (strlen($l)) - $newline .= '> ' . $l . "\n"; - else - $newline .= ">\n"; - } - $line = rtrim($newline); - } - else - $line = '> ' . $line; + // Rebuild the message body with a maximum of $max chars, while keeping quoted message. + $max = max(75, $length + 8); + $lines = preg_split('/\r?\n/', trim($text)); + $out = ''; + + foreach ($lines as $line) { + // don't wrap already quoted lines + if ($line[0] == '>') { + $line = '>' . rtrim($line); + } + else if (mb_strlen($line) > $max) { + $newline = ''; + + foreach (explode("\n", rcube_mime::wordwrap($line, $length - 2)) as $l) { + if (strlen($l)) + $newline .= '> ' . $l . "\n"; + else + $newline .= ">\n"; + } - // Append the line - $out .= $line . "\n"; - } + $line = rtrim($newline); + } + else { + $line = '> ' . $line; + } - return rtrim($out, "\n"); -} + // Append the line + $out .= $line . "\n"; + } + return rtrim($out, "\n"); +} function rcmail_draftinfo_encode($p) { - $parts = array(); - foreach ($p as $key => $val) - $parts[] = $key . '=' . ($key == 'folder' ? base64_encode($val) : $val); + $parts = array(); + foreach ($p as $key => $val) { + $parts[] = $key . '=' . ($key == 'folder' ? base64_encode($val) : $val); + } - return join('; ', $parts); + return join('; ', $parts); } - function rcmail_draftinfo_decode($str) { - $info = array(); - foreach (preg_split('/;\s+/', $str) as $part) { - list($key, $val) = explode('=', $part, 2); - if ($key == 'folder') - $val = base64_decode($val); - $info[$key] = $val; - } + $info = array(); - return $info; -} + foreach (preg_split('/;\s+/', $str) as $part) { + list($key, $val) = explode('=', $part, 2); + if ($key == 'folder') { + $val = base64_decode($val); + } + $info[$key] = $val; + } + + return $info; +} /** * clear message composing settings */ function rcmail_compose_cleanup($id) { - if (!isset($_SESSION['compose_data_'.$id])) - return; + if (!isset($_SESSION['compose_data_'.$id])) { + return; + } - $rcmail = rcmail::get_instance(); - $rcmail->plugins->exec_hook('attachments_cleanup', array('group' => $id)); - $rcmail->session->remove('compose_data_'.$id); + $rcmail = rcmail::get_instance(); + $rcmail->plugins->exec_hook('attachments_cleanup', array('group' => $id)); + $rcmail->session->remove('compose_data_'.$id); } - /** * Send the MDN response * @@ -1716,76 +1784,78 @@ function rcmail_compose_cleanup($id) */ function rcmail_send_mdn($message, &$smtp_error) { - global $RCMAIL; - - if (!is_object($message) || !is_a($message, 'rcube_message')) - $message = new rcube_message($message); - - if ($message->headers->mdn_to && empty($message->headers->flags['MDNSENT']) && - ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*'))) - { - $identity = rcmail_identity_select($message); - $sender = format_email_recipient($identity['email'], $identity['name']); - $recipient = array_shift(rcube_mime::decode_address_list( - $message->headers->mdn_to, 1, true, $message->headers->charset)); - $mailto = $recipient['mailto']; - - $compose = new Mail_mime("\r\n"); - - $compose->setParam('text_encoding', 'quoted-printable'); - $compose->setParam('html_encoding', 'quoted-printable'); - $compose->setParam('head_encoding', 'quoted-printable'); - $compose->setParam('head_charset', RCMAIL_CHARSET); - $compose->setParam('html_charset', RCMAIL_CHARSET); - $compose->setParam('text_charset', RCMAIL_CHARSET); - - // compose headers array - $headers = array( - 'Date' => rcmail_user_date(), - 'From' => $sender, - 'To' => $message->headers->mdn_to, - 'Subject' => rcube_label('receiptread') . ': ' . $message->subject, - 'Message-ID' => rcmail_gen_message_id(), - 'X-Sender' => $identity['email'], - 'References' => trim($message->headers->references . ' ' . $message->headers->messageID), - ); + global $RCMAIL; + + if (!is_object($message) || !is_a($message, 'rcube_message')) { + $message = new rcube_message($message); + } - if ($agent = $RCMAIL->config->get('useragent')) - $headers['User-Agent'] = $agent; + if ($message->headers->mdn_to && empty($message->headers->flags['MDNSENT']) && + ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*')) + ) { + $identity = rcmail_identity_select($message); + $sender = format_email_recipient($identity['email'], $identity['name']); + $recipient = array_shift(rcube_mime::decode_address_list( + $message->headers->mdn_to, 1, true, $message->headers->charset)); + $mailto = $recipient['mailto']; + + $compose = new Mail_mime("\r\n"); + + $compose->setParam('text_encoding', 'quoted-printable'); + $compose->setParam('html_encoding', 'quoted-printable'); + $compose->setParam('head_encoding', 'quoted-printable'); + $compose->setParam('head_charset', RCUBE_CHARSET); + $compose->setParam('html_charset', RCUBE_CHARSET); + $compose->setParam('text_charset', RCUBE_CHARSET); + + // compose headers array + $headers = array( + 'Date' => $RCMAIL->user_date(), + 'From' => $sender, + 'To' => $message->headers->mdn_to, + 'Subject' => $RCMAIL->gettext('receiptread') . ': ' . $message->subject, + 'Message-ID' => $RCMAIL->gen_message_id(), + 'X-Sender' => $identity['email'], + 'References' => trim($message->headers->references . ' ' . $message->headers->messageID), + ); - if ($RCMAIL->config->get('mdn_use_from')) - $options['mdn_use_from'] = true; + $report = "Final-Recipient: rfc822; {$identity['email']}\r\n" + . "Original-Message-ID: {$message->headers->messageID}\r\n" + . "Disposition: manual-action/MDN-sent-manually; displayed\r\n"; - $body = rcube_label("yourmessage") . "\r\n\r\n" . - "\t" . rcube_label("to") . ': ' . rcube_mime::decode_mime_string($message->headers->to, $message->headers->charset) . "\r\n" . - "\t" . rcube_label("subject") . ': ' . $message->subject . "\r\n" . - "\t" . rcube_label("sent") . ': ' . format_date($message->headers->date, $RCMAIL->config->get('date_long')) . "\r\n" . - "\r\n" . rcube_label("receiptnote") . "\r\n"; + if ($message->headers->to) { + $report .= "Original-Recipient: {$message->headers->to}\r\n"; + } - $ua = $RCMAIL->config->get('useragent', "Roundcube Webmail (Version ".RCMAIL_VERSION.")"); - $report = "Reporting-UA: $ua\r\n"; + if ($agent = $RCMAIL->config->get('useragent')) { + $headers['User-Agent'] = $agent; + $report .= "Reporting-UA: $agent\r\n"; + } - if ($message->headers->to) - $report .= "Original-Recipient: {$message->headers->to}\r\n"; + $body = $RCMAIL->gettext("yourmessage") . "\r\n\r\n" . + "\t" . $RCMAIL->gettext("to") . ': ' . rcube_mime::decode_mime_string($message->headers->to, $message->headers->charset) . "\r\n" . + "\t" . $RCMAIL->gettext("subject") . ': ' . $message->subject . "\r\n" . + "\t" . $RCMAIL->gettext("sent") . ': ' . $RCMAIL->format_date($message->headers->date, $RCMAIL->config->get('date_long')) . "\r\n" . + "\r\n" . $RCMAIL->gettext("receiptnote"); - $report .= "Final-Recipient: rfc822; {$identity['email']}\r\n" . - "Original-Message-ID: {$message->headers->messageID}\r\n" . - "Disposition: manual-action/MDN-sent-manually; displayed\r\n"; + $compose->headers($headers); + $compose->setContentType('multipart/report', array('report-type'=> 'disposition-notification')); + $compose->setTXTBody(rcube_mime::wordwrap($body, 75, "\r\n")); + $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline'); - $compose->headers($headers); - $compose->setContentType('multipart/report', array('report-type'=> 'disposition-notification')); - $compose->setTXTBody(rc_wordwrap($body, 75, "\r\n")); - $compose->addAttachment($report, 'message/disposition-notification', 'MDNPart2.txt', false, '7bit', 'inline'); + if ($RCMAIL->config->get('mdn_use_from')) { + $options['mdn_use_from'] = true; + } - $sent = rcmail_deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file, $options); + $sent = $RCMAIL->deliver_message($compose, $identity['email'], $mailto, $smtp_error, $body_file, $options); - if ($sent) { - $RCMAIL->storage->set_flag($message->uid, 'MDNSENT'); - return true; + if ($sent) { + $RCMAIL->storage->set_flag($message->uid, 'MDNSENT'); + return true; + } } - } - return false; + return false; } /** @@ -1821,28 +1891,34 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r } } - $from_idx = null; - $found_idx = null; - $default_identity = 0; // default identity is always first on the list + // decode From: address + $from = rcube_mime::decode_address_list($MESSAGE->headers->from, null, true, $MESSAGE->headers->charset); + $from = array_shift($from); + $from['mailto'] = strtolower($from['mailto']); + + $from_idx = null; + $found_idx = array('to' => null, 'from' => null); + $check_from = in_array($compose_mode, array('draft', 'edit', 'reply')); // Select identity foreach ($identities as $idx => $ident) { - // use From header - if (in_array($compose_mode, array('draft', 'edit'))) { - if ($MESSAGE->headers->from == $ident['ident']) { + // use From: header when in edit/draft or reply-to-self + if ($check_from && $from['mailto'] == strtolower($ident['email_ascii'])) { + // remember first matching identity address + if ($found_idx['from'] === null) { + $found_idx['from'] = $idx; + } + // match identity name + if ($from['name'] && $ident['name'] && $from['name'] == $ident['name']) { $from_idx = $idx; break; } } - // reply to yourself - else if ($compose_mode == 'reply' && $MESSAGE->headers->from == $ident['ident']) { - $from_idx = $idx; - break; - } - // use replied message recipients + // use replied/forwarded message recipients else if (($found = array_search(strtolower($ident['email_ascii']), $a_recipients)) !== false) { - if ($found_idx === null) { - $found_idx = $idx; + // remember first matching identity address + if ($found_idx['to'] === null) { + $found_idx['to'] = $idx; } // match identity name if ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name']) { @@ -1852,22 +1928,27 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r } } - // If matching by name+address doesn't found any matches, get first found address (identity) + // If matching by name+address didn't find any matches, + // get first found identity (address) if any if ($from_idx === null) { - $from_idx = $found_idx; + $from_idx = $found_idx['from'] !== null ? $found_idx['from'] : $found_idx['to']; } // Try Return-Path if ($from_idx === null && ($return_path = $MESSAGE->headers->others['return-path'])) { + $return_path = array_map('strtolower', (array) $return_path); + foreach ($identities as $idx => $ident) { // Return-Path header contains an email address, but on some mailing list // it can be e.g. <pear-dev-return-55250-local=domain.tld@lists.php.net> // where local@domain.tld is the address we're looking for (#1489241) - $ident1 = $ident['email_ascii']; + $ident1 = strtolower($ident['email_ascii']); $ident2 = str_replace('@', '=', $ident1); + $ident1 = '<' . $ident1 . '>'; + $ident2 = '-' . $ident2 . '@'; - foreach ((array)$return_path as $path) { - if (stripos($path, $ident1) !== false || stripos($path, $ident2)) { + foreach ($return_path as $path) { + if ($path == $ident1 || stripos($path, $ident2)) { $from_idx = $idx; break 2; } @@ -1881,36 +1962,41 @@ function rcmail_identity_select($MESSAGE, $identities = null, $compose_mode = 'r $selected = $plugin['selected']; - return $identities[$selected !== null ? $selected : $default_identity]; + // default identity is always first on the list + return $identities[$selected !== null ? $selected : 0]; } // Fixes some content-type names function rcmail_fix_mimetype($name) { - // Some versions of Outlook create garbage Content-Type: - // application/pdf.A520491B_3BF7_494D_8855_7FAC2C6C0608 - if (preg_match('/^application\/pdf.+/', $name)) - $name = 'application/pdf'; - // treat image/pjpeg (image/pjpg, image/jpg) as image/jpeg (#1489097) - else if (preg_match('/^image\/p?jpe?g$/', $name)) - $name = 'image/jpeg'; - - return $name; + // Some versions of Outlook create garbage Content-Type: + // application/pdf.A520491B_3BF7_494D_8855_7FAC2C6C0608 + if (preg_match('/^application\/pdf.+/', $name)) { + $name = 'application/pdf'; + } + // treat image/pjpeg (image/pjpg, image/jpg) as image/jpeg (#1489097) + else if (preg_match('/^image\/p?jpe?g$/', $name)) { + $name = 'image/jpeg'; + } + + return $name; } // return attachment filename, handle empty filename case function rcmail_attachment_name($attachment, $display = false) { + global $RCMAIL; + $filename = $attachment->filename; if ($filename === null || $filename === '') { if ($attachment->mimetype == 'text/html') { - $filename = rcube_label('htmlmessage'); + $filename = $RCMAIL->gettext('htmlmessage'); } else { $ext = (array) rcube_mime::get_mime_extensions($attachment->mimetype); $ext = array_shift($ext); - $filename = rcube_label('messagepart') . ' ' . $attachment->mime_id; + $filename = $RCMAIL->gettext('messagepart') . ' ' . $attachment->mime_id; if ($ext) { $filename .= '.' . $ext; } @@ -1922,7 +2008,7 @@ function rcmail_attachment_name($attachment, $display = false) // Display smart names for some known mimetypes if ($display) { if (preg_match('/application\/(pgp|pkcs7)-signature/i', $attachment->mimetype)) { - $filename = rcube_label('digitalsig'); + $filename = $RCMAIL->gettext('digitalsig'); } } @@ -1931,92 +2017,104 @@ function rcmail_attachment_name($attachment, $display = false) function rcmail_search_filter($attrib) { - global $OUTPUT, $CONFIG; + global $RCMAIL; - if (!strlen($attrib['id'])) - $attrib['id'] = 'rcmlistfilter'; + if (!strlen($attrib['id'])) + $attrib['id'] = 'rcmlistfilter'; - $attrib['onchange'] = JS_OBJECT_NAME.'.filter_mailbox(this.value)'; + $attrib['onchange'] = rcmail_output::JS_OBJECT_NAME.'.filter_mailbox(this.value)'; - // Content-Type values of messages with attachments - // the same as in app.js:add_message_row() - $ctypes = array('application/', 'multipart/m', 'multipart/signed', 'multipart/report'); + // Content-Type values of messages with attachments + // the same as in app.js:add_message_row() + $ctypes = array('application/', 'multipart/m', 'multipart/signed', 'multipart/report'); - // Build search string of "with attachment" filter - $attachment = str_repeat(' OR', count($ctypes)-1); - foreach ($ctypes as $type) { - $attachment .= ' HEADER Content-Type ' . rcube_imap_generic::escape($type); - } + // Build search string of "with attachment" filter + $attachment = str_repeat(' OR', count($ctypes)-1); + foreach ($ctypes as $type) { + $attachment .= ' HEADER Content-Type ' . rcube_imap_generic::escape($type); + } - $select_filter = new html_select($attrib); - $select_filter->add(rcube_label('all'), 'ALL'); - $select_filter->add(rcube_label('unread'), 'UNSEEN'); - $select_filter->add(rcube_label('flagged'), 'FLAGGED'); - $select_filter->add(rcube_label('unanswered'), 'UNANSWERED'); - if (!$CONFIG['skip_deleted']) { - $select_filter->add(rcube_label('deleted'), 'DELETED'); - $select_filter->add(rcube_label('undeleted'), 'UNDELETED'); - } - $select_filter->add(rcube_label('withattachment'), $attachment); - $select_filter->add(rcube_label('priority').': '.rcube_label('highest'), 'HEADER X-PRIORITY 1'); - $select_filter->add(rcube_label('priority').': '.rcube_label('high'), 'HEADER X-PRIORITY 2'); - $select_filter->add(rcube_label('priority').': '.rcube_label('normal'), 'NOT HEADER X-PRIORITY 1 NOT HEADER X-PRIORITY 2 NOT HEADER X-PRIORITY 4 NOT HEADER X-PRIORITY 5'); - $select_filter->add(rcube_label('priority').': '.rcube_label('low'), 'HEADER X-PRIORITY 4'); - $select_filter->add(rcube_label('priority').': '.rcube_label('lowest'), 'HEADER X-PRIORITY 5'); + $select_filter = new html_select($attrib); + $select_filter->add($RCMAIL->gettext('all'), 'ALL'); + $select_filter->add($RCMAIL->gettext('unread'), 'UNSEEN'); + $select_filter->add($RCMAIL->gettext('flagged'), 'FLAGGED'); + $select_filter->add($RCMAIL->gettext('unanswered'), 'UNANSWERED'); + if (!$RCMAIL->config->get('skip_deleted')) { + $select_filter->add($RCMAIL->gettext('deleted'), 'DELETED'); + $select_filter->add($RCMAIL->gettext('undeleted'), 'UNDELETED'); + } + $select_filter->add($RCMAIL->gettext('withattachment'), $attachment); + $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('highest'), 'HEADER X-PRIORITY 1'); + $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('high'), 'HEADER X-PRIORITY 2'); + $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('normal'), 'NOT HEADER X-PRIORITY 1 NOT HEADER X-PRIORITY 2 NOT HEADER X-PRIORITY 4 NOT HEADER X-PRIORITY 5'); + $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('low'), 'HEADER X-PRIORITY 4'); + $select_filter->add($RCMAIL->gettext('priority').': '.$RCMAIL->gettext('lowest'), 'HEADER X-PRIORITY 5'); - $out = $select_filter->show($_SESSION['search_filter']); + $out = $select_filter->show($_SESSION['search_filter']); - $OUTPUT->add_gui_object('search_filter', $attrib['id']); + $RCMAIL->output->add_gui_object('search_filter', $attrib['id']); - return $out; + return $out; } function rcmail_message_error($uid=null) { - global $RCMAIL; + global $RCMAIL; - // Set env variables for messageerror.html template - if ($RCMAIL->action == 'show') { - $mbox_name = $RCMAIL->storage->get_folder(); - $RCMAIL->output->set_env('mailbox', $mbox_name); - $RCMAIL->output->set_env('uid', null); - } - // display error message - $RCMAIL->output->show_message('messageopenerror', 'error'); - // ... display message error page - $RCMAIL->output->send('messageerror'); + // Set env variables for messageerror.html template + if ($RCMAIL->action == 'show') { + $mbox_name = $RCMAIL->storage->get_folder(); + + $RCMAIL->output->set_env('mailbox', $mbox_name); + $RCMAIL->output->set_env('uid', null); + } + + // display error message + $RCMAIL->output->show_message('messageopenerror', 'error'); + // ... display message error page + $RCMAIL->output->send('messageerror'); } function rcmail_message_import_form($attrib = array()) { - global $OUTPUT; - - // set defaults - $attrib += array('id' => 'rcmImportform', 'buttons' => 'yes'); - - // Get filesize, enable upload progress bar - $max_filesize = rcube_upload_init(); - - $button = new html_inputfield(array('type' => 'button')); - $fileinput = new html_inputfield(array( - 'type' => 'file', - 'name' => '_file[]', - 'multiple' => 'multiple', - 'accept' => ".eml, .mbox, message/rfc822, text/*", - )); - - $out = html::div($attrib, - $OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'method' => 'post', 'enctype' => 'multipart/form-data'), - html::tag('input', array('type' => 'hidden', 'name' => '_unlock', 'value' => '')) . - html::div(null, $fileinput->show()) . - html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) . - (get_boolean($attrib['buttons']) ? html::div('buttons', - $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' . - $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('import-messages', this.form)")) - ) : '') - ) - ); - - $OUTPUT->add_gui_object('importform', $attrib['id'].'Frm'); - return $out; + global $RCMAIL; + + // set defaults + $attrib += array('id' => 'rcmImportform', 'buttons' => 'yes'); + + // Get filesize, enable upload progress bar + $max_filesize = $RCMAIL->upload_init(); + + $button = new html_inputfield(array('type' => 'button')); + $fileinput = new html_inputfield(array( + 'type' => 'file', + 'name' => '_file[]', + 'multiple' => 'multiple', + 'accept' => ".eml, .mbox, message/rfc822, text/*", + )); + + $content = html::tag('input', array('type' => 'hidden', 'name' => '_unlock', 'value' => '')) + . html::div(null, $fileinput->show()) + . html::div('hint', $RCMAIL->gettext(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))); + + if (rcube_utils::get_boolean($attrib['buttons'])) { + $content .= html::div('buttons', + $button->show($RCMAIL->gettext('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) + . ' ' . + $button->show($RCMAIL->gettext('upload'), array( + 'class' => 'button mainaction', + 'onclick' => rcmail_output::JS_OBJECT_NAME . ".command('import-messages', this.form)" + ))); + } + + $out = $RCMAIL->output->form_tag(array( + 'id' => $attrib['id'].'Frm', + 'method' => 'post', + 'enctype' => 'multipart/form-data' + ), + $content); + + $RCMAIL->output->add_gui_object('importform', $attrib['id'].'Frm'); + + return html::div($attrib, $out); } diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc index e0c4e2911..8f869c67c 100644 --- a/program/steps/mail/get.inc +++ b/program/steps/mail/get.inc @@ -5,7 +5,7 @@ | program/steps/mail/get.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2011, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -22,15 +22,15 @@ // show loading page if (!empty($_GET['_preload'])) { - $url = preg_replace('/([&?]+)_preload=/', '\\1_mimewarning=1&_embed=', $_SERVER['REQUEST_URI']); - $message = rcube_label('loadingdata'); + $url = preg_replace('/([&?]+)_preload=/', '\\1_mimewarning=1&_embed=', $_SERVER['REQUEST_URI']); + $message = $RCMAIL->gettext('loadingdata'); - header('Content-Type: text/html; charset=' . RCMAIL_CHARSET); - print "<html>\n<head>\n" - . '<meta http-equiv="refresh" content="0; url='.Q($url).'">' . "\n" - . '<meta http-equiv="content-type" content="text/html; charset='.RCMAIL_CHARSET.'">' . "\n" + header('Content-Type: text/html; charset=' . RCUBE_CHARSET); + print "<html>\n<head>\n" + . '<meta http-equiv="refresh" content="0; url='.rcube::Q($url).'">' . "\n" + . '<meta http-equiv="content-type" content="text/html; charset='.RCUBE_CHARSET.'">' . "\n" . "</head>\n<body>\n$message\n</body>\n</html>"; - exit; + exit; } ob_end_clean(); @@ -38,353 +38,361 @@ ob_end_clean(); // similar code as in program/steps/mail/show.inc if (!empty($_GET['_uid'])) { - $uid = get_input_value('_uid', RCUBE_INPUT_GET); - $RCMAIL->config->set('prefer_html', true); - $MESSAGE = new rcube_message($uid); + $uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET); + $RCMAIL->config->set('prefer_html', true); + $MESSAGE = new rcube_message($uid); } // check connection status check_storage_status(); -$part_id = get_input_value('_part', RCUBE_INPUT_GPC); +$part_id = rcube_utils::get_input_value('_part', rcube_utils::INPUT_GPC); // show part page if (!empty($_GET['_frame'])) { - if ($part_id && ($part = $MESSAGE->mime_parts[$part_id])) { - $filename = rcmail_attachment_name($part); - $OUTPUT->set_pagetitle($filename); - } - - // register UI objects - $OUTPUT->add_handlers(array( - 'messagepartframe' => 'rcmail_message_part_frame', - 'messagepartcontrols' => 'rcmail_message_part_controls', - )); - - $OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder()); - $OUTPUT->set_env('uid', $uid); - $OUTPUT->set_env('part', $part_id); - $OUTPUT->set_env('filename', $filename); - - $OUTPUT->send('messagepart'); - exit; + if ($part_id && ($part = $MESSAGE->mime_parts[$part_id])) { + $filename = rcmail_attachment_name($part); + $OUTPUT->set_pagetitle($filename); + } + + // register UI objects + $OUTPUT->add_handlers(array( + 'messagepartframe' => 'rcmail_message_part_frame', + 'messagepartcontrols' => 'rcmail_message_part_controls', + )); + + $OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder()); + $OUTPUT->set_env('uid', $uid); + $OUTPUT->set_env('part', $part_id); + $OUTPUT->set_env('filename', $filename); + + $OUTPUT->send('messagepart'); + exit; } // render thumbnail of an image attachment else if ($_GET['_thumb']) { - $pid = get_input_value('_part', RCUBE_INPUT_GET); - if ($part = $MESSAGE->mime_parts[$pid]) { - $thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240); - $temp_dir = $RCMAIL->config->get('temp_dir'); - list(,$ext) = explode('/', $part->mimetype); - $mimetype = $part->mimetype; - $file_ident = $MESSAGE->headers->messageID . ':' . $part->mime_id . ':' . $part->size . ':' . $part->mimetype; - $cache_basename = $temp_dir . '/' . md5($file_ident . ':' . $RCMAIL->user->ID . ':' . $thumbnail_size); - $cache_file = $cache_basename . '.' . $ext; - - // render thumbnail image if not done yet - if (!is_file($cache_file)) { - $fp = fopen(($orig_name = $cache_basename . '.orig.' . $ext), 'w'); - $MESSAGE->get_part_content($part->mime_id, $fp); - fclose($fp); - - $image = new rcube_image($orig_name); - if ($imgtype = $image->resize($thumbnail_size, $cache_file, true)) { - $mimetype = 'image/' . $imgtype; - unlink($orig_name); - } - else { - rename($orig_name, $cache_file); - } - } + $pid = rcube_utils::get_input_value('_part', rcube_utils::INPUT_GET); + if ($part = $MESSAGE->mime_parts[$pid]) { + $thumbnail_size = $RCMAIL->config->get('image_thumbnail_size', 240); + $temp_dir = $RCMAIL->config->get('temp_dir'); + list(,$ext) = explode('/', $part->mimetype); + $mimetype = $part->mimetype; + $file_ident = $MESSAGE->headers->messageID . ':' . $part->mime_id . ':' . $part->size . ':' . $part->mimetype; + $cache_basename = $temp_dir . '/' . md5($file_ident . ':' . $RCMAIL->user->ID . ':' . $thumbnail_size); + $cache_file = $cache_basename . '.' . $ext; + + // render thumbnail image if not done yet + if (!is_file($cache_file)) { + if ($fp = fopen(($orig_name = $cache_basename . '.orig.' . $ext), 'w')) { + $MESSAGE->get_part_content($part->mime_id, $fp); + fclose($fp); + + $image = new rcube_image($orig_name); + if ($imgtype = $image->resize($thumbnail_size, $cache_file, true)) { + $mimetype = 'image/' . $imgtype; + unlink($orig_name); + } + else { + rename($orig_name, $cache_file); + } + } + } - if (is_file($cache_file)) { - header('Content-Type: ' . $mimetype); - readfile($cache_file); + if (is_file($cache_file)) { + header('Content-Type: ' . $mimetype); + readfile($cache_file); + } } - } - exit; + exit; } else if (strlen($part_id)) { - if ($part = $MESSAGE->mime_parts[$part_id]) { - $mimetype = rcmail_fix_mimetype($part->mimetype); - - // allow post-processing of the message body - $plugin = $RCMAIL->plugins->exec_hook('message_part_get', - array('uid' => $MESSAGE->uid, 'id' => $part->mime_id, 'mimetype' => $mimetype, 'part' => $part, 'download' => !empty($_GET['_download']))); - - if ($plugin['abort']) - exit; - - // overwrite modified vars from plugin - $mimetype = $plugin['mimetype']; - $extensions = rcube_mime::get_mime_extensions($mimetype); - - if ($plugin['body']) - $part->body = $plugin['body']; - - - // compare file mimetype with the stated content-type headers and file extension to avoid malicious operations - if (!empty($_REQUEST['_embed']) && empty($_REQUEST['_nocheck'])) { - $file_extension = strtolower(pathinfo($part->filename, PATHINFO_EXTENSION)); - - // 1. compare filename suffix with expected suffix derived from mimetype - $valid = $file_extension && in_array($file_extension, (array)$extensions) || !empty($_REQUEST['_mimeclass']); - - // 2. detect the real mimetype of the attachment part and compare it with the stated mimetype and filename extension - if ($valid || !$file_extension || $mimetype == 'application/octet-stream' || stripos($mimetype, 'text/') === 0) { - if ($part->body) // part body is already loaded - $body = $part->body; - else if ($part->size && $part->size < 1024*1024) // load the entire part if it's small enough - $body = $part->body = $MESSAGE->get_part_content($part->mime_id); - else // fetch the first 2K of the message part - $body = $MESSAGE->get_part_content($part->mime_id, null, true, 2048); - - // detect message part mimetype - $real_mimetype = rcube_mime::file_content_type($body, $part->filename, $mimetype, true, true); - list($real_ctype_primary, $real_ctype_secondary) = explode('/', $real_mimetype); - - // accept text/plain with any extension - if ($real_mimetype == 'text/plain' && $real_mimetype == $mimetype) - $file_extension = 'txt'; - - // ignore differences in text/* mimetypes. Filetype detection isn't very reliable here - if ($real_ctype_primary == 'text' && strpos($mimetype, $real_ctype_primary) === 0) - $real_mimetype = $mimetype; - - // get valid file extensions - $extensions = rcube_mime::get_mime_extensions($real_mimetype); - $valid_extension = (!$file_extension || in_array($file_extension, (array)$extensions)); - - // ignore filename extension if mimeclass matches (#1489029) - if (!empty($_REQUEST['_mimeclass']) && $real_ctype_primary == $_REQUEST['_mimeclass']) - $valid_extension = true; - - // fix mimetype for images wrongly declared as octet-stream - if ($mimetype == 'application/octet-stream' && strpos($real_mimetype, 'image/') === 0 && $valid_extension) - $mimetype = $real_mimetype; - - $valid = ($real_mimetype == $mimetype && $valid_extension); - } - else { - $real_mimetype = $mimetype; - } - - // show warning if validity checks failed - if (!$valid) { - // send blocked.gif for expected images - if (empty($_REQUEST['_mimewarning']) && strpos($mimetype, 'image/') === 0) { - // Do not cache. Failure might be the result of a misconfiguration, thus real content should be returned once fixed. - $OUTPUT->nocacheing_headers(); - header("Content-Type: image/gif"); - header("Content-Transfer-Encoding: binary"); - readfile(INSTALL_PATH . 'program/resources/blocked.gif'); - } - else { // html warning with a button to load the file anyway - $OUTPUT = new rcmail_html_page(); - $OUTPUT->write(html::tag('html', null, html::tag('body', 'embed', - html::div(array('class' => 'rcmail-inline-message rcmail-inline-warning'), - rcube_label(array( - 'name' => 'attachmentvalidationerror', - 'vars' => array( - 'expected' => $mimetype . ($file_extension ? " (.$file_extension)" : ''), - 'detected' => $real_mimetype . ($extensions[0] ? " (.$extensions[0])" : ''), - ) - )) . - html::p(array('class' => 'rcmail-inline-buttons'), - html::tag('button', - array('onclick' => "location.href='" . $RCMAIL->url(array_merge($_GET, array('_nocheck' => 1))) . "'"), - rcube_label('showanyway'))) - ) - ))); + if ($part = $MESSAGE->mime_parts[$part_id]) { + $mimetype = rcmail_fix_mimetype($part->mimetype); + + // allow post-processing of the message body + $plugin = $RCMAIL->plugins->exec_hook('message_part_get', array( + 'uid' => $MESSAGE->uid, + 'id' => $part->mime_id, + 'mimetype' => $mimetype, + 'part' => $part, + 'download' => !empty($_GET['_download']) + )); + + if ($plugin['abort']) { + exit; } - exit; - } - } + // overwrite modified vars from plugin + $mimetype = $plugin['mimetype']; + $extensions = rcube_mime::get_mime_extensions($mimetype); - // TIFF to JPEG conversion, if needed - $tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']); - if (!empty($_REQUEST['_embed']) && !$tiff_support - && $RCMAIL->config->get('im_convert_path') - && rcmail_part_image_type($part) == 'image/tiff' - ) { - $tiff2jpeg = true; - $mimetype = 'image/jpeg'; - } - + if ($plugin['body']) { + $part->body = $plugin['body']; + } - $browser = $RCMAIL->output->browser; - list($ctype_primary, $ctype_secondary) = explode('/', $mimetype); + // compare file mimetype with the stated content-type headers and file extension to avoid malicious operations + if (!empty($_REQUEST['_embed']) && empty($_REQUEST['_nocheck'])) { + $file_extension = strtolower(pathinfo($part->filename, PATHINFO_EXTENSION)); + + // 1. compare filename suffix with expected suffix derived from mimetype + $valid = $file_extension && in_array($file_extension, (array)$extensions) || !empty($_REQUEST['_mimeclass']); + + // 2. detect the real mimetype of the attachment part and compare it with the stated mimetype and filename extension + if ($valid || !$file_extension || $mimetype == 'application/octet-stream' || stripos($mimetype, 'text/') === 0) { + if ($part->body) // part body is already loaded + $body = $part->body; + else if ($part->size && $part->size < 1024*1024) // load the entire part if it's small enough + $body = $part->body = $MESSAGE->get_part_content($part->mime_id); + else // fetch the first 2K of the message part + $body = $MESSAGE->get_part_content($part->mime_id, null, true, 2048); + + // detect message part mimetype + $real_mimetype = rcube_mime::file_content_type($body, $part->filename, $mimetype, true, true); + list($real_ctype_primary, $real_ctype_secondary) = explode('/', $real_mimetype); + + // accept text/plain with any extension + if ($real_mimetype == 'text/plain' && $real_mimetype == $mimetype) { + $file_extension = 'txt'; + } + + // ignore differences in text/* mimetypes. Filetype detection isn't very reliable here + if ($real_ctype_primary == 'text' && strpos($mimetype, $real_ctype_primary) === 0) { + $real_mimetype = $mimetype; + } + + // get valid file extensions + $extensions = rcube_mime::get_mime_extensions($real_mimetype); + $valid_extension = (!$file_extension || in_array($file_extension, (array)$extensions)); + + // ignore filename extension if mimeclass matches (#1489029) + if (!empty($_REQUEST['_mimeclass']) && $real_ctype_primary == $_REQUEST['_mimeclass']) { + $valid_extension = true; + } + + // fix mimetype for images wrongly declared as octet-stream + if ($mimetype == 'application/octet-stream' && strpos($real_mimetype, 'image/') === 0 && $valid_extension) { + $mimetype = $real_mimetype; + } + + $valid = ($real_mimetype == $mimetype && $valid_extension); + } + else { + $real_mimetype = $mimetype; + } + + // show warning if validity checks failed + if (!$valid) { + // send blocked.gif for expected images + if (empty($_REQUEST['_mimewarning']) && strpos($mimetype, 'image/') === 0) { + // Do not cache. Failure might be the result of a misconfiguration, thus real content should be returned once fixed. + $OUTPUT->nocacheing_headers(); + header("Content-Type: image/gif"); + header("Content-Transfer-Encoding: binary"); + readfile(INSTALL_PATH . 'program/resources/blocked.gif'); + } + else { // html warning with a button to load the file anyway + $OUTPUT = new rcmail_html_page(); + $OUTPUT->write(html::tag('html', null, html::tag('body', 'embed', + html::div(array('class' => 'rcmail-inline-message rcmail-inline-warning'), + $RCMAIL->gettext(array( + 'name' => 'attachmentvalidationerror', + 'vars' => array( + 'expected' => $mimetype . ($file_extension ? " (.$file_extension)" : ''), + 'detected' => $real_mimetype . ($extensions[0] ? " (.$extensions[0])" : ''), + ) + )) + . html::p(array('class' => 'rcmail-inline-buttons'), + html::tag('button', array( + 'onclick' => "location.href='" . $RCMAIL->url(array_merge($_GET, array('_nocheck' => 1))) . "'" + ), + $RCMAIL->gettext('showanyway')) + ) + )))); + } + + exit; + } + } - // send download headers - if ($plugin['download']) { - header("Content-Type: application/octet-stream"); - if ($browser->ie) - header("Content-Type: application/force-download"); - } - else if ($ctype_primary == 'text') { - header("Content-Type: text/$ctype_secondary; charset=" . ($part->charset ? $part->charset : RCMAIL_CHARSET)); - } - else { - header("Content-Type: $mimetype"); - header("Content-Transfer-Encoding: binary"); - } - // deliver part content - if ($ctype_primary == 'text' && $ctype_secondary == 'html' && empty($plugin['download'])) { - // Check if we have enough memory to handle the message in it - // #1487424: we need up to 10x more memory than the body - if (!rcmail_mem_check($part->size * 10)) { - $out = '<body>' . rcube_label('messagetoobig'). ' ' - . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id - .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), rcube_label('download')) . '</body></html>'; - } - else { - // get part body if not available - if (!$part->body) - $part->body = $MESSAGE->get_part_content($part->mime_id); - - // show images? - rcmail_check_safe($MESSAGE); - - // render HTML body - $out = rcmail_print_body($part, array('safe' => $MESSAGE->is_safe, 'inline_html' => false)); - - // insert remote objects warning into HTML body - if ($REMOTE_OBJECTS) { - $body_start = 0; - if ($body_pos = strpos($out, '<body')) { - $body_start = strpos($out, '>', $body_pos) + 1; - } - $out = substr($out, 0, $body_start) . - html::div(array('class' => 'rcmail-inline-message rcmail-inline-warning'), - Q(rcube_label('blockedimages')) . ' ' . - html::tag('button', - array('onclick' => "location.href='" . $RCMAIL->url(array_merge($_GET, array('_safe' => 1))) . "'"), - Q(rcube_label('showimages'))) - ) . - substr($out, $body_start); + // TIFF to JPEG conversion, if needed + $tiff_support = !empty($_SESSION['browser_caps']) && !empty($_SESSION['browser_caps']['tif']); + if (!empty($_REQUEST['_embed']) && !$tiff_support + && $RCMAIL->config->get('im_convert_path') + && rcmail_part_image_type($part) == 'image/tiff' + ) { + $tiff2jpeg = true; + $mimetype = 'image/jpeg'; } - } - // check connection status - if ($part->size && empty($part->body)) { - check_storage_status(); - } - $OUTPUT = new rcube_html_page(); - $OUTPUT->write($out); - } - else { - // don't kill the connection if download takes more than 30 sec. - @set_time_limit(0); - - $filename = rcmail_attachment_name($part); - - if ($browser->ie && $browser->ver < 7) - $filename = rawurlencode(abbreviate_string($filename, 55)); - else if ($browser->ie) - $filename = rawurlencode($filename); - else - $filename = addcslashes($filename, '"'); - - $disposition = !empty($plugin['download']) ? 'attachment' : 'inline'; - - // Workaround for nasty IE bug (#1488844) - // If Content-Disposition header contains string "attachment" e.g. in filename - // IE handles data as attachment not inline - if ($disposition == 'inline' && $browser->ie && $browser->ver < 9) { - $filename = str_ireplace('attachment', 'attach', $filename); - } - - // add filename extension if missing - if (!pathinfo($filename, PATHINFO_EXTENSION) && ($extensions = rcube_mime::get_mime_extensions($mimetype))) { - $filename .= '.' . $extensions[0]; - } - - header("Content-Disposition: $disposition; filename=\"$filename\""); - - // handle tiff to jpeg conversion - if (!empty($tiff2jpeg)) { - $temp_dir = unslashify($RCMAIL->config->get('temp_dir')); - $file_path = tempnam($temp_dir, 'rcmAttmnt'); - - // write content to temp file - if ($part->body) { - $saved = file_put_contents($file_path, $part->body); - } - else if ($part->size) { - $fd = fopen($file_path, 'w'); - $saved = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, false, $fd); - fclose($fd); - } + $browser = $RCMAIL->output->browser; + list($ctype_primary, $ctype_secondary) = explode('/', $mimetype); - // convert image to jpeg and send it to the browser - if ($saved) { - $image = new rcube_image($file_path); - if ($image->convert(rcube_image::TYPE_JPG, $file_path)) { - header("Content-Length: " . filesize($file_path)); - readfile($file_path); - } - unlink($file_path); - } - } - // do content filtering to avoid XSS through fake images - else if (!empty($_REQUEST['_embed']) && $browser->ie && $browser->ver <= 8) { - if ($part->body) { - echo preg_match('/<(script|iframe|object)/i', $part->body) ? '' : $part->body; - $sent = true; - } - else if ($part->size) { - $stdout = fopen('php://output', 'w'); - stream_filter_register('rcube_content', 'rcube_content_filter') or die('Failed to register content filter'); - stream_filter_append($stdout, 'rcube_content'); - $sent = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, false, $stdout); + if (!$plugin['download'] && $ctype_primary == 'text') { + header("Content-Type: text/$ctype_secondary; charset=" . ($part->charset ? $part->charset : RCUBE_CHARSET)); } - } - // send part as-it-is - else { - if ($part->body) { - header("Content-Length: " . strlen($part->body)); - echo $part->body; - $sent = true; + else { + header("Content-Type: $mimetype"); + header("Content-Transfer-Encoding: binary"); } - else if ($part->size) { - if ($size = (int)$part->d_parameters['size']) { - header("Content-Length: $size"); - } - // 8th argument disables re-formatting of text/* parts (#1489267) - $sent = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, true, null, false, 0, false); + // deliver part content + if ($ctype_primary == 'text' && $ctype_secondary == 'html' && empty($plugin['download'])) { + // Check if we have enough memory to handle the message in it + // #1487424: we need up to 10x more memory than the body + if (!rcube_utils::mem_check($part->size * 10)) { + $out = '<body>' . $RCMAIL->gettext('messagetoobig'). ' ' + . html::a('?_task=mail&_action=get&_download=1&_uid='.$MESSAGE->uid.'&_part='.$part->mime_id + .'&_mbox='. urlencode($RCMAIL->storage->get_folder()), $RCMAIL->gettext('download')) . '</body></html>'; + } + else { + // get part body if not available + if (!$part->body) { + $part->body = $MESSAGE->get_part_content($part->mime_id); + } + + // show images? + rcmail_check_safe($MESSAGE); + + // render HTML body + $out = rcmail_print_body($part, array('safe' => $MESSAGE->is_safe, 'inline_html' => false)); + + // insert remote objects warning into HTML body + if ($REMOTE_OBJECTS) { + $body_start = 0; + if ($body_pos = strpos($out, '<body')) { + $body_start = strpos($out, '>', $body_pos) + 1; + } + + $out = substr($out, 0, $body_start) + . html::div(array('class' => 'rcmail-inline-message rcmail-inline-warning'), + rcube::Q($RCMAIL->gettext('blockedimages')) . ' ' . + html::tag('button', + array('onclick' => "location.href='" . $RCMAIL->url(array_merge($_GET, array('_safe' => 1))) . "'"), + rcube::Q($RCMAIL->gettext('showimages'))) + ) + . substr($out, $body_start); + } + } + + // check connection status + if ($part->size && empty($part->body)) { + check_storage_status(); + } + + $OUTPUT = new rcmail_html_page(); + $OUTPUT->write($out); + } + else { + // don't kill the connection if download takes more than 30 sec. + @set_time_limit(0); + + $filename = rcmail_attachment_name($part); + + if ($browser->ie && $browser->ver < 7) + $filename = rawurlencode(abbreviate_string($filename, 55)); + else if ($browser->ie) + $filename = rawurlencode($filename); + else + $filename = addcslashes($filename, '"'); + + $disposition = !empty($plugin['download']) ? 'attachment' : 'inline'; + + // Workaround for nasty IE bug (#1488844) + // If Content-Disposition header contains string "attachment" e.g. in filename + // IE handles data as attachment not inline + if ($disposition == 'inline' && $browser->ie && $browser->ver < 9) { + $filename = str_ireplace('attachment', 'attach', $filename); + } + + // add filename extension if missing + if (!pathinfo($filename, PATHINFO_EXTENSION) && ($extensions = rcube_mime::get_mime_extensions($mimetype))) { + $filename .= '.' . $extensions[0]; + } + + header("Content-Disposition: $disposition; filename=\"$filename\""); + + // handle tiff to jpeg conversion + if (!empty($tiff2jpeg)) { + $temp_dir = unslashify($RCMAIL->config->get('temp_dir')); + $file_path = tempnam($temp_dir, 'rcmAttmnt'); + + // write content to temp file + if ($part->body) { + $saved = file_put_contents($file_path, $part->body); + } + else if ($part->size) { + $fd = fopen($file_path, 'w'); + $saved = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, false, $fd); + fclose($fd); + } + + // convert image to jpeg and send it to the browser + if ($saved) { + $image = new rcube_image($file_path); + if ($image->convert(rcube_image::TYPE_JPG, $file_path)) { + header("Content-Length: " . filesize($file_path)); + readfile($file_path); + } + unlink($file_path); + } + } + // do content filtering to avoid XSS through fake images + else if (!empty($_REQUEST['_embed']) && $browser->ie && $browser->ver <= 8) { + if ($part->body) { + echo preg_match('/<(script|iframe|object)/i', $part->body) ? '' : $part->body; + $sent = true; + } + else if ($part->size) { + $stdout = fopen('php://output', 'w'); + stream_filter_register('rcube_content', 'rcube_content_filter') or die('Failed to register content filter'); + stream_filter_append($stdout, 'rcube_content'); + $sent = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, false, $stdout); + } + } + // send part as-it-is + else { + if ($part->body) { + header("Content-Length: " . strlen($part->body)); + echo $part->body; + $sent = true; + } + else if ($part->size) { + if ($size = (int)$part->d_parameters['size']) { + header("Content-Length: $size"); + } + + // 8th argument disables re-formatting of text/* parts (#1489267) + $sent = $RCMAIL->storage->get_message_part($MESSAGE->uid, $part->mime_id, $part, true, null, false, 0, false); + } + } + + // check connection status + if ($part->size && !$sent) { + check_storage_status(); + } } - } - // check connection status - if ($part->size && !$sent) { - check_storage_status(); - } + exit; } - - exit; - } } - // print message else { - // send correct headers for content type - header("Content-Type: text/html"); + // send correct headers for content type + header("Content-Type: text/html"); - $cont = "<html>\n<head><title></title>\n</head>\n<body>"; - $cont .= rcmail_message_body(array()); - $cont .= "\n</body>\n</html>"; + $cont = "<html>\n<head><title></title>\n</head>\n<body>"; + $cont .= rcmail_message_body(array()); + $cont .= "\n</body>\n</html>"; - $OUTPUT = new rcube_html_page(); - $OUTPUT->write($cont); + $OUTPUT = new rcmail_html_page(); + $OUTPUT->write($cont); - exit; + exit; } @@ -415,7 +423,7 @@ function check_storage_status() header('Location: ' . $_SERVER['REQUEST_URI'] . '&_redirected=1'); } else { - raise_error(array( + rcube::raise_error(array( 'code' => 500, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => 'Unable to get/display message part. IMAP connection error'), @@ -434,7 +442,7 @@ function rcmail_message_part_controls($attrib) { global $MESSAGE, $RCMAIL; - $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC)); + $part = asciiwords(rcube_utils::get_input_value('_part', rcube_utils::INPUT_GPC)); if (!is_object($MESSAGE) || !is_array($MESSAGE->parts) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part] ) { @@ -444,14 +452,14 @@ function rcmail_message_part_controls($attrib) $part = $MESSAGE->mime_parts[$part]; $table = new html_table(array('cols' => 2)); - $table->add('title', Q(rcube_label('namex')).':'); - $table->add('header', Q(rcmail_attachment_name($part))); + $table->add('title', rcube::Q($RCMAIL->gettext('namex')).':'); + $table->add('header', rcube::Q(rcmail_attachment_name($part))); - $table->add('title', Q(rcube_label('type')).':'); - $table->add('header', Q($part->mimetype)); + $table->add('title', rcube::Q($RCMAIL->gettext('type')).':'); + $table->add('header', rcube::Q($part->mimetype)); - $table->add('title', Q(rcube_label('size')).':'); - $table->add('header', Q($RCMAIL->message_part_size($part))); + $table->add('title', rcube::Q($RCMAIL->gettext('size')).':'); + $table->add('header', rcube::Q($RCMAIL->message_part_size($part))); return $table->show($attrib); } @@ -463,7 +471,7 @@ function rcmail_message_part_frame($attrib) { global $MESSAGE, $RCMAIL; - $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))]; + $part = $MESSAGE->mime_parts[asciiwords(rcube_utils::get_input_value('_part', rcube_utils::INPUT_GPC))]; $ctype_primary = strtolower($part->ctype_primary); $attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary=='text' ? '_embed=' : '_preload='), $_SERVER['QUERY_STRING']); diff --git a/program/steps/mail/getunread.inc b/program/steps/mail/getunread.inc index fb7e802fb..f708c8aef 100644 --- a/program/steps/mail/getunread.inc +++ b/program/steps/mail/getunread.inc @@ -5,7 +5,7 @@ | program/steps/mail/getunread.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -21,28 +21,36 @@ $a_folders = $RCMAIL->storage->list_folders_subscribed('', '*', 'mail'); -if (!empty($a_folders)) -{ - $current = $RCMAIL->storage->get_folder(); - $inbox = ($current == 'INBOX'); - $check_all = (bool)$RCMAIL->config->get('check_all_folders'); - - foreach ($a_folders as $mbox_row) { - $unseen_old = rcmail_get_unseen_count($mbox_row); - - if (!$check_all && $unseen_old !== null && $mbox_row != $current) - $unseen = $unseen_old; - else - $unseen = $RCMAIL->storage->count($mbox_row, 'UNSEEN', $unseen_old === null); - - if ($unseen || $unseen_old === null) { - $OUTPUT->command('set_unread_count', $mbox_row, $unseen, $inbox && $mbox_row == 'INBOX'); +if (!empty($a_folders)) { + $current = $RCMAIL->storage->get_folder(); + $inbox = ($current == 'INBOX'); + $trash = $RCMAIL->config->get('trash_mbox'); + $check_all = (bool)$RCMAIL->config->get('check_all_folders'); + + foreach ($a_folders as $mbox) { + $unseen_old = rcmail_get_unseen_count($mbox); + + if (!$check_all && $unseen_old !== null && $mbox != $current) { + $unseen = $unseen_old; + } + else { + $unseen = $RCMAIL->storage->count($mbox, 'UNSEEN', $unseen_old === null); + } + + // call it always for current folder, so it can update counter + // after possible message status change when opening a message + // not in preview frame + if ($unseen || $unseen_old === null || $mbox == $current) { + $OUTPUT->command('set_unread_count', $mbox, $unseen, $inbox && $mbox_row == 'INBOX'); + } + + rcmail_set_unseen_count($mbox, $unseen); + + // set trash folder state + if ($mbox === $trash) { + $OUTPUT->command('set_trash_count', $RCMAIL->storage->count($mbox, 'EXISTS')); + } } - - rcmail_set_unseen_count($mbox_row, $unseen); - } } $OUTPUT->send(); - - diff --git a/program/steps/mail/headers.inc b/program/steps/mail/headers.inc index cad113f68..9d3e6d348 100644 --- a/program/steps/mail/headers.inc +++ b/program/steps/mail/headers.inc @@ -19,8 +19,7 @@ +-----------------------------------------------------------------------+ */ -if ($uid = get_input_value('_uid', RCUBE_INPUT_POST)) -{ +if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST)) { $source = $RCMAIL->storage->get_raw_headers($uid); if ($source !== false) { @@ -48,5 +47,3 @@ if ($uid = get_input_value('_uid', RCUBE_INPUT_POST)) } exit; - - diff --git a/program/steps/mail/import.inc b/program/steps/mail/import.inc index f7e7a3eb8..4f822e0e4 100644 --- a/program/steps/mail/import.inc +++ b/program/steps/mail/import.inc @@ -31,7 +31,8 @@ if (is_array($_FILES['_file'])) { if (!$err) { // check file content type first - list($mtype_primary,) = explode('/', rc_mime_content_type($filepath, $_FILES['_file']['name'][$i], $_FILES['_file']['type'][$i])); + list($mtype_primary,) = explode('/', rcube_mime::file_content_type($filepath, $_FILES['_file']['name'][$i], $_FILES['_file']['type'][$i])); + if (!in_array($mtype_primary, array('text','message'))) { $OUTPUT->show_message('importmessageerror', 'error'); continue; @@ -39,7 +40,9 @@ if (is_array($_FILES['_file'])) { // read the first few lines to detect header-like structure $fp = fopen($filepath, 'r'); - do { $line = fgets($fp); } + do { + $line = fgets($fp); + } while ($line !== false && trim($line) == ''); if (!preg_match('/^From\s+-/', $line) && !preg_match('/^[a-z-_]+:\s+.+/i', $line)) { @@ -74,7 +77,8 @@ if (is_array($_FILES['_file'])) { } if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) { - $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes(ini_get('upload_max_filesize')))))); + $size = $RCMAIL->show_bytes(parse_bytes(ini_get('upload_max_filesize'))); + $msg = $RCMAIL->gettext(array('name' => 'filesizeerror', 'vars' => array('size' => $size))); } else if ($err) { $OUTPUT->show_message('fileuploaderror', 'error'); @@ -82,7 +86,7 @@ if (is_array($_FILES['_file'])) { } // end foreach if ($imported) { - $OUTPUT->show_message(rcube_label(array('name' => 'importmessagesuccess', 'nr' => $imported, 'vars' => array('nr' => $imported))), 'confirmation'); + $OUTPUT->show_message($RCMAIL->gettext(array('name' => 'importmessagesuccess', 'nr' => $imported, 'vars' => array('nr' => $imported))), 'confirmation'); $OUTPUT->command('command', 'list'); } else { @@ -93,13 +97,12 @@ else if ($_SERVER['REQUEST_METHOD'] == 'POST') { // if filesize exceeds post_max_size then $_FILES array is empty, // show filesizeerror instead of fileuploaderror if ($maxsize = ini_get('post_max_size')) - $msg = rcube_label(array('name' => 'filesizeerror', 'vars' => array('size' => show_bytes(parse_bytes($maxsize))))); + $msg = $RCMAIL->gettext(array('name' => 'filesizeerror', 'vars' => array('size' => $RCMAIL->show_bytes(parse_bytes($maxsize))))); else - $msg = rcube_label('fileuploaderror'); + $msg = $RCMAIL->gettext('fileuploaderror'); $OUTPUT->command('display_message', $msg, 'error'); } // send html page with JS calls as response $OUTPUT->send('iframe'); - diff --git a/program/steps/mail/list.inc b/program/steps/mail/list.inc index a2380131a..277564c38 100644 --- a/program/steps/mail/list.inc +++ b/program/steps/mail/list.inc @@ -23,11 +23,11 @@ if (!$OUTPUT->ajax_call) { return; } -$save_arr = array(); -$dont_override = (array) $RCMAIL->config->get('dont_override'); +$save_arr = array(); +$dont_override = (array) $RCMAIL->config->get('dont_override'); // is there a sort type for this request? -if ($sort = get_input_value('_sort', RCUBE_INPUT_GET)) { +if ($sort = rcube_utils::get_input_value('_sort', rcube_utils::INPUT_GET)) { // yes, so set the sort vars list($sort_col, $sort_order) = explode('_', $sort); @@ -41,7 +41,7 @@ if ($sort = get_input_value('_sort', RCUBE_INPUT_GET)) { } // is there a set of columns for this request? -if ($cols = get_input_value('_cols', RCUBE_INPUT_GET)) { +if ($cols = rcube_utils::get_input_value('_cols', rcube_utils::INPUT_GET)) { if (!in_array('list_cols', $dont_override)) { $save_arr['list_cols'] = explode(',', $cols); } @@ -60,7 +60,7 @@ $RCMAIL->storage->folder_sync($mbox_name); // initialize searching result if search_filter is used if ($_SESSION['search_filter'] && $_SESSION['search_filter'] != 'ALL') { $search_request = md5($mbox_name.$_SESSION['search_filter']); - $RCMAIL->storage->search($mbox_name, $_SESSION['search_filter'], RCMAIL_CHARSET, rcmail_sort_column()); + $RCMAIL->storage->search($mbox_name, $_SESSION['search_filter'], RCUBE_CHARSET, rcmail_sort_column()); $_SESSION['search'] = $RCMAIL->storage->get_search_set(); $_SESSION['search_request'] = $search_request; $OUTPUT->set_env('search_request', $search_request); @@ -90,12 +90,14 @@ if (empty($search_request) && empty($a_headers)) { rcmail_send_unread_count($mbox_name, !empty($_REQUEST['_refresh']), $unseen); // update message count display -$pages = ceil($count/$RCMAIL->storage->get_pagesize()); +$pages = ceil($count/$RCMAIL->storage->get_pagesize()); +$exists = $RCMAIL->storage->count($mbox_name, 'EXISTS'); + $OUTPUT->set_env('messagecount', $count); $OUTPUT->set_env('pagecount', $pages); $OUTPUT->set_env('threading', $threading); $OUTPUT->set_env('current_page', $count ? $RCMAIL->storage->get_page() : 1); -$OUTPUT->set_env('exists', $RCMAIL->storage->count($mbox_name, 'EXISTS')); +$OUTPUT->set_env('exists', $exists); $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($count), $mbox_name); // add message rows @@ -104,11 +106,18 @@ if (isset($a_headers) && count($a_headers)) { if ($search_request) { $OUTPUT->show_message('searchsuccessful', 'confirmation', array('nr' => $count)); } + + // remember last HIGHESTMODSEQ value (if supported) + // we need it for flag updates in check-recent + $data = $RCMAIL->storage->folder_data($mbox_name); + if (!empty($data['HIGHESTMODSEQ'])) { + $_SESSION['list_mod_seq'] = $data['HIGHESTMODSEQ']; + } } else { // handle IMAP errors (e.g. #1486905) if ($err_code = $RCMAIL->storage->get_error_code()) { - rcmail_display_server_error(); + $RCMAIL->display_server_error(); } else if ($search_request) $OUTPUT->show_message('searchnomatch', 'notice'); @@ -116,5 +125,10 @@ else { $OUTPUT->show_message('nomessagesfound', 'notice'); } +// set trash folder state +if ($mbox_name === $RCMAIL->config->get('trash_mbox')) { + $OUTPUT->command('set_trash_count', $exists); +} + // send response $OUTPUT->send(); diff --git a/program/steps/mail/list_contacts.inc b/program/steps/mail/list_contacts.inc index dab146431..46f81353a 100644 --- a/program/steps/mail/list_contacts.inc +++ b/program/steps/mail/list_contacts.inc @@ -65,7 +65,7 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search } // list contacts from selected source else { - $source = get_input_value('_source', RCUBE_INPUT_GPC); + $source = rcube_utils::get_input_value('_source', rcube_utils::INPUT_GPC); $CONTACTS = $RCMAIL->get_address_book($source); if ($CONTACTS && $CONTACTS->ready) { @@ -73,7 +73,7 @@ else { $CONTACTS->set_pagesize($page_size); $CONTACTS->set_page($list_page); - if ($group_id = get_input_value('_gid', RCUBE_INPUT_GPC)) { + if ($group_id = rcube_utils::get_input_value('_gid', rcube_utils::INPUT_GPC)) { $CONTACTS->set_group($group_id); } // list groups of this source (on page one) @@ -89,7 +89,7 @@ else { $row_id = 'G'.$group['ID']; $jsresult[$row_id] = format_email_recipient($email, $group['name']); $OUTPUT->command('add_contact_row', $row_id, array( - 'contactgroup' => html::span(array('title' => $email), Q($group['name']))), 'group'); + 'contactgroup' => html::span(array('title' => $email), rcube::Q($group['name']))), 'group'); } } // make virtual groups clickable to list their members @@ -99,9 +99,9 @@ else { 'contactgroup' => html::a(array( 'href' => '#list', 'rel' => $row['ID'], - 'title' => rcube_label('listgroup'), - 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", JS_OBJECT_NAME, $source, $group['ID']), - ), Q($group['name']) . ' ' . html::span('action', '»'))), + 'title' => $RCMAIL->gettext('listgroup'), + 'onclick' => sprintf("return %s.command('pushgroup',{'source':'%s','id':'%s'},this,event)", rcmail_output::JS_OBJECT_NAME, $source, $group['ID']), + ), rcube::Q($group['name']) . ' ' . html::span('action', '»'))), 'group', array('ID' => $group['ID'], 'name' => $group['name'], 'virtual' => true)); } @@ -110,7 +110,7 @@ else { $row_id = 'E'.$group['ID']; $jsresult[$row_id] = $group['name']; $OUTPUT->command('add_contact_row', $row_id, array( - 'contactgroup' => Q($group['name'] . ' (' . intval($result->count) . ')')), 'group'); + 'contactgroup' => rcube::Q($group['name'] . ' (' . intval($result->count) . ')')), 'group'); } } @@ -134,14 +134,14 @@ else if (!empty($result) && $result->count > 0) { // add record for every email address of the contact $emails = $CONTACTS->get_col_values('email', $row, true); foreach ($emails as $i => $email) { - $row_id = $row['ID'].$i; + $row_id = $row['ID'].'-'.$i; $jsresult[$row_id] = format_email_recipient($email, $name); $classname = $row['_type'] == 'group' ? 'group' : 'person'; $keyname = $row['_type'] == 'group' ? 'contactgroup' : 'contact'; $OUTPUT->command('add_contact_row', $row_id, array( - $keyname => html::span(array('title' => $email), Q($name ? $name : $email) . - ($name && count($emails) > 1 ? ' ' . html::span('email', Q($email)) : '') + $keyname => html::span(array('title' => $email), rcube::Q($name ? $name : $email) . + ($name && count($emails) > 1 ? ' ' . html::span('email', rcube::Q($email)) : '') )), $classname); } } diff --git a/program/steps/mail/mark.inc b/program/steps/mail/mark.inc index fad11d0fc..50243c636 100644 --- a/program/steps/mail/mark.inc +++ b/program/steps/mail/mark.inc @@ -4,7 +4,7 @@ | program/steps/mail/mark.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,114 +19,125 @@ */ // only process ajax requests -if (!$OUTPUT->ajax_call) - return; - -$a_flags_map = array( - 'undelete' => 'UNDELETED', - 'delete' => 'DELETED', - 'read' => 'SEEN', - 'unread' => 'UNSEEN', - 'flagged' => 'FLAGGED', - 'unflagged' => 'UNFLAGGED'); - -$threading = (bool) $RCMAIL->storage->get_threading(); - -if (($_uids = get_input_value('_uid', RCUBE_INPUT_POST)) && ($flag = get_input_value('_flag', RCUBE_INPUT_POST))) -{ - $flag = $a_flags_map[$flag] ? $a_flags_map[$flag] : strtoupper($flag); - - if ($flag == 'DELETED' && $CONFIG['skip_deleted'] && $_POST['_from'] != 'show') { - // count messages before changing anything - $old_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL'); - $old_pages = ceil($old_count / $RCMAIL->storage->get_pagesize()); - } - - foreach (rcmail_get_uids() as $mbox => $uids) { - $marked += (int)$RCMAIL->storage->set_flag($uids, $flag, $mbox); - $count += count($uids); - } - - if (!$marked) { - // send error message - if ($_POST['_from'] != 'show') - $OUTPUT->command('list_mailbox'); - rcmail_display_server_error('errormarking'); - $OUTPUT->send(); - exit; - } - else if (empty($_POST['_quiet'])) { - $OUTPUT->show_message('messagemarked', 'confirmation'); - } - - if ($flag == 'DELETED' && $CONFIG['read_when_deleted'] && !empty($_POST['_ruid'])) { - $ruids = get_input_value('_ruid', RCUBE_INPUT_POST); - $read = $RCMAIL->storage->set_flag($ruids, 'SEEN'); - - if ($read && !$CONFIG['skip_deleted']) - $OUTPUT->command('flag_deleted_as_read', $ruids); - } - - if ($flag == 'SEEN' || $flag == 'UNSEEN' || ($flag == 'DELETED' && !$CONFIG['skip_deleted'])) { - rcmail_send_unread_count($RCMAIL->storage->get_folder()); - } - else if ($flag == 'DELETED' && $CONFIG['skip_deleted']) { - if ($_POST['_from'] == 'show') { - if ($next = get_input_value('_next_uid', RCUBE_INPUT_GPC)) - $OUTPUT->command('show_message', $next); - else - $OUTPUT->command('command', 'list'); - } else { - $search_request = get_input_value('_search', RCUBE_INPUT_GPC); - // refresh saved search set after moving some messages - if ($search_request && $RCMAIL->storage->get_search_set()) { - $_SESSION['search'] = $RCMAIL->storage->refresh_search(); - } - - $msg_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL'); - $page_size = $RCMAIL->storage->get_pagesize(); - $page = $RCMAIL->storage->get_page(); - $pages = ceil($msg_count / $page_size); - $nextpage_count = $old_count - $page_size * $page; - $remaining = $msg_count - $page_size * ($page - 1); - - // jump back one page (user removed the whole last page) - if ($page > 1 && $remaining == 0) { - $page -= 1; - $RCMAIL->storage->set_page($page); - $_SESSION['page'] = $page; - $jump_back = true; - } - - // update message count display - $OUTPUT->set_env('messagecount', $msg_count); - $OUTPUT->set_env('current_page', $page); - $OUTPUT->set_env('pagecount', $pages); - - // update mailboxlist - $mbox = $RCMAIL->storage->get_folder(); - $unseen_count = $msg_count ? $RCMAIL->storage->count($mbox, 'UNSEEN') : 0; - $old_unseen = rcmail_get_unseen_count($mbox); - - if ($old_unseen != $unseen_count) { - $OUTPUT->command('set_unread_count', $mbox, $unseen_count, ($mbox == 'INBOX')); - rcmail_set_unseen_count($mbox, $unseen_count); - } - $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count), $mbox); - - if ($threading) { - $count = get_input_value('_count', RCUBE_INPUT_POST); - } - - // add new rows from next page (if any) - if ($old_count && $_uids != '*' && ($jump_back || $nextpage_count > 0)) { - $a_headers = $RCMAIL->storage->list_messages($mbox, NULL, - rcmail_sort_column(), rcmail_sort_order(), $jump_back ? NULL : $count); - - rcmail_js_message_list($a_headers, false); - } +if (!$OUTPUT->ajax_call) { + return; +} + +$threading = (bool) $RCMAIL->storage->get_threading(); +$skip_deleted = (bool) $RCMAIL->config->get('skip_deleted'); +$read_deleted = (bool) $RCMAIL->config->get('read_when_deleted'); + +$a_flags_map = array( + 'undelete' => 'UNDELETED', + 'delete' => 'DELETED', + 'read' => 'SEEN', + 'unread' => 'UNSEEN', + 'flagged' => 'FLAGGED', + 'unflagged' => 'UNFLAGGED', +); + +if (($_uids = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST)) + && ($flag = rcube_utils::get_input_value('_flag', rcube_utils::INPUT_POST)) +) { + $flag = $a_flags_map[$flag] ? $a_flags_map[$flag] : strtoupper($flag); + + if ($flag == 'DELETED' && $skip_deleted && $_POST['_from'] != 'show') { + // count messages before changing anything + $old_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL'); + $old_pages = ceil($old_count / $RCMAIL->storage->get_pagesize()); + } + + foreach (rcmail_get_uids() as $mbox => $uids) { + $marked += (int)$RCMAIL->storage->set_flag($uids, $flag, $mbox); + $count += count($uids); + } + + if (!$marked) { + // send error message + if ($_POST['_from'] != 'show') { + $OUTPUT->command('list_mailbox'); + } + + $RCMAIL->display_server_error('errormarking'); + $OUTPUT->send(); + exit; + } + else if (empty($_POST['_quiet'])) { + $OUTPUT->show_message('messagemarked', 'confirmation'); + } + + if ($flag == 'DELETED' && $read_deleted && !empty($_POST['_ruid'])) { + $ruids = rcube_utils::get_input_value('_ruid', rcube_utils::INPUT_POST); + $read = $RCMAIL->storage->set_flag($ruids, 'SEEN'); + + if ($read && !$skip_deleted) { + $OUTPUT->command('flag_deleted_as_read', $ruids); + } + } + + if ($flag == 'SEEN' || $flag == 'UNSEEN' || ($flag == 'DELETED' && !$skip_deleted)) { + rcmail_send_unread_count($RCMAIL->storage->get_folder()); + } + else if ($flag == 'DELETED' && $skip_deleted) { + if ($_POST['_from'] == 'show') { + if ($next = rcube_utils::get_input_value('_next_uid', rcube_utils::INPUT_GPC)) + $OUTPUT->command('show_message', $next); + else + $OUTPUT->command('command', 'list'); + } + else { + $search_request = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC); + + // refresh saved search set after moving some messages + if ($search_request && $RCMAIL->storage->get_search_set()) { + $_SESSION['search'] = $RCMAIL->storage->refresh_search(); + } + + $msg_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL'); + $page_size = $RCMAIL->storage->get_pagesize(); + $page = $RCMAIL->storage->get_page(); + $pages = ceil($msg_count / $page_size); + $nextpage_count = $old_count - $page_size * $page; + $remaining = $msg_count - $page_size * ($page - 1); + + // jump back one page (user removed the whole last page) + if ($page > 1 && $remaining == 0) { + $page -= 1; + $RCMAIL->storage->set_page($page); + $_SESSION['page'] = $page; + $jump_back = true; + } + + // update message count display + $OUTPUT->set_env('messagecount', $msg_count); + $OUTPUT->set_env('current_page', $page); + $OUTPUT->set_env('pagecount', $pages); + + // update mailboxlist + $mbox = $RCMAIL->storage->get_folder(); + $unseen_count = $msg_count ? $RCMAIL->storage->count($mbox, 'UNSEEN') : 0; + $old_unseen = rcmail_get_unseen_count($mbox); + + if ($old_unseen != $unseen_count) { + $OUTPUT->command('set_unread_count', $mbox, $unseen_count, ($mbox == 'INBOX')); + rcmail_set_unseen_count($mbox, $unseen_count); + } + + $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count), $mbox); + + if ($threading) { + $count = rcube_utils::get_input_value('_count', rcube_utils::INPUT_POST); + } + + // add new rows from next page (if any) + if ($old_count && $_uids != '*' && ($jump_back || $nextpage_count > 0)) { + $a_headers = $RCMAIL->storage->list_messages($mbox, NULL, + rcmail_sort_column(), rcmail_sort_order(), $jump_back ? NULL : $count); + + rcmail_js_message_list($a_headers, false); + } + } } - } } else { $OUTPUT->show_message('internalerror', 'error'); diff --git a/program/steps/mail/move_del.inc b/program/steps/mail/move_del.inc index e172d7188..9a8b4a3ac 100644 --- a/program/steps/mail/move_del.inc +++ b/program/steps/mail/move_del.inc @@ -28,9 +28,15 @@ $threading = (bool) $RCMAIL->storage->get_threading(); $old_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL'); $old_pages = ceil($old_count / $RCMAIL->storage->get_pagesize()); +$trash = $RCMAIL->config->get('trash_mbox'); + // move messages if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) { +<<<<<<< HEAD + $target = rcube_utils::get_input_value('_target_mbox', rcube_utils::INPUT_POST, true); +======= $target = get_input_value('_target_mbox', RCUBE_INPUT_POST, true); +>>>>>>> 010a350715f1a36eab666fe26d3118ed025133c1 $trash = $RCMAIL->config->get('trash_mbox'); foreach (rcmail_get_uids() as $mbox => $uids) { @@ -42,7 +48,7 @@ if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_targe // send error message if ($_POST['_from'] != 'show') $OUTPUT->command('list_mailbox'); - rcmail_display_server_error('errormoving', null, $target == $trash ? 'delete' : ''); + $RCMAIL->display_server_error('errormoving', null, $target == $trash ? 'delete' : ''); $OUTPUT->send(); exit; } @@ -63,7 +69,7 @@ else if ($RCMAIL->action=='delete' && !empty($_POST['_uid'])) { // send error message if ($_POST['_from'] != 'show') $OUTPUT->command('list_mailbox'); - rcmail_display_server_error('errordeleting'); + $RCMAIL->display_server_error('errordeleting'); $OUTPUT->send(); exit; } @@ -80,23 +86,22 @@ else { exit; } -$search_request = get_input_value('_search', RCUBE_INPUT_GPC); +$search_request = rcube_utils::get_input_value('_search', rcube_utils::INPUT_GPC); // refresh saved search set after moving some messages if ($search_request && $RCMAIL->storage->get_search_set()) { $_SESSION['search'] = $RCMAIL->storage->refresh_search(); } -if ($_POST['_from'] == 'show') -{ - if ($next = get_input_value('_next_uid', RCUBE_INPUT_GPC)) +if ($_POST['_from'] == 'show') { + if ($next = rcube_utils::get_input_value('_next_uid', rcube_utils::INPUT_GPC)) $OUTPUT->command('show_message', $next); else $OUTPUT->command('command', 'list'); } -else -{ +else { $msg_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL'); + $exists = $RCMAIL->storage->count($mbox, 'EXISTS', true); $page_size = $RCMAIL->storage->get_pagesize(); $page = $RCMAIL->storage->get_page(); $pages = ceil($msg_count / $page_size); @@ -115,7 +120,7 @@ else $OUTPUT->set_env('messagecount', $msg_count); $OUTPUT->set_env('current_page', $page); $OUTPUT->set_env('pagecount', $pages); - $OUTPUT->set_env('exists', $RCMAIL->storage->count($mbox, 'EXISTS', true)); + $OUTPUT->set_env('exists', $exists); // update mailboxlist $mbox = $RCMAIL->storage->get_folder(); @@ -131,11 +136,11 @@ else rcmail_send_unread_count($target, true); } - $OUTPUT->command('set_quota', rcmail_quota_content()); + $OUTPUT->command('set_quota', $RCMAIL->quota_content()); $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($msg_count), $mbox); if ($threading) { - $count = get_input_value('_count', RCUBE_INPUT_POST); + $count = rcube_utils::get_input_value('_count', rcube_utils::INPUT_POST); } // add new rows from next page (if any) @@ -145,6 +150,14 @@ else rcmail_js_message_list($a_headers, false); } + + // set trash folder state + if ($mbox === $trash) { + $OUTPUT->command('set_trash_count', $exists); + } + else if ($target !== null && $target === $trash) { + $OUTPUT->command('set_trash_count', $RCMAIL->storage->count($trash, 'EXISTS')); + } } // send response diff --git a/program/steps/mail/pagenav.inc b/program/steps/mail/pagenav.inc index e4b70ad60..74cca88f2 100644 --- a/program/steps/mail/pagenav.inc +++ b/program/steps/mail/pagenav.inc @@ -19,7 +19,7 @@ +-----------------------------------------------------------------------+ */ -$uid = get_input_value('_uid', RCUBE_INPUT_GET); +$uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET); $index = $RCMAIL->storage->index(null, rcmail_sort_column(), rcmail_sort_order()); $cnt = $index->count_messages(); @@ -35,23 +35,27 @@ if ($prev) { $OUTPUT->set_env('prev_uid', $prev); $OUTPUT->command('enable_command', 'previousmessage', 'firstmessage', true); } + if ($next) { $OUTPUT->set_env('next_uid', $next); $OUTPUT->command('enable_command', 'nextmessage', 'lastmessage', true); } -if ($first) + +if ($first) { $OUTPUT->set_env('first_uid', $first); -if ($last) +} + +if ($last) { $OUTPUT->set_env('last_uid', $last); +} // Don't need a real messages count value $OUTPUT->set_env('messagecount', 1); // Set rowcount text -$OUTPUT->command('set_rowcount', rcube_label(array( +$OUTPUT->command('set_rowcount', $RCMAIL->gettext(array( 'name' => 'messagenrof', 'vars' => array('nr' => $pos+1, 'count' => $cnt) ))); $OUTPUT->send(); - diff --git a/program/steps/mail/search.inc b/program/steps/mail/search.inc index 7d128c73c..67fee755d 100644 --- a/program/steps/mail/search.inc +++ b/program/steps/mail/search.inc @@ -1,14 +1,18 @@ <?php + /* +-----------------------------------------------------------------------+ | steps/mail/search.inc | | | - | Search functions for rc webmail | + | This file is part of the Roundcube Webmail client | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | | See the README file for a full license statement. | | | + | PURPOSE: | + | Mail messages search action | +-----------------------------------------------------------------------+ | Author: Benjamin Smith <defitro@gmail.com> | | Thomas Bruederli <roundcube@gmail.com> | @@ -24,13 +28,13 @@ $_SESSION['page'] = 1; // using encodeURI with javascript "should" give us // a correctly encoded query string -$imap_charset = RCMAIL_CHARSET; +$imap_charset = RCUBE_CHARSET; // get search string -$str = get_input_value('_q', RCUBE_INPUT_GET, true); -$mbox = get_input_value('_mbox', RCUBE_INPUT_GET, true); -$filter = get_input_value('_filter', RCUBE_INPUT_GET); -$headers = get_input_value('_headers', RCUBE_INPUT_GET); +$str = rcube_utils::get_input_value('_q', rcube_utils::INPUT_GET, true); +$mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GET, true); +$filter = rcube_utils::get_input_value('_filter', rcube_utils::INPUT_GET); +$headers = rcube_utils::get_input_value('_headers', rcube_utils::INPUT_GET); $subject = array(); $search_request = md5($mbox.$filter.$str); @@ -41,67 +45,62 @@ $search_str = $filter && $filter != 'ALL' ? $filter : ''; $_SESSION['search_filter'] = $filter; // Check the search string for type of search -if (preg_match("/^from:.*/i", $str)) -{ - list(,$srch) = explode(":", $str); - $subject['from'] = "HEADER FROM"; -} -else if (preg_match("/^to:.*/i", $str)) -{ - list(,$srch) = explode(":", $str); - $subject['to'] = "HEADER TO"; -} -else if (preg_match("/^cc:.*/i", $str)) -{ - list(,$srch) = explode(":", $str); - $subject['cc'] = "HEADER CC"; -} -else if (preg_match("/^bcc:.*/i", $str)) -{ - list(,$srch) = explode(":", $str); - $subject['bcc'] = "HEADER BCC"; -} -else if (preg_match("/^subject:.*/i", $str)) -{ - list(,$srch) = explode(":", $str); - $subject['subject'] = "HEADER SUBJECT"; -} -else if (preg_match("/^body:.*/i", $str)) -{ - list(,$srch) = explode(":", $str); - $subject['body'] = "BODY"; -} -else if (strlen(trim($str))) -{ - if ($headers) { - foreach (explode(',', $headers) as $header) { - if ($header == 'text') { - // #1488208: get rid of other headers when searching by "TEXT" - $subject = array('text' => 'TEXT'); - break; - } - else { - $subject[$header] = ($header != 'body' ? 'HEADER ' : '') . strtoupper($header); - } +if (preg_match("/^from:.*/i", $str)) { + list(,$srch) = explode(":", $str); + $subject['from'] = "HEADER FROM"; +} +else if (preg_match("/^to:.*/i", $str)) { + list(,$srch) = explode(":", $str); + $subject['to'] = "HEADER TO"; +} +else if (preg_match("/^cc:.*/i", $str)) { + list(,$srch) = explode(":", $str); + $subject['cc'] = "HEADER CC"; +} +else if (preg_match("/^bcc:.*/i", $str)) { + list(,$srch) = explode(":", $str); + $subject['bcc'] = "HEADER BCC"; +} +else if (preg_match("/^subject:.*/i", $str)) { + list(,$srch) = explode(":", $str); + $subject['subject'] = "HEADER SUBJECT"; +} +else if (preg_match("/^body:.*/i", $str)) { + list(,$srch) = explode(":", $str); + $subject['body'] = "BODY"; +} +else if (strlen(trim($str))) { + if ($headers) { + foreach (explode(',', $headers) as $header) { + if ($header == 'text') { + // #1488208: get rid of other headers when searching by "TEXT" + $subject = array('text' => 'TEXT'); + break; + } + else { + $subject[$header] = ($header != 'body' ? 'HEADER ' : '') . strtoupper($header); + } + } + + // save search modifiers for the current folder to user prefs + $search_mods = rcmail_search_mods(); + $search_mods[$mbox] = array_fill_keys(array_keys($subject), 1); + + $RCMAIL->user->save_prefs(array('search_mods' => $search_mods)); + } + else { + // search in subject by default + $subject['subject'] = 'HEADER SUBJECT'; } - - // save search modifiers for the current folder to user prefs - $search_mods = $RCMAIL->config->get('search_mods', $SEARCH_MODS_DEFAULT); - $search_mods[$mbox] = array_fill_keys(array_keys($subject), 1); - $RCMAIL->user->save_prefs(array('search_mods' => $search_mods)); - } - else { - // search in subject by default - $subject['subject'] = 'HEADER SUBJECT'; - } } $search = isset($srch) ? trim($srch) : trim($str); if (!empty($subject)) { - $search_str .= str_repeat(' OR', count($subject)-1); - foreach ($subject as $sub) - $search_str .= ' ' . $sub . ' ' . rcube_imap_generic::escape($search); + $search_str .= str_repeat(' OR', count($subject)-1); + foreach ($subject as $sub) { + $search_str .= ' ' . $sub . ' ' . rcube_imap_generic::escape($search); + } } $search_str = trim($search_str); @@ -111,23 +110,42 @@ $sort_column = rcmail_sort_column(); $mboxes = $RCMAIL->storage->list_folders_subscribed('', '*', 'mail'); // execute IMAP search -if ($search_str) - $RCMAIL->storage->search($mboxes, $search_str, $imap_charset, $sort_column); +if ($search_str) { + $RCMAIL->storage->search($mbox, $search_str, $imap_charset, $sort_column); +} // save search results in session -if (!is_array($_SESSION['search'])) - $_SESSION['search'] = array(); +if (!is_array($_SESSION['search'])) { + $_SESSION['search'] = array(); +} if ($search_str) { - $_SESSION['search'] = $RCMAIL->storage->get_search_set(); - $_SESSION['last_text_search'] = $str; + $_SESSION['search'] = $RCMAIL->storage->get_search_set(); + $_SESSION['last_text_search'] = $str; } $_SESSION['search_request'] = $search_request; // Get the headers $result_h = $RCMAIL->storage->list_messages($mbox, 1, $sort_column, rcmail_sort_order()); -$count = $RCMAIL->storage->count($mbox, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL'); +$count = $RCMAIL->storage->count($mbox, $RCMAIL->storage->get_threading() ? 'THREADS' : 'ALL'); + +// Add 'folder' column to list +if ($_SESSION['search'][1]->multi) { + $a_show_cols = $_SESSION['list_attrib']['columns'] ? $_SESSION['list_attrib']['columns'] : (array)$CONFIG['list_cols']; + if (!in_array('folder', $a_show_cols)) + $a_show_cols[] = 'folder'; + + // make message UIDs unique by appending the folder name + foreach ($result_h as $i => $header) { + $header->uid .= '-'.$header->folder; + $header->flags['skip_mbox_check'] = true; + if ($header->parent_uid) + $header->parent_uid .= '-'.$header->folder; + } + + $OUTPUT->command('select_folder', ''); +} // Add 'folder' column to list if ($_SESSION['search'][1]->multi) { @@ -148,16 +166,24 @@ if ($_SESSION['search'][1]->multi) { // Make sure we got the headers if (!empty($result_h)) { - rcmail_js_message_list($result_h, false, $a_show_cols); - if ($search_str) - $OUTPUT->show_message('searchsuccessful', 'confirmation', array('nr' => $RCMAIL->storage->count(NULL, 'ALL'))); + rcmail_js_message_list($result_h, false, $a_show_cols); + if ($search_str) { + $OUTPUT->show_message('searchsuccessful', 'confirmation', array('nr' => $RCMAIL->storage->count(NULL, 'ALL'))); + } + + // remember last HIGHESTMODSEQ value (if supported) + // we need it for flag updates in check-recent + $data = $RCMAIL->storage->folder_data($mbox_name); + if (!empty($data['HIGHESTMODSEQ'])) { + $_SESSION['list_mod_seq'] = $data['HIGHESTMODSEQ']; + } } // handle IMAP errors (e.g. #1486905) else if ($err_code = $RCMAIL->storage->get_error_code()) { - rcmail_display_server_error(); + $RCMAIL->display_server_error(); } else { - $OUTPUT->show_message('searchnomatch', 'notice'); + $OUTPUT->show_message('searchnomatch', 'notice'); } // update message count display diff --git a/program/steps/mail/search_contacts.inc b/program/steps/mail/search_contacts.inc index 6a30ad1f5..4d5abf9ef 100644 --- a/program/steps/mail/search_contacts.inc +++ b/program/steps/mail/search_contacts.inc @@ -19,7 +19,7 @@ +-----------------------------------------------------------------------+ */ -$search = get_input_value('_q', RCUBE_INPUT_GPC, true); +$search = rcube_utils::get_input_value('_q', rcube_utils::INPUT_GPC, true); $sources = $RCMAIL->get_address_sources(); $search_mode = (int) $RCMAIL->config->get('addressbook_search_mode'); $addr_sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name'); @@ -76,11 +76,11 @@ if (!empty($result) && $result->count > 0) { // (same as in list_contacts.inc) $emails = $source->get_col_values('email', $row, true); foreach ($emails as $i => $email) { - $row_id = $row['ID'].$i; + $row_id = $row['ID'].'-'.$i; $jsresult[$row_id] = format_email_recipient($email, $name); $OUTPUT->command('add_contact_row', $row_id, array( - 'contact' => html::span(array('title' => $email), Q($name ? $name : $email) . - ($name && count($emails) > 1 ? ' ' . html::span('email', Q($email)) : '') + 'contact' => html::span(array('title' => $email), rcube::Q($name ? $name : $email) . + ($name && count($emails) > 1 ? ' ' . html::span('email', rcube::Q($email)) : '') )), 'person'); } } diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc index ccb8978be..0619d630b 100644 --- a/program/steps/mail/sendmail.inc +++ b/program/steps/mail/sendmail.inc @@ -5,7 +5,7 @@ | program/steps/mail/sendmail.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2011, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -24,434 +24,224 @@ $OUTPUT->reset(); $OUTPUT->framed = TRUE; -$savedraft = !empty($_POST['_draft']) ? true : false; +$savedraft = !empty($_POST['_draft']) ? true : false; +$sendmail_delay = (int) $RCMAIL->config->get('sendmail_delay'); +$drafts_mbox = $RCMAIL->config->get('drafts_mbox'); -$COMPOSE_ID = get_input_value('_id', RCUBE_INPUT_GPC); +$COMPOSE_ID = rcube_utils::get_input_value('_id', rcube_utils::INPUT_GPC); $COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; /****** checks ********/ if (!isset($COMPOSE['id'])) { - raise_error(array('code' => 500, 'type' => 'php', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Invalid compose ID"), true, false); - - $OUTPUT->show_message('internalerror', 'error'); - $OUTPUT->send('iframe'); -} + rcube::raise_error(array('code' => 500, 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Invalid compose ID"), true, false); -if (!$savedraft) { - if (empty($_POST['_to']) && empty($_POST['_cc']) && empty($_POST['_bcc']) - && empty($_POST['_subject']) && $_POST['_message']) { - $OUTPUT->show_message('sendingfailed', 'error'); + $OUTPUT->show_message('internalerror', 'error'); $OUTPUT->send('iframe'); - } - - if(!empty($CONFIG['sendmail_delay'])) { - $wait_sec = time() - intval($CONFIG['sendmail_delay']) - intval($CONFIG['last_message_time']); - if ($wait_sec < 0) { - $OUTPUT->show_message('senttooquickly', 'error', array('sec' => $wait_sec * -1)); - $OUTPUT->send('iframe'); - } - } -} - - -/****** message sending functions ********/ - -// encrypt parts of the header -function rcmail_encrypt_header($what) -{ - global $CONFIG, $RCMAIL; - if (!$CONFIG['http_received_header_encrypt']) { - return $what; - } - return $RCMAIL->encrypt($what); } -// get identity record -function rcmail_get_identity($id) -{ - global $RCMAIL, $message_charset; - global $RCMAIL; - - if ($sql_arr = $RCMAIL->user->get_identity($id)) { - $out = $sql_arr; - - if ($message_charset != RCMAIL_CHARSET) { - foreach ($out as $k => $v) - $out[$k] = rcube_charset_convert($v, RCMAIL_CHARSET, $message_charset); +if (!$savedraft) { + if (empty($_POST['_to']) && empty($_POST['_cc']) && empty($_POST['_bcc']) + && empty($_POST['_subject']) && $_POST['_message'] + ) { + $OUTPUT->show_message('sendingfailed', 'error'); + $OUTPUT->send('iframe'); } - $out['mailto'] = $sql_arr['email']; - $out['string'] = format_email_recipient($sql_arr['email'], $sql_arr['name']); - - return $out; - } - - return FALSE; -} - -/** - * go from this: - * <img src="http[s]://.../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" /> - * - * to this: - * - * <img src="/path/on/server/.../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" /> - */ -function rcmail_fix_emoticon_paths($mime_message) -{ - global $RCMAIL; - - $body = $mime_message->getHTMLBody(); - - // remove any null-byte characters before parsing - $body = preg_replace('/\x00/', '', $body); - - $searchstr = 'program/js/tiny_mce/plugins/emotions/img/'; - $offset = 0; - - // keep track of added images, so they're only added once - $included_images = array(); - - if (preg_match_all('# src=[\'"]([^\'"]+)#', $body, $matches, PREG_OFFSET_CAPTURE)) { - foreach ($matches[1] as $m) { - // find emoticon image tags - if (preg_match('#'.$searchstr.'(.*)$#', $m[0], $imatches)) { - $image_name = $imatches[1]; - - // sanitize image name so resulting attachment doesn't leave images dir - $image_name = preg_replace('/[^a-zA-Z0-9_\.\-]/i', '', $image_name); - $img_file = INSTALL_PATH . '/' . $searchstr . $image_name; - - if (! in_array($image_name, $included_images)) { - // add the image to the MIME message - if (!$mime_message->addHTMLImage($img_file, 'image/gif', '', true, $image_name)) { - $RCMAIL->output->show_message("emoticonerror", 'error'); - } - array_push($included_images, $image_name); + if ($sendmail_delay) { + $wait_sec = time() - $sendmail_delay - intval($RCMAIL->config->get('last_message_time')); + if ($wait_sec < 0) { + $OUTPUT->show_message('senttooquickly', 'error', array('sec' => $wait_sec * -1)); + $OUTPUT->send('iframe'); } - - $body = substr_replace($body, $img_file, $m[1] + $offset, strlen($m[0])); - $offset += strlen($img_file) - strlen($m[0]); - } } - } - - $mime_message->setHTMLBody($body); -} - -/** - * Extract image attachments from HTML content (data URIs) - */ -function rcmail_extract_inline_images($mime_message, $from) -{ - $body = $mime_message->getHTMLBody(); - $offset = 0; - $list = array(); - $regexp = '# src=[\'"](data:(image/[a-z]+);base64,([a-z0-9+/=\r\n]+))([\'"])#i'; - - // get domain for the Content-ID, must be the same as in Mail_Mime::get() - if (preg_match('#@([0-9a-zA-Z\-\.]+)#', $from, $matches)) { - $domain = $matches[1]; - } else { - $domain = 'localhost'; - } - - if (preg_match_all($regexp, $body, $matches, PREG_OFFSET_CAPTURE)) { - foreach ($matches[1] as $idx => $m) { - $data = preg_replace('/\r\n/', '', $matches[3][$idx][0]); - $data = base64_decode($data); - - if (empty($data)) { - continue; - } - - $hash = md5($data) . '@' . $domain; - $mime_type = $matches[2][$idx][0]; - $name = $list[$hash]; - - // add the image to the MIME message - if (!$name) { - $ext = preg_replace('#^[^/]+/#', '', $mime_type); - $name = substr($hash, 0, 8) . '.' . $ext; - $list[$hash] = $name; - - $mime_message->addHTMLImage($data, $mime_type, $name, false, $hash); - } - - $body = substr_replace($body, $name, $m[1] + $offset, strlen($m[0])); - $offset += strlen($name) - strlen($m[0]); - } - } - - $mime_message->setHTMLBody($body); -} - -/** - * Parse and cleanup email address input (and count addresses) - * - * @param string Address input - * @param boolean Do count recipients (saved in global $RECIPIENT_COUNT) - * @param boolean Validate addresses (errors saved in global $EMAIL_FORMAT_ERROR) - * @return string Canonical recipients string separated by comma - */ -function rcmail_email_input_format($mailto, $count=false, $check=true) -{ - global $RCMAIL, $EMAIL_FORMAT_ERROR, $RECIPIENT_COUNT; - - // simplified email regexp, supporting quoted local part - $email_regexp = '(\S+|("[^"]+"))@\S+'; - - $delim = trim($RCMAIL->config->get('recipients_separator', ',')); - $regexp = array("/[,;$delim]\s*[\r\n]+/", '/[\r\n]+/', "/[,;$delim]\s*\$/m", '/;/', '/(\S{1})(<'.$email_regexp.'>)/U'); - $replace = array($delim.' ', ', ', '', $delim, '\\1 \\2'); - - // replace new lines and strip ending ', ', make address input more valid - $mailto = trim(preg_replace($regexp, $replace, $mailto)); - - $result = array(); - $items = rcube_explode_quoted_string($delim, $mailto); - - foreach($items as $item) { - $item = trim($item); - // address in brackets without name (do nothing) - if (preg_match('/^<'.$email_regexp.'>$/', $item)) { - $item = rcube_idn_to_ascii(trim($item, '<>')); - $result[] = $item; - // address without brackets and without name (add brackets) - } else if (preg_match('/^'.$email_regexp.'$/', $item)) { - $item = rcube_idn_to_ascii($item); - $result[] = $item; - // address with name (handle name) - } else if (preg_match('/<*'.$email_regexp.'>*$/', $item, $matches)) { - $address = $matches[0]; - $name = trim(str_replace($address, '', $item)); - if ($name[0] == '"' && $name[count($name)-1] == '"') { - $name = substr($name, 1, -1); - } - $name = stripcslashes($name); - $address = rcube_idn_to_ascii(trim($address, '<>')); - $result[] = format_email_recipient($address, $name); - $item = $address; - } else if (trim($item)) { - continue; - } - - // check address format - $item = trim($item, '<>'); - if ($item && $check && !check_email($item)) { - $EMAIL_FORMAT_ERROR = $item; - return; - } - } - - if ($count) { - $RECIPIENT_COUNT += count($result); - } - - return implode(', ', $result); -} - - -function rcmail_generic_message_footer($isHtml) -{ - global $CONFIG; - - if ($isHtml && !empty($CONFIG['generic_message_footer_html'])) { - $file = $CONFIG['generic_message_footer_html']; - $html_footer = true; - } - else { - $file = $CONFIG['generic_message_footer']; - $html_footer = false; - } - - if ($file && realpath($file)) { - // sanity check - if (!preg_match('/\.(php|ini|conf)$/', $file) && strpos($file, '/etc/') === false) { - $footer = file_get_contents($file); - if ($isHtml && !$html_footer) - $footer = '<pre>' . $footer . '</pre>'; - return $footer; - } - } - - return false; } /****** compose message ********/ -if (strlen($_POST['_draft_saveid']) > 3) - $olddraftmessageid = get_input_value('_draft_saveid', RCUBE_INPUT_POST); - -$message_id = rcmail_gen_message_id(); +if (empty($COMPOSE['param']['message-id'])) { + $COMPOSE['param']['message-id'] = $RCMAIL->gen_message_id(); +} +$message_id = $COMPOSE['param']['message-id']; // set default charset $message_charset = isset($_POST['_charset']) ? $_POST['_charset'] : $OUTPUT->get_charset(); $EMAIL_FORMAT_ERROR = NULL; -$RECIPIENT_COUNT = 0; +$RECIPIENT_COUNT = 0; -$mailto = rcmail_email_input_format(get_input_value('_to', RCUBE_INPUT_POST, TRUE, $message_charset), true); -$mailcc = rcmail_email_input_format(get_input_value('_cc', RCUBE_INPUT_POST, TRUE, $message_charset), true); -$mailbcc = rcmail_email_input_format(get_input_value('_bcc', RCUBE_INPUT_POST, TRUE, $message_charset), true); +$mailto = rcmail_email_input_format(rcube_utils::get_input_value('_to', rcube_utils::INPUT_POST, TRUE, $message_charset), true); +$mailcc = rcmail_email_input_format(rcube_utils::get_input_value('_cc', rcube_utils::INPUT_POST, TRUE, $message_charset), true); +$mailbcc = rcmail_email_input_format(rcube_utils::get_input_value('_bcc', rcube_utils::INPUT_POST, TRUE, $message_charset), true); if ($EMAIL_FORMAT_ERROR) { - $OUTPUT->show_message('emailformaterror', 'error', array('email' => $EMAIL_FORMAT_ERROR)); - $OUTPUT->send('iframe'); + $OUTPUT->show_message('emailformaterror', 'error', array('email' => $EMAIL_FORMAT_ERROR)); + $OUTPUT->send('iframe'); } if (empty($mailto) && !empty($mailcc)) { - $mailto = $mailcc; - $mailcc = null; + $mailto = $mailcc; + $mailcc = null; +} +else if (empty($mailto)) { + $mailto = 'undisclosed-recipients:;'; } -else if (empty($mailto)) - $mailto = 'undisclosed-recipients:;'; // Get sender name and address... -$from = get_input_value('_from', RCUBE_INPUT_POST, true, $message_charset); +$from = rcube_utils::get_input_value('_from', rcube_utils::INPUT_POST, true, $message_charset); // ... from identity... if (is_numeric($from)) { - if (is_array($identity_arr = rcmail_get_identity($from))) { - if ($identity_arr['mailto']) - $from = $identity_arr['mailto']; - if ($identity_arr['string']) - $from_string = $identity_arr['string']; - } - else { - $from = null; - } + if (is_array($identity_arr = rcmail_get_identity($from))) { + if ($identity_arr['mailto']) + $from = $identity_arr['mailto']; + if ($identity_arr['string']) + $from_string = $identity_arr['string']; + } + else { + $from = null; + } } // ... if there is no identity record, this might be a custom from else if ($from_string = rcmail_email_input_format($from)) { - if (preg_match('/(\S+@\S+)/', $from_string, $m)) - $from = trim($m[1], '<>'); - else - $from = null; + if (preg_match('/(\S+@\S+)/', $from_string, $m)) + $from = trim($m[1], '<>'); + else + $from = null; } -if (!$from_string && $from) - $from_string = $from; +if (!$from_string && $from) { + $from_string = $from; +} // compose headers array $headers = array(); // if configured, the Received headers goes to top, for good measure -if ($CONFIG['http_received_header']) -{ - $nldlm = "\r\n\t"; - // FROM/VIA - $http_header = 'from '; - if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $host = $_SERVER['HTTP_X_FORWARDED_FOR']; +if ($RCMAIL->config->get('http_received_header')) { + $nldlm = "\r\n\t"; + $encrypt = $RCMAIL->config->get('http_received_header_encrypt'); + + // FROM/VIA + $http_header = 'from '; + + if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { + $hosts = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'], 2); + $hostname = gethostbyaddr($hosts[0]); + + if ($encrypt) { + $http_header .= rcmail_encrypt_header($hostname); + if ($host != $hostname) + $http_header .= ' ('. rcmail_encrypt_header($host) . ')'; + } + else { + $http_header .= (($host != $hostname) ? $hostname : '[' . $host . ']'); + if ($host != $hostname) + $http_header .= ' (['. $host .'])'; + } + $http_header .= $nldlm . ' via '; + } + + $host = $_SERVER['REMOTE_ADDR']; $hostname = gethostbyaddr($host); - if ($CONFIG['http_received_header_encrypt']) { - $http_header .= rcmail_encrypt_header($hostname); - if ($host != $hostname) - $http_header .= ' ('. rcmail_encrypt_header($host) . ')'; - } else { - $http_header .= (($host != $hostname) ? $hostname : '[' . $host . ']'); - if ($host != $hostname) - $http_header .= ' (['. $host .'])'; - } - $http_header .= $nldlm . ' via '; - } - $host = $_SERVER['REMOTE_ADDR']; - $hostname = gethostbyaddr($host); - if ($CONFIG['http_received_header_encrypt']) { - $http_header .= rcmail_encrypt_header($hostname); - if ($host != $hostname) - $http_header .= ' ('. rcmail_encrypt_header($host) . ')'; - } else { - $http_header .= (($host != $hostname) ? $hostname : '[' . $host . ']'); - if ($host != $hostname) - $http_header .= ' (['. $host .'])'; - } - // BY - $http_header .= $nldlm . 'by ' . $_SERVER['HTTP_HOST']; - // WITH - $http_header .= $nldlm . 'with HTTP (' . $_SERVER['SERVER_PROTOCOL'] . + + if ($encrypt) { + $http_header .= rcmail_encrypt_header($hostname); + if ($host != $hostname) + $http_header .= ' ('. rcmail_encrypt_header($host) . ')'; + } + else { + $http_header .= (($host != $hostname) ? $hostname : '[' . $host . ']'); + if ($host != $hostname) + $http_header .= ' (['. $host .'])'; + } + + // BY + $http_header .= $nldlm . 'by ' . $_SERVER['HTTP_HOST']; + + // WITH + $http_header .= $nldlm . 'with HTTP (' . $_SERVER['SERVER_PROTOCOL'] . ' '.$_SERVER['REQUEST_METHOD'] . '); ' . date('r'); - $http_header = wordwrap($http_header, 69, $nldlm); + $http_header = wordwrap($http_header, 69, $nldlm); - $headers['Received'] = $http_header; + $headers['Received'] = $http_header; } -$headers['Date'] = rcmail_user_date(); -$headers['From'] = rcube_charset_convert($from_string, RCMAIL_CHARSET, $message_charset); +$headers['Date'] = $RCMAIL->user_date(); +$headers['From'] = rcube_charset::convert($from_string, RCUBE_CHARSET, $message_charset); $headers['To'] = $mailto; // additional recipients if (!empty($mailcc)) { - $headers['Cc'] = $mailcc; + $headers['Cc'] = $mailcc; } if (!empty($mailbcc)) { - $headers['Bcc'] = $mailbcc; + $headers['Bcc'] = $mailbcc; } if (($max_recipients = (int) $RCMAIL->config->get('max_recipients')) > 0) { - if ($RECIPIENT_COUNT > $max_recipients) { - $OUTPUT->show_message('toomanyrecipients', 'error', array('max' => $max_recipients)); - $OUTPUT->send('iframe'); - } + if ($RECIPIENT_COUNT > $max_recipients) { + $OUTPUT->show_message('toomanyrecipients', 'error', array('max' => $max_recipients)); + $OUTPUT->send('iframe'); + } } // add subject -$headers['Subject'] = trim(get_input_value('_subject', RCUBE_INPUT_POST, TRUE, $message_charset)); +$headers['Subject'] = trim(rcube_utils::get_input_value('_subject', rcube_utils::INPUT_POST, TRUE, $message_charset)); if (!empty($identity_arr['organization'])) { - $headers['Organization'] = $identity_arr['organization']; + $headers['Organization'] = $identity_arr['organization']; } -if (!empty($_POST['_replyto'])) { - $headers['Reply-To'] = rcmail_email_input_format(get_input_value('_replyto', RCUBE_INPUT_POST, TRUE, $message_charset)); +if ($hdr = rcube_utils::get_input_value('_replyto', rcube_utils::INPUT_POST, TRUE, $message_charset)) { + $headers['Reply-To'] = rcmail_email_input_format($hdr); } if (!empty($headers['Reply-To'])) { - $headers['Mail-Reply-To'] = $headers['Reply-To']; + $headers['Mail-Reply-To'] = $headers['Reply-To']; } -if (!empty($_POST['_followupto'])) { - $headers['Mail-Followup-To'] = rcmail_email_input_format(get_input_value('_followupto', RCUBE_INPUT_POST, TRUE, $message_charset)); +if ($hdr = rcube_utils::get_input_value('_followupto', rcube_utils::INPUT_POST, TRUE, $message_charset)) { + $headers['Mail-Followup-To'] = rcmail_email_input_format(); } // remember reply/forward UIDs in special headers if (!empty($COMPOSE['reply_uid']) && $savedraft) { - $headers['X-Draft-Info'] = array('type' => 'reply', 'uid' => $COMPOSE['reply_uid']); + $headers['X-Draft-Info'] = array('type' => 'reply', 'uid' => $COMPOSE['reply_uid']); } else if (!empty($COMPOSE['forward_uid']) && $savedraft) { - $headers['X-Draft-Info'] = array('type' => 'forward', 'uid' => $COMPOSE['forward_uid']); + $headers['X-Draft-Info'] = array('type' => 'forward', 'uid' => $COMPOSE['forward_uid']); } if (!empty($COMPOSE['reply_msgid'])) { - $headers['In-Reply-To'] = $COMPOSE['reply_msgid']; + $headers['In-Reply-To'] = $COMPOSE['reply_msgid']; } if (!empty($COMPOSE['references'])) { - $headers['References'] = $COMPOSE['references']; + $headers['References'] = $COMPOSE['references']; } if (!empty($_POST['_priority'])) { - $priority = intval($_POST['_priority']); - $a_priorities = array(1=>'highest', 2=>'high', 4=>'low', 5=>'lowest'); - if ($str_priority = $a_priorities[$priority]) { - $headers['X-Priority'] = sprintf("%d (%s)", $priority, ucfirst($str_priority)); - } + $priority = intval($_POST['_priority']); + $a_priorities = array(1 => 'highest', 2 => 'high', 4 => 'low', 5 => 'lowest'); + + if ($str_priority = $a_priorities[$priority]) { + $headers['X-Priority'] = sprintf("%d (%s)", $priority, ucfirst($str_priority)); + } } if (!empty($_POST['_receipt'])) { - $headers['Return-Receipt-To'] = $from_string; - $headers['Disposition-Notification-To'] = $from_string; + $headers['Return-Receipt-To'] = $from_string; + $headers['Disposition-Notification-To'] = $from_string; } // additional headers $headers['Message-ID'] = $message_id; -$headers['X-Sender'] = $from; +$headers['X-Sender'] = $from; if (is_array($headers['X-Draft-Info'])) { - $headers['X-Draft-Info'] = rcmail_draftinfo_encode($headers['X-Draft-Info'] + array('folder' => $COMPOSE['mailbox'])); + $headers['X-Draft-Info'] = rcmail_draftinfo_encode($headers['X-Draft-Info'] + array('folder' => $COMPOSE['mailbox'])); } -if (!empty($CONFIG['useragent'])) { - $headers['User-Agent'] = $CONFIG['useragent']; +if ($hdr = $RCMAIL->config->get('useragent')) { + $headers['User-Agent'] = $hdr; } // exec hook for header checking and manipulation @@ -460,85 +250,85 @@ $data = $RCMAIL->plugins->exec_hook('message_outgoing_headers', array('headers' // sending aborted by plugin if ($data['abort'] && !$savedraft) { - $OUTPUT->show_message($data['message'] ? $data['message'] : 'sendingfailed'); - $OUTPUT->send('iframe'); + $OUTPUT->show_message($data['message'] ? $data['message'] : 'sendingfailed'); + $OUTPUT->send('iframe'); +} +else { + $headers = $data['headers']; } -else - $headers = $data['headers']; - -$isHtml = (bool) get_input_value('_is_html', RCUBE_INPUT_POST); +$isHtml = (bool) rcube_utils::get_input_value('_is_html', rcube_utils::INPUT_POST); // fetch message body -$message_body = get_input_value('_message', RCUBE_INPUT_POST, TRUE, $message_charset); +$message_body = rcube_utils::get_input_value('_message', rcube_utils::INPUT_POST, TRUE, $message_charset); if ($isHtml) { - $bstyle = array(); + $bstyle = array(); - if ($font_size = $RCMAIL->config->get('default_font_size')) { - $bstyle[] = 'font-size: ' . $font_size; - } - if ($font_family = $RCMAIL->config->get('default_font')) { - $bstyle[] = 'font-family: ' . rcmail::font_defs($font_family); - } + if ($font_size = $RCMAIL->config->get('default_font_size')) { + $bstyle[] = 'font-size: ' . $font_size; + } + if ($font_family = $RCMAIL->config->get('default_font')) { + $bstyle[] = 'font-family: ' . rcmail::font_defs($font_family); + } - // append doctype and html/body wrappers - $message_body = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">' - . "\r\n<html><body" . (!empty($bstyle) ? " style='" . implode($bstyle, '; ') . "'" : '') . ">\r\n" - . $message_body; + // append doctype and html/body wrappers + $message_body = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN">' + . "\r\n<html><body" . (!empty($bstyle) ? " style='" . implode($bstyle, '; ') . "'" : '') . ">\r\n" + . $message_body; } if (!$savedraft) { - if ($isHtml) { - // remove signature's div ID - $message_body = preg_replace('/\s*id="_rc_sig"/', '', $message_body); + if ($isHtml) { + // remove signature's div ID + $message_body = preg_replace('/\s*id="_rc_sig"/', '', $message_body); + + // add inline css for blockquotes + $bstyle = 'padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px'; + $message_body = preg_replace('/<blockquote>/', + '<blockquote type="cite" style="'.$bstyle.'">', $message_body); + } - // add inline css for blockquotes - $bstyle = 'padding-left:5px; border-left:#1010ff 2px solid; margin-left:5px'; - $message_body = preg_replace('/<blockquote>/', - '<blockquote type="cite" style="'.$bstyle.'">', $message_body); - } + // Check spelling before send + if ($RCMAIL->config->get('spellcheck_before_send') && $RCMAIL->config->get('enable_spellcheck') + && empty($COMPOSE['spell_checked']) && !empty($message_body) + ) { + $message_body = str_replace("\r\n", "\n", $message_body); + $spellchecker = new rcube_spellchecker(rcube_utils::get_input_value('_lang', rcube_utils::INPUT_GPC)); + $spell_result = $spellchecker->check($message_body, $isHtml); - // Check spelling before send - if ($CONFIG['spellcheck_before_send'] && $CONFIG['enable_spellcheck'] - && empty($COMPOSE['spell_checked']) && !empty($message_body) - ) { - $message_body = str_replace("\r\n", "\n", $message_body); - $spellchecker = new rcube_spellchecker(get_input_value('_lang', RCUBE_INPUT_GPC)); - $spell_result = $spellchecker->check($message_body, $isHtml); + $COMPOSE['spell_checked'] = true; - $COMPOSE['spell_checked'] = true; + if (!$spell_result) { + $result = $isHtml ? $spellchecker->get_words() : $spellchecker->get_xml(); - if (!$spell_result) { - $result = $isHtml ? $spellchecker->get_words() : $spellchecker->get_xml(); - $OUTPUT->show_message('mispellingsfound', 'error'); - $OUTPUT->command('spellcheck_resume', $isHtml, $result); - $OUTPUT->send('iframe'); + $OUTPUT->show_message('mispellingsfound', 'error'); + $OUTPUT->command('spellcheck_resume', $isHtml, $result); + $OUTPUT->send('iframe'); + } } - } - // generic footer for all messages - if ($footer = rcmail_generic_message_footer($isHtml)) { - $footer = rcube_charset_convert($footer, RCMAIL_CHARSET, $message_charset); - $message_body .= "\r\n" . $footer; - } + // generic footer for all messages + if ($footer = rcmail_generic_message_footer($isHtml)) { + $footer = rcube_charset::convert($footer, RCUBE_CHARSET, $message_charset); + $message_body .= "\r\n" . $footer; + } } if ($isHtml) { - $message_body .= "\r\n</body></html>\r\n"; + $message_body .= "\r\n</body></html>\r\n"; } // sort attachments to make sure the order is the same as in the UI (#1488423) -$files = get_input_value('_attachments', RCUBE_INPUT_POST); -if ($files) { - $files = explode(',', $files); - $files = array_flip($files); - foreach ($files as $idx => $val) { - $files[$idx] = $COMPOSE['attachments'][$idx]; - unset($COMPOSE['attachments'][$idx]); - } +if ($files = rcube_utils::get_input_value('_attachments', rcube_utils::INPUT_POST)) { + $files = explode(',', $files); + $files = array_flip($files); + foreach ($files as $idx => $val) { + $files[$idx] = $COMPOSE['attachments'][$idx]; + unset($COMPOSE['attachments'][$idx]); + } - $COMPOSE['attachments'] = array_merge(array_filter($files), $COMPOSE['attachments']); + $COMPOSE['attachments'] = array_merge(array_filter($files), $COMPOSE['attachments']); } // set line length for body wrapping @@ -552,110 +342,142 @@ $MAIL_MIME = new Mail_mime("\r\n"); // Check if we have enough memory to handle the message in it // It's faster than using files, so we'll do this if we only can -if (is_array($COMPOSE['attachments']) && $CONFIG['smtp_server'] - && ($mem_limit = parse_bytes(ini_get('memory_limit')))) -{ - $memory = function_exists('memory_get_usage') ? memory_get_usage() : 16*1024*1024; // safe value: 16MB - - foreach ($COMPOSE['attachments'] as $id => $attachment) - $memory += $attachment['size']; +if (is_array($COMPOSE['attachments']) && $RCMAIL->config->get('smtp_server') + && ($mem_limit = parse_bytes(ini_get('memory_limit'))) +) { + $memory = 0; + foreach ($COMPOSE['attachments'] as $id => $attachment) { + $memory += $attachment['size']; + } - // Yeah, Net_SMTP needs up to 12x more memory, 1.33 is for base64 - if ($memory * 1.33 * 12 > $mem_limit) - $MAIL_MIME->setParam('delay_file_io', true); + // Yeah, Net_SMTP needs up to 12x more memory, 1.33 is for base64 + if (!rcube_utils::mem_check($memory * 1.33 * 12)) { + $MAIL_MIME->setParam('delay_file_io', true); + } } // For HTML-formatted messages, construct the MIME message with both // the HTML part and the plain-text part - if ($isHtml) { - $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', - array('body' => $message_body, 'type' => 'html', 'message' => $MAIL_MIME)); + $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', + array('body' => $message_body, 'type' => 'html', 'message' => $MAIL_MIME)); - $MAIL_MIME->setHTMLBody($plugin['body']); + $MAIL_MIME->setHTMLBody($plugin['body']); - // replace emoticons - $plugin['body'] = rcmail_replace_emoticons($plugin['body']); + // replace emoticons + $plugin['body'] = $RCMAIL->replace_emoticons($plugin['body']); - // add a plain text version of the e-mail as an alternative part. - $h2t = new rcube_html2text($plugin['body'], false, true, 0, $message_charset); - $plainTextPart = rc_wordwrap($h2t->get_text(), $LINE_LENGTH, "\r\n", false, $message_charset); - $plainTextPart = wordwrap($plainTextPart, 998, "\r\n", true); + // add a plain text version of the e-mail as an alternative part. + $h2t = new rcube_html2text($plugin['body'], false, true, 0, $message_charset); + $plainTextPart = rcube_mime::wordwrap($h2t->get_text(), $LINE_LENGTH, "\r\n", false, $message_charset); + $plainTextPart = wordwrap($plainTextPart, 998, "\r\n", true); - // make sure all line endings are CRLF (#1486712) - $plainTextPart = preg_replace('/\r?\n/', "\r\n", $plainTextPart); + // make sure all line endings are CRLF (#1486712) + $plainTextPart = preg_replace('/\r?\n/', "\r\n", $plainTextPart); - $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', - array('body' => $plainTextPart, 'type' => 'alternative', 'message' => $MAIL_MIME)); + $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', + array('body' => $plainTextPart, 'type' => 'alternative', 'message' => $MAIL_MIME)); - $MAIL_MIME->setTXTBody($plugin['body']); + $MAIL_MIME->setTXTBody($plugin['body']); - // look for "emoticon" images from TinyMCE and change their src paths to - // be file paths on the server instead of URL paths. - rcmail_fix_emoticon_paths($MAIL_MIME); + // look for "emoticon" images from TinyMCE and change their src paths to + // be file paths on the server instead of URL paths. + rcmail_fix_emoticon_paths($MAIL_MIME); - // Extract image Data URIs into message attachments (#1488502) - rcmail_extract_inline_images($MAIL_MIME, $from); + // Extract image Data URIs into message attachments (#1488502) + rcmail_extract_inline_images($MAIL_MIME, $from); } else { - $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', - array('body' => $message_body, 'type' => 'plain', 'message' => $MAIL_MIME)); + $plugin = $RCMAIL->plugins->exec_hook('message_outgoing_body', + array('body' => $message_body, 'type' => 'plain', 'message' => $MAIL_MIME)); - $message_body = $plugin['body']; + $message_body = $plugin['body']; - // compose format=flowed content if enabled - if ($flowed = ($savedraft || $RCMAIL->config->get('send_format_flowed', true))) - $message_body = rcube_mime::format_flowed($message_body, min($LINE_LENGTH+2, 79), $message_charset); - else - $message_body = rc_wordwrap($message_body, $LINE_LENGTH, "\r\n", false, $message_charset); + // compose format=flowed content if enabled + if ($flowed = ($savedraft || $RCMAIL->config->get('send_format_flowed', true))) + $message_body = rcube_mime::format_flowed($message_body, min($LINE_LENGTH+2, 79), $message_charset); + else + $message_body = rcube_mime::wordwrap($message_body, $LINE_LENGTH, "\r\n", false, $message_charset); - $message_body = wordwrap($message_body, 998, "\r\n", true); + $message_body = wordwrap($message_body, 998, "\r\n", true); - $MAIL_MIME->setTXTBody($message_body, false, true); + $MAIL_MIME->setTXTBody($message_body, false, true); } // add stored attachments, if any -if (is_array($COMPOSE['attachments'])) -{ - foreach ($COMPOSE['attachments'] as $id => $attachment) { - // This hook retrieves the attachment contents from the file storage backend - $attachment = $RCMAIL->plugins->exec_hook('attachment_get', $attachment); +if (is_array($COMPOSE['attachments'])) { + foreach ($COMPOSE['attachments'] as $id => $attachment) { + // This hook retrieves the attachment contents from the file storage backend + $attachment = $RCMAIL->plugins->exec_hook('attachment_get', $attachment); + + if ($isHtml) { + $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' + . preg_quote($attachment['id']) . '[\s\'"]*/'; + $message_body = $MAIL_MIME->getHTMLBody(); + $is_inline = preg_match($dispurl, $message_body); + } + else { + $is_inline = false; + } - $dispurl = '/\ssrc\s*=\s*[\'"]*\S+display-attachment\S+file=rcmfile' . preg_quote($attachment['id']) . '[\s\'"]*/'; - $message_body = $MAIL_MIME->getHTMLBody(); - if ($isHtml && (preg_match($dispurl, $message_body) > 0)) { - $message_body = preg_replace($dispurl, ' src="'.$attachment['name'].'" ', $message_body); - $MAIL_MIME->setHTMLBody($message_body); + // inline image + if ($is_inline) { + // Mail_Mime does not support many inline attachments with the same name (#1489406) + // we'll generate cid: urls here to workaround this + $cid = preg_replace('/[^0-9a-zA-Z]/', '', uniqid(time(), true)); + if (preg_match('#(@[0-9a-zA-Z\-\.]+)#', $from, $matches)) { + $cid .= $matches[1]; + } + else { + $cid .= '@localhost'; + } - if ($attachment['data']) - $MAIL_MIME->addHTMLImage($attachment['data'], $attachment['mimetype'], $attachment['name'], false); - else - $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name'], true); - } - else { - $ctype = str_replace('image/pjpeg', 'image/jpeg', $attachment['mimetype']); // #1484914 - $file = $attachment['data'] ? $attachment['data'] : $attachment['path']; + $message_body = preg_replace($dispurl, ' src="cid:' . $cid . '" ', $message_body); + + $MAIL_MIME->setHTMLBody($message_body); - $MAIL_MIME->addAttachment($file, - $ctype, - $attachment['name'], - ($attachment['data'] ? false : true), - ($ctype == 'message/rfc822' ? '8bit' : 'base64'), - 'attachment', - '', '', '', - $CONFIG['mime_param_folding'] ? 'quoted-printable' : NULL, - $CONFIG['mime_param_folding'] == 2 ? 'quoted-printable' : NULL, - '', RCMAIL_CHARSET - ); + if ($attachment['data']) + $MAIL_MIME->addHTMLImage($attachment['data'], $attachment['mimetype'], $attachment['name'], false, $cid); + else + $MAIL_MIME->addHTMLImage($attachment['path'], $attachment['mimetype'], $attachment['name'], true, $cid); + } + else { + $ctype = str_replace('image/pjpeg', 'image/jpeg', $attachment['mimetype']); // #1484914 + $file = $attachment['data'] ? $attachment['data'] : $attachment['path']; + $folding = (int) $RCMAIL->config->get('mime_param_folding'); + + $MAIL_MIME->addAttachment($file, + $ctype, + $attachment['name'], + $attachment['data'] ? false : true, + $ctype == 'message/rfc822' ? '8bit' : 'base64', + 'attachment', + '', '', '', + $folding ? 'quoted-printable' : NULL, + $folding == 2 ? 'quoted-printable' : NULL, + '', RCUBE_CHARSET + ); + } } - } } // choose transfer encoding for plain/text body -if (preg_match('/[^\x00-\x7F]/', $MAIL_MIME->getTXTBody())) - $transfer_encoding = $RCMAIL->config->get('force_7bit') ? 'quoted-printable' : '8bit'; -else - $transfer_encoding = '7bit'; +if (preg_match('/[^\x00-\x7F]/', $MAIL_MIME->getTXTBody())) { + $text_charset = $message_charset; + $transfer_encoding = $RCMAIL->config->get('force_7bit') ? 'quoted-printable' : '8bit'; +} +else { + $text_charset = ''; + $transfer_encoding = '7bit'; +} + +if ($flowed) { + if (!$text_charset) { + $text_charset = 'US-ASCII'; + } + + $text_charset .= ";\r\n format=flowed"; +} // encoding settings for mail composing $MAIL_MIME->setParam('text_encoding', $transfer_encoding); @@ -663,191 +485,432 @@ $MAIL_MIME->setParam('html_encoding', 'quoted-printable'); $MAIL_MIME->setParam('head_encoding', 'quoted-printable'); $MAIL_MIME->setParam('head_charset', $message_charset); $MAIL_MIME->setParam('html_charset', $message_charset); -$MAIL_MIME->setParam('text_charset', $message_charset . ($flowed ? ";\r\n format=flowed" : '')); +$MAIL_MIME->setParam('text_charset', $text_charset); // encoding subject header with mb_encode provides better results with asian characters if (function_exists('mb_encode_mimeheader')) { - mb_internal_encoding($message_charset); - $headers['Subject'] = mb_encode_mimeheader($headers['Subject'], - $message_charset, 'Q', "\r\n", 8); - mb_internal_encoding(RCMAIL_CHARSET); + mb_internal_encoding($message_charset); + $headers['Subject'] = mb_encode_mimeheader($headers['Subject'], + $message_charset, 'Q', "\r\n", 8); + mb_internal_encoding(RCUBE_CHARSET); } // pass headers to message object $MAIL_MIME->headers($headers); // Begin SMTP Delivery Block -if (!$savedraft) -{ - // check 'From' address (identity may be incomplete) - if (empty($from)) { - $OUTPUT->show_message('nofromaddress', 'error'); - $OUTPUT->send('iframe'); - } - - // Handle Delivery Status Notification request - if (!empty($_POST['_dsn'])) { - $smtp_opts['dsn'] = true; - } - - $sent = rcmail_deliver_message($MAIL_MIME, $from, $mailto, - $smtp_error, $mailbody_file, $smtp_opts); +if (!$savedraft) { + // check 'From' address (identity may be incomplete) + if (empty($from)) { + $OUTPUT->show_message('nofromaddress', 'error'); + $OUTPUT->send('iframe'); + } - // return to compose page if sending failed - if (!$sent) { - // remove temp file - if ($mailbody_file) { - unlink($mailbody_file); + // Handle Delivery Status Notification request + if (!empty($_POST['_dsn'])) { + $smtp_opts['dsn'] = true; } - if ($smtp_error) - $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']); - else - $OUTPUT->show_message('sendingfailed', 'error'); - $OUTPUT->send('iframe'); - } + $sent = $RCMAIL->deliver_message($MAIL_MIME, $from, $mailto, + $smtp_error, $mailbody_file, $smtp_opts); - // save message sent time - if (!empty($CONFIG['sendmail_delay'])) - $RCMAIL->user->save_prefs(array('last_message_time' => time())); + // return to compose page if sending failed + if (!$sent) { + // remove temp file + if ($mailbody_file) { + unlink($mailbody_file); + } - // set replied/forwarded flag - if ($COMPOSE['reply_uid']) - $RCMAIL->storage->set_flag($COMPOSE['reply_uid'], 'ANSWERED', $COMPOSE['mailbox']); - else if ($COMPOSE['forward_uid']) - $RCMAIL->storage->set_flag($COMPOSE['forward_uid'], 'FORWARDED', $COMPOSE['mailbox']); + if ($smtp_error) + $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']); + else + $OUTPUT->show_message('sendingfailed', 'error'); + $OUTPUT->send('iframe'); + } -} // End of SMTP Delivery Block + // save message sent time + if ($sendmail_delay) { + $RCMAIL->user->save_prefs(array('last_message_time' => time())); + } + // set replied/forwarded flag + if ($COMPOSE['reply_uid']) + $RCMAIL->storage->set_flag($COMPOSE['reply_uid'], 'ANSWERED', $COMPOSE['mailbox']); + else if ($COMPOSE['forward_uid']) + $RCMAIL->storage->set_flag($COMPOSE['forward_uid'], 'FORWARDED', $COMPOSE['mailbox']); +} // Determine which folder to save message -if ($savedraft) - $store_target = $CONFIG['drafts_mbox']; -else if (!$RCMAIL->config->get('no_save_sent_messages')) - $store_target = isset($_POST['_store_target']) ? get_input_value('_store_target', RCUBE_INPUT_POST) : $CONFIG['sent_mbox']; +if ($savedraft) { + $store_target = $drafts_mbox; +} +else if (!$RCMAIL->config->get('no_save_sent_messages')) { + $store_target = rcube_utils::get_input_value('_store_target', rcube_utils::INPUT_POST); + if (!strlen($store_target)) { + $sore_target = $RCMAIL->config->get('sent_mbox'); + } +} if ($store_target) { - // check if folder is subscribed - if ($RCMAIL->storage->folder_exists($store_target, true)) - $store_folder = true; - // folder may be existing but not subscribed (#1485241) - else if (!$RCMAIL->storage->folder_exists($store_target)) - $store_folder = $RCMAIL->storage->create_folder($store_target, true); - else if ($RCMAIL->storage->subscribe($store_target)) - $store_folder = true; - - // append message to sent box - if ($store_folder) { - // message body in file - if ($mailbody_file || $MAIL_MIME->getParam('delay_file_io')) { - $headers = $MAIL_MIME->txtHeaders(); - - // file already created - if ($mailbody_file) - $msg = $mailbody_file; - else { - $temp_dir = $RCMAIL->config->get('temp_dir'); - $mailbody_file = tempnam($temp_dir, 'rcmMsg'); - if (!PEAR::isError($msg = $MAIL_MIME->saveMessageBody($mailbody_file))) - $msg = $mailbody_file; - } + // check if folder is subscribed + if ($RCMAIL->storage->folder_exists($store_target, true)) { + $store_folder = true; } - else { - $msg = $MAIL_MIME->getMessage(); - $headers = ''; + // folder may be existing but not subscribed (#1485241) + else if (!$RCMAIL->storage->folder_exists($store_target)) { + $store_folder = $RCMAIL->storage->create_folder($store_target, true); } - - if (PEAR::isError($msg)) - raise_error(array('code' => 650, 'type' => 'php', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Could not create message: ".$msg->getMessage()), - TRUE, FALSE); - else { - $saved = $RCMAIL->storage->save_message($store_target, $msg, $headers, - $mailbody_file ? true : false, array('SEEN')); + else if ($RCMAIL->storage->subscribe($store_target)) { + $store_folder = true; } - if ($mailbody_file) { - unlink($mailbody_file); - $mailbody_file = null; - } - } + // append message to sent box + if ($store_folder) { + // message body in file + if ($mailbody_file || $MAIL_MIME->getParam('delay_file_io')) { + $headers = $MAIL_MIME->txtHeaders(); - // raise error if saving failed - if (!$saved) { - raise_error(array('code' => 800, 'type' => 'imap', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Could not save message in $store_target"), TRUE, FALSE); + // file already created + if ($mailbody_file) { + $msg = $mailbody_file; + } + else { + $temp_dir = $RCMAIL->config->get('temp_dir'); + $mailbody_file = tempnam($temp_dir, 'rcmMsg'); - if ($savedraft) { - $OUTPUT->show_message('errorsaving', 'error'); - // start the auto-save timer again - $OUTPUT->command('auto_save_start'); - $OUTPUT->send('iframe'); - } - } + if (!PEAR::isError($msg = $MAIL_MIME->saveMessageBody($mailbody_file))) { + $msg = $mailbody_file; + } + } + } + else { + $msg = $MAIL_MIME->getMessage(); + $headers = ''; + } - if ($olddraftmessageid) { - // delete previous saved draft - // @TODO: use message UID (remember to check UIDVALIDITY) to skip this SEARCH - $delete_idx = $RCMAIL->storage->search_once($CONFIG['drafts_mbox'], - 'HEADER Message-ID '.$olddraftmessageid); + if (PEAR::isError($msg)) { + rcube::raise_error(array('code' => 650, 'type' => 'php', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Could not create message: ".$msg->getMessage()), + true, false); + } + else { + $saved = $RCMAIL->storage->save_message($store_target, $msg, $headers, + $mailbody_file ? true : false, array('SEEN')); + } - if ($del_uid = $delete_idx->get_element('FIRST')) { - $deleted = $RCMAIL->storage->delete_message($del_uid, $CONFIG['drafts_mbox']); + if ($mailbody_file) { + unlink($mailbody_file); + $mailbody_file = null; + } + } - // raise error if deletion of old draft failed - if (!$deleted) - raise_error(array('code' => 800, 'type' => 'imap', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => "Could not delete message from ".$CONFIG['drafts_mbox']), TRUE, FALSE); + // raise error if saving failed + if (!$saved) { + rcube::raise_error(array('code' => 800, 'type' => 'imap', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Could not save message in $store_target"), true, false); + + if ($savedraft) { + $OUTPUT->show_message('errorsaving', 'error'); + // start the auto-save timer again + $OUTPUT->command('auto_save_start'); + $OUTPUT->send('iframe'); + } + } + + // delete previous saved draft + if ($saved && ($old_id = rcube_utils::get_input_value('_draft_saveid', rcube_utils::INPUT_POST))) { + $deleted = $RCMAIL->storage->delete_message($old_id, $drafts_mbox); + + // raise error if deletion of old draft failed + if (!$deleted) { + rcube::raise_error(array('code' => 800, 'type' => 'imap', + 'file' => __FILE__, 'line' => __LINE__, + 'message' => "Could not delete message from $drafts_mbox"), true, false); + } } - } } // remove temp file else if ($mailbody_file) { - unlink($mailbody_file); + unlink($mailbody_file); } if ($savedraft) { - $msgid = strtr($message_id, array('>' => '', '<' => '')); + // remember new draft-uid ($saved could be an UID or true/false here) + if ($saved && is_bool($saved)) { + $index = $RCMAIL->storage->search_once($drafts_mbox, 'HEADER Message-ID ' . $message_id); + $saved = @max($index->get()); + } - // remember new draft-uid ($saved could be an UID or TRUE here) - if (is_bool($saved)) { - $draft_idx = $RCMAIL->storage->search_once($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$msgid); - $saved = $draft_idx->get_element('FIRST'); - } - $COMPOSE['param']['draft_uid'] = $saved; - $plugin = $RCMAIL->plugins->exec_hook('message_draftsaved', array('msgid' => $msgid, 'uid' => $saved, 'folder' => $store_target)); + if ($saved) { + $plugin = $RCMAIL->plugins->exec_hook('message_draftsaved', + array('msgid' => $message_id, 'uid' => $saved, 'folder' => $store_target)); - // display success - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'messagesaved', 'confirmation'); + // display success + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'messagesaved', 'confirmation'); - // update "_draft_saveid" and the "cmp_hash" to prevent "Unsaved changes" warning - $OUTPUT->command('set_draft_id', $msgid); - $OUTPUT->command('compose_field_hash', true); + // update "_draft_saveid" and the "cmp_hash" to prevent "Unsaved changes" warning + $COMPOSE['param']['draft_uid'] = $plugin['uid']; + $OUTPUT->command('set_draft_id', $plugin['uid']); + $OUTPUT->command('compose_field_hash', true); + } - // start the auto-save timer again - $OUTPUT->command('auto_save_start'); + // start the auto-save timer again + $OUTPUT->command('auto_save_start'); } else { - $folders = array(); + $folders = array(); - if ($COMPOSE['mode'] == 'reply' || $COMPOSE['mode'] == 'forward') - $folders[] = $COMPOSE['mailbox']; + if ($COMPOSE['mode'] == 'reply' || $COMPOSE['mode'] == 'forward') { + $folders[] = $COMPOSE['mailbox']; + } - rcmail_compose_cleanup($COMPOSE_ID); + rcmail_compose_cleanup($COMPOSE_ID); + $OUTPUT->command('remove_compose_data', $COMPOSE_ID); - if ($store_folder && !$saved) - $OUTPUT->command('sent_successfully', 'error', rcube_label('errorsavingsent'), $folders); - else { - if ($store_folder) { - $folders[] = $store_target; + if ($store_folder && !$saved) { + $OUTPUT->command('sent_successfully', 'error', $RCMAIL->gettext('errorsavingsent'), $folders); + } + else if ($store_folder) { + $folders[] = $store_target; } - $OUTPUT->command('sent_successfully', 'confirmation', rcube_label('messagesent'), $folders); - } + $OUTPUT->command('sent_successfully', 'confirmation', $RCMAIL->gettext('messagesent'), $folders); } $OUTPUT->send('iframe'); + + +/****** message sending functions ********/ + +// encrypt parts of the header +function rcmail_encrypt_header($what) +{ + global $RCMAIL; + + if (!$RCMAIL->config->get('http_received_header_encrypt')) { + return $what; + } + + return $RCMAIL->encrypt($what); +} + +// get identity record +function rcmail_get_identity($id) +{ + global $RCMAIL, $message_charset; + + if ($sql_arr = $RCMAIL->user->get_identity($id)) { + $out = $sql_arr; + + if ($message_charset != RCUBE_CHARSET) { + foreach ($out as $k => $v) { + $out[$k] = rcube_charset::convert($v, RCUBE_CHARSET, $message_charset); + } + } + + $out['mailto'] = $sql_arr['email']; + $out['string'] = format_email_recipient($sql_arr['email'], $sql_arr['name']); + + return $out; + } + + return false; +} + +/** + * go from this: + * <img src="http[s]://.../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" /> + * + * to this: + * + * <img src="/path/on/server/.../tiny_mce/plugins/emotions/images/smiley-cool.gif" border="0" alt="Cool" title="Cool" /> + */ +function rcmail_fix_emoticon_paths($mime_message) +{ + global $RCMAIL; + + $body = $mime_message->getHTMLBody(); + + // remove any null-byte characters before parsing + $body = preg_replace('/\x00/', '', $body); + + $searchstr = 'program/js/tiny_mce/plugins/emotions/img/'; + $offset = 0; + + // keep track of added images, so they're only added once + $included_images = array(); + + if (preg_match_all('# src=[\'"]([^\'"]+)#', $body, $matches, PREG_OFFSET_CAPTURE)) { + foreach ($matches[1] as $m) { + // find emoticon image tags + if (preg_match('#'.$searchstr.'(.*)$#', $m[0], $imatches)) { + $image_name = $imatches[1]; + + // sanitize image name so resulting attachment doesn't leave images dir + $image_name = preg_replace('/[^a-zA-Z0-9_\.\-]/i', '', $image_name); + $img_file = INSTALL_PATH . '/' . $searchstr . $image_name; + + if (! in_array($image_name, $included_images)) { + // add the image to the MIME message + if (!$mime_message->addHTMLImage($img_file, 'image/gif', '', true, $image_name)) { + $RCMAIL->output->show_message("emoticonerror", 'error'); + } + + array_push($included_images, $image_name); + } + + $body = substr_replace($body, $img_file, $m[1] + $offset, strlen($m[0])); + $offset += strlen($img_file) - strlen($m[0]); + } + } + } + + $mime_message->setHTMLBody($body); +} + +/** + * Extract image attachments from HTML content (data URIs) + */ +function rcmail_extract_inline_images($mime_message, $from) +{ + $body = $mime_message->getHTMLBody(); + $offset = 0; + $list = array(); + $domain = 'localhost'; + $regexp = '#img[^>]+src=[\'"](data:([^;]*);base64,([a-z0-9+/=\r\n]+))([\'"])#i'; + + if (preg_match_all($regexp, $body, $matches, PREG_OFFSET_CAPTURE)) { + // get domain for the Content-ID, must be the same as in Mail_Mime::get() + if (preg_match('#@([0-9a-zA-Z\-\.]+)#', $from, $m)) { + $domain = $m[1]; + } + + foreach ($matches[1] as $idx => $m) { + $data = preg_replace('/\r\n/', '', $matches[3][$idx][0]); + $data = base64_decode($data); + + if (empty($data)) { + continue; + } + + $hash = md5($data) . '@' . $domain; + $mime_type = $matches[2][$idx][0]; + $name = $list[$hash]; + + if (empty($mime_type)) { + $mime_type = rcube_mime::image_content_type($data); + } + + // add the image to the MIME message + if (!$name) { + $ext = preg_replace('#^[^/]+/#', '', $mime_type); + $name = substr($hash, 0, 8) . '.' . $ext; + $list[$hash] = $name; + + $mime_message->addHTMLImage($data, $mime_type, $name, false, $hash); + } + + $body = substr_replace($body, $name, $m[1] + $offset, strlen($m[0])); + $offset += strlen($name) - strlen($m[0]); + } + } + + $mime_message->setHTMLBody($body); +} + +/** + * Parse and cleanup email address input (and count addresses) + * + * @param string Address input + * @param boolean Do count recipients (saved in global $RECIPIENT_COUNT) + * @param boolean Validate addresses (errors saved in global $EMAIL_FORMAT_ERROR) + * @return string Canonical recipients string separated by comma + */ +function rcmail_email_input_format($mailto, $count=false, $check=true) +{ + global $RCMAIL, $EMAIL_FORMAT_ERROR, $RECIPIENT_COUNT; + + // simplified email regexp, supporting quoted local part + $email_regexp = '(\S+|("[^"]+"))@\S+'; + + $delim = trim($RCMAIL->config->get('recipients_separator', ',')); + $regexp = array("/[,;$delim]\s*[\r\n]+/", '/[\r\n]+/', "/[,;$delim]\s*\$/m", '/;/', '/(\S{1})(<'.$email_regexp.'>)/U'); + $replace = array($delim.' ', ', ', '', $delim, '\\1 \\2'); + + // replace new lines and strip ending ', ', make address input more valid + $mailto = trim(preg_replace($regexp, $replace, $mailto)); + $items = rcube_utils::explode_quoted_string($delim, $mailto); + $result = array(); + + foreach ($items as $item) { + $item = trim($item); + // address in brackets without name (do nothing) + if (preg_match('/^<'.$email_regexp.'>$/', $item)) { + $item = rcube_utils::idn_to_ascii(trim($item, '<>')); + $result[] = $item; + } + // address without brackets and without name (add brackets) + else if (preg_match('/^'.$email_regexp.'$/', $item)) { + $item = rcube_utils::idn_to_ascii($item); + $result[] = $item; + } + // address with name (handle name) + else if (preg_match('/<*'.$email_regexp.'>*$/', $item, $matches)) { + $address = $matches[0]; + $name = trim(str_replace($address, '', $item)); + if ($name[0] == '"' && $name[count($name)-1] == '"') { + $name = substr($name, 1, -1); + } + $name = stripcslashes($name); + $address = rcube_utils::idn_to_ascii(trim($address, '<>')); + $result[] = format_email_recipient($address, $name); + $item = $address; + } + else if (trim($item)) { + continue; + } + + // check address format + $item = trim($item, '<>'); + if ($item && $check && !rcube_utils::check_email($item)) { + $EMAIL_FORMAT_ERROR = $item; + return; + } + } + + if ($count) { + $RECIPIENT_COUNT += count($result); + } + + return implode(', ', $result); +} + + +function rcmail_generic_message_footer($isHtml) +{ + global $RCMAIL; + + if ($isHtml && ($file = $RCMAIL->config->get('generic_message_footer_html'))) { + $html_footer = true; + } + else { + $file = $RCMAIL->config->get('generic_message_footer'); + $html_footer = false; + } + + if ($file && realpath($file)) { + // sanity check + if (!preg_match('/\.(php|ini|conf)$/', $file) && strpos($file, '/etc/') === false) { + $footer = file_get_contents($file); + if ($isHtml && !$html_footer) { + $footer = '<pre>' . $footer . '</pre>'; + } + return $footer; + } + } + + return false; +} diff --git a/program/steps/mail/sendmdn.inc b/program/steps/mail/sendmdn.inc index 01d0807be..727e75bb9 100644 --- a/program/steps/mail/sendmdn.inc +++ b/program/steps/mail/sendmdn.inc @@ -5,7 +5,7 @@ | program/steps/mail/sendmdn.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2008-2009, The Roundcube Dev Team | + | Copyright (C) 2008-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -20,23 +20,24 @@ */ // only process ajax requests -if (!$OUTPUT->ajax_call) - return; +if (!$OUTPUT->ajax_call) { + return; +} if (!empty($_POST['_uid'])) { - $sent = rcmail_send_mdn(get_input_value('_uid', RCUBE_INPUT_POST), $smtp_error); + $sent = rcmail_send_mdn(rcube_utils::get_input_value('_uid', rcube_utils::INPUT_POST), $smtp_error); } // show either confirm or error message if ($sent) { - $OUTPUT->set_env('mdn_request', false); - $OUTPUT->show_message('receiptsent', 'confirmation'); + $OUTPUT->set_env('mdn_request', false); + $OUTPUT->show_message('receiptsent', 'confirmation'); } else if ($smtp_error) { - $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']); + $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']); } else { - $OUTPUT->show_message('errorsendingreceipt', 'error'); + $OUTPUT->show_message('errorsendingreceipt', 'error'); } $OUTPUT->send(); diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc index 9d85f9c8f..9498d1dc5 100644 --- a/program/steps/mail/show.inc +++ b/program/steps/mail/show.inc @@ -5,7 +5,7 @@ | program/steps/mail/show.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -22,312 +22,333 @@ $PRINT_MODE = $RCMAIL->action == 'print' ? TRUE : FALSE; // Read browser capabilities and store them in session -if ($caps = get_input_value('_caps', RCUBE_INPUT_GET)) { - $browser_caps = array(); - foreach (explode(',', $caps) as $cap) { - $cap = explode('=', $cap); - $browser_caps[$cap[0]] = $cap[1]; - } - $_SESSION['browser_caps'] = $browser_caps; +if ($caps = rcube_utils::get_input_value('_caps', rcube_utils::INPUT_GET)) { + $browser_caps = array(); + foreach (explode(',', $caps) as $cap) { + $cap = explode('=', $cap); + $browser_caps[$cap[0]] = $cap[1]; + } + $_SESSION['browser_caps'] = $browser_caps; } -$uid = get_input_value('_uid', RCUBE_INPUT_GET); +$uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET); $mbox_name = $RCMAIL->storage->get_folder(); // similar code as in program/steps/mail/get.inc if ($uid) { - // set message format (need to be done before rcube_message construction) - if (!empty($_GET['_format'])) { - $prefer_html = $_GET['_format'] == 'html'; - $RCMAIL->config->set('prefer_html', $prefer_html); - $_SESSION['msg_formats'][$mbox_name.':'.$uid] = $prefer_html; - } - else if (isset($_SESSION['msg_formats'][$mbox_name.':'.$uid])) { - $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$uid]); - } - - $MESSAGE = new rcube_message($uid); - - // if message not found (wrong UID)... - if (empty($MESSAGE->headers)) { - rcmail_message_error($uid); - } - - - // show images? - rcmail_check_safe($MESSAGE); - - // set message charset as default - if (!empty($MESSAGE->headers->charset)) - $RCMAIL->storage->set_charset($MESSAGE->headers->charset); - - $OUTPUT->set_pagetitle(abbreviate_string($MESSAGE->subject, 128, '...', true)); - - // give message uid to the client - $OUTPUT->set_env('uid', $MESSAGE->uid); - // set environement - $OUTPUT->set_env('safemode', $MESSAGE->is_safe); - $OUTPUT->set_env('sender', $MESSAGE->sender['string']); - $OUTPUT->set_env('permaurl', rcmail_url('show', array('_uid' => $MESSAGE->uid, '_mbox' => $mbox_name))); - $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter()); - $OUTPUT->set_env('mailbox', $mbox_name); - $OUTPUT->set_env('compose_extwin', $RCMAIL->config->get('compose_extwin',false)); - - // mimetypes supported by the browser (default settings) - $mimetypes = (array)$RCMAIL->config->get('client_mimetypes'); - - // Remove unsupported types, which makes that attachment which cannot be - // displayed in a browser will be downloaded directly without displaying an overlay page - if (empty($_SESSION['browser_caps']['pdf']) && ($key = array_search('application/pdf', $mimetypes)) !== false) { - unset($mimetypes[$key]); - } - if (empty($_SESSION['browser_caps']['flash']) && ($key = array_search('application/x-shockwave-flash', $mimetypes)) !== false) { - unset($mimetypes[$key]); - } - if (empty($_SESSION['browser_caps']['tif']) && ($key = array_search('image/tiff', $mimetypes)) !== false) { - // we can convert tiff to jpeg - if (!$RCMAIL->config->get('im_convert_path')) { - unset($mimetypes[$key]); + // set message format (need to be done before rcube_message construction) + if (!empty($_GET['_format'])) { + $prefer_html = $_GET['_format'] == 'html'; + $RCMAIL->config->set('prefer_html', $prefer_html); + $_SESSION['msg_formats'][$mbox_name.':'.$uid] = $prefer_html; } - } - - $OUTPUT->set_env('mimetypes', array_values($mimetypes)); - - if ($CONFIG['drafts_mbox']) - $OUTPUT->set_env('drafts_mailbox', $CONFIG['drafts_mbox']); - if ($CONFIG['trash_mbox']) - $OUTPUT->set_env('trash_mailbox', $CONFIG['trash_mbox']); - if ($CONFIG['junk_mbox']) - $OUTPUT->set_env('junk_mailbox', $CONFIG['junk_mbox']); - if ($CONFIG['delete_junk']) - $OUTPUT->set_env('delete_junk', true); - if ($CONFIG['flag_for_deletion']) - $OUTPUT->set_env('flag_for_deletion', true); - if ($CONFIG['read_when_deleted']) - $OUTPUT->set_env('read_when_deleted', true); - if ($CONFIG['skip_deleted']) - $OUTPUT->set_env('skip_deleted', true); - if ($CONFIG['display_next']) - $OUTPUT->set_env('display_next', true); - if ($MESSAGE->headers->get('list-post', false)) - $OUTPUT->set_env('list_post', true); - if ($CONFIG['forward_attachment']) - $OUTPUT->set_env('forward_attachment', true); - - if (!$OUTPUT->ajax_call) - $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', - 'movingmessage', 'deletingmessage', 'markingmessage', 'replyall', 'replylist'); - - $prefer_html = $RCMAIL->config->get('prefer_html'); - if ($MESSAGE->has_html_part()) { - $OUTPUT->set_env('optional_format', $prefer_html ? 'text' : 'html'); - } - - // check for unset disposition notification - if ($MESSAGE->headers->mdn_to - && empty($MESSAGE->headers->flags['MDNSENT']) - && empty($MESSAGE->headers->flags['SEEN']) - && ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*')) - && $mbox_name != $CONFIG['drafts_mbox'] - && $mbox_name != $CONFIG['sent_mbox'] - ) { - $mdn_cfg = intval($CONFIG['mdn_requests']); - - if ($mdn_cfg == 1 || (($mdn_cfg == 3 || $mdn_cfg == 4) && rcmail_contact_exists($MESSAGE->sender['mailto']))) { - // Send MDN - if (rcmail_send_mdn($MESSAGE, $smtp_error)) - $OUTPUT->show_message('receiptsent', 'confirmation'); - else if ($smtp_error) - $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']); - else - $OUTPUT->show_message('errorsendingreceipt', 'error'); + else if (isset($_SESSION['msg_formats'][$mbox_name.':'.$uid])) { + $RCMAIL->config->set('prefer_html', $_SESSION['msg_formats'][$mbox_name.':'.$uid]); } - else if ($mdn_cfg != 2 && $mdn_cfg != 4) { - // Ask user - $OUTPUT->add_label('mdnrequest'); - $OUTPUT->set_env('mdn_request', true); + + $MESSAGE = new rcube_message($uid); + + // if message not found (wrong UID)... + if (empty($MESSAGE->headers)) { + rcmail_message_error($uid); } - } - - if (empty($MESSAGE->headers->flags['SEEN']) - && ($RCMAIL->action == 'show' || ($RCMAIL->action == 'preview' && intval($CONFIG['preview_pane_mark_read']) == 0)) - ) { - $RCMAIL->plugins->exec_hook('message_read', array('uid' => $MESSAGE->uid, - 'mailbox' => $mbox_name, 'message' => $MESSAGE)); - } -} + // show images? + rcmail_check_safe($MESSAGE); -function rcmail_message_attachments($attrib) -{ - global $PRINT_MODE, $MESSAGE, $RCMAIL; - - $out = $ol = ''; - $attachments = array(); - - if (sizeof($MESSAGE->attachments)) { - foreach ($MESSAGE->attachments as $attach_prop) { - $filename = rcmail_attachment_name($attach_prop, true); - - if ($PRINT_MODE) { - $size = $RCMAIL->message_part_size($attach_prop); - $ol .= html::tag('li', null, Q(sprintf("%s (%s)", $filename, $size))); - } - else { - if ($attrib['maxlength'] && mb_strlen($filename) > $attrib['maxlength']) { - $title = $filename; - $filename = abbreviate_string($filename, $attrib['maxlength']); + // set message charset as default + if (!empty($MESSAGE->headers->charset)) { + $RCMAIL->storage->set_charset($MESSAGE->headers->charset); + } + + $OUTPUT->set_pagetitle(abbreviate_string($MESSAGE->subject, 128, '...', true)); + + // set message environment + $OUTPUT->set_env('uid', $MESSAGE->uid); + $OUTPUT->set_env('safemode', $MESSAGE->is_safe); + $OUTPUT->set_env('sender', $MESSAGE->sender['string']); + $OUTPUT->set_env('mailbox', $mbox_name); + $OUTPUT->set_env('permaurl', $RCMAIL->url(array('_action' => 'show', '_uid' => $MESSAGE->uid, '_mbox' => $mbox_name))); + + if ($MESSAGE->headers->get('list-post', false)) { + $OUTPUT->set_env('list_post', true); + } + + // set environment + $OUTPUT->set_env('delimiter', $RCMAIL->storage->get_hierarchy_delimiter()); + + // set configuration + $RCMAIL->set_env_config(array('delete_junk', 'flag_for_deletion', 'read_when_deleted', + 'skip_deleted', 'display_next', 'compose_extwin', 'forward_attachment')); + + // set special folders + foreach (array('drafts', 'trash', 'junk') as $mbox) { + if ($folder = $RCMAIL->config->get($mbox . '_mbox')) { + $OUTPUT->set_env($mbox . '_mailbox', $folder); } - else { - $title = ''; + } + + // mimetypes supported by the browser (default settings) + $mimetypes = (array)$RCMAIL->config->get('client_mimetypes'); + + // Remove unsupported types, which makes that attachment which cannot be + // displayed in a browser will be downloaded directly without displaying an overlay page + if (empty($_SESSION['browser_caps']['pdf']) && ($key = array_search('application/pdf', $mimetypes)) !== false) { + unset($mimetypes[$key]); + } + if (empty($_SESSION['browser_caps']['flash']) && ($key = array_search('application/x-shockwave-flash', $mimetypes)) !== false) { + unset($mimetypes[$key]); + } + if (empty($_SESSION['browser_caps']['tif']) && ($key = array_search('image/tiff', $mimetypes)) !== false) { + // we can convert tiff to jpeg + if (!$RCMAIL->config->get('im_convert_path')) { + unset($mimetypes[$key]); } + } - $mimetype = rcmail_fix_mimetype($attach_prop->mimetype); - $class = rcmail_filetype2classname($mimetype, $filename); - $id = 'attach' . $attach_prop->mime_id; - $link = html::a(array( - 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false), - 'onclick' => sprintf('return %s.command(\'load-attachment\',\'%s\',this)', - JS_OBJECT_NAME, $attach_prop->mime_id), - 'onmouseover' => $title ? '' : 'rcube_webmail.long_subject_title_ex(this, 0)', - 'title' => Q($title), - ), Q($filename)); - $ol .= html::tag('li', array('class' => $class, 'id' => $id), $link); - - $attachments[$attach_prop->mime_id] = $mimetype; - } + $OUTPUT->set_env('mimetypes', array_values($mimetypes)); + + if ($MESSAGE->has_html_part()) { + $prefer_html = $RCMAIL->config->get('prefer_html'); + $OUTPUT->set_env('optional_format', $prefer_html ? 'text' : 'html'); + } + + if (!$OUTPUT->ajax_call) { + $OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash', + 'movingmessage', 'deletingmessage', 'markingmessage', 'replyall', 'replylist'); } - $out = html::tag('ul', $attrib, $ol, html::$common_attrib); - $RCMAIL->output->set_env('attachments', $attachments); - } + // check for unset disposition notification + if ($MESSAGE->headers->mdn_to + && empty($MESSAGE->headers->flags['MDNSENT']) + && empty($MESSAGE->headers->flags['SEEN']) + && ($RCMAIL->storage->check_permflag('MDNSENT') || $RCMAIL->storage->check_permflag('*')) + && $mbox_name != $RCMAIL->config->get('drafts_mbox') + && $mbox_name != $RCMAIL->config->get('sent_mbox') + ) { + $mdn_cfg = intval($RCMAIL->config->get('mdn_requests')); + + if ($mdn_cfg == 1 || (($mdn_cfg == 3 || $mdn_cfg == 4) && rcmail_contact_exists($MESSAGE->sender['mailto']))) { + // Send MDN + if (rcmail_send_mdn($MESSAGE, $smtp_error)) + $OUTPUT->show_message('receiptsent', 'confirmation'); + else if ($smtp_error) + $OUTPUT->show_message($smtp_error['label'], 'error', $smtp_error['vars']); + else + $OUTPUT->show_message('errorsendingreceipt', 'error'); + } + else if ($mdn_cfg != 2 && $mdn_cfg != 4) { + // Ask user + $OUTPUT->add_label('mdnrequest'); + $OUTPUT->set_env('mdn_request', true); + } + } - return $out; + if (empty($MESSAGE->headers->flags['SEEN']) + && ($RCMAIL->action == 'show' || ($RCMAIL->action == 'preview' && intval($RCMAIL->config->get('preview_pane_mark_read')) == 0)) + ) { + $RCMAIL->plugins->exec_hook('message_read', array( + 'uid' => $MESSAGE->uid, + 'mailbox' => $mbox_name, + 'message' => $MESSAGE, + )); + } } -function rcmail_remote_objects_msg() + +$OUTPUT->add_handlers(array( + 'messageattachments' => 'rcmail_message_attachments', + 'mailboxname' => 'rcmail_mailbox_name_display', + 'messageobjects' => 'rcmail_message_objects', + 'contactphoto' => 'rcmail_message_contactphoto', +)); + + +if ($RCMAIL->action == 'print' && $OUTPUT->template_exists('messageprint')) + $OUTPUT->send('messageprint', false); +else if ($RCMAIL->action == 'preview' && $OUTPUT->template_exists('messagepreview')) + $OUTPUT->send('messagepreview', false); +else + $OUTPUT->send('message', false); + + +// mark message as read +if ($MESSAGE && $MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN']) && + ($RCMAIL->action == 'show' || ($RCMAIL->action == 'preview' && intval($RCMAIL->config->get('preview_pane_mark_read')) == 0)) +) { + if ($RCMAIL->storage->set_flag($MESSAGE->uid, 'SEEN')) { + if ($count = rcmail_get_unseen_count($mbox_name)) { + rcmail_set_unseen_count($mbox_name, $count - 1); + } + } +} + +exit; + + + +function rcmail_message_attachments($attrib) { - global $MESSAGE, $RCMAIL; + global $PRINT_MODE, $MESSAGE, $RCMAIL; + + $out = $ol = ''; + $attachments = array(); + + if (sizeof($MESSAGE->attachments)) { + foreach ($MESSAGE->attachments as $attach_prop) { + $filename = rcmail_attachment_name($attach_prop, true); + + if ($PRINT_MODE) { + $size = $RCMAIL->message_part_size($attach_prop); + $ol .= html::tag('li', null, rcube::Q(sprintf("%s (%s)", $filename, $size))); + } + else { + if ($attrib['maxlength'] && mb_strlen($filename) > $attrib['maxlength']) { + $title = $filename; + $filename = abbreviate_string($filename, $attrib['maxlength']); + } + else { + $title = ''; + } + + $mimetype = rcmail_fix_mimetype($attach_prop->mimetype); + $class = rcube_utils::file2class($mimetype, $filename); + $id = 'attach' . $attach_prop->mime_id; + $link = html::a(array( + 'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false), + 'onclick' => sprintf('return %s.command(\'load-attachment\',\'%s\',this)', + rcmail_output::JS_OBJECT_NAME, $attach_prop->mime_id), + 'onmouseover' => $title ? '' : 'rcube_webmail.long_subject_title_ex(this, 0)', + 'title' => rcube::Q($title), + ), rcube::Q($filename)); + + $ol .= html::tag('li', array('class' => $class, 'id' => $id), $link); + + $attachments[$attach_prop->mime_id] = $mimetype; + } + } - $attrib['id'] = 'remote-objects-message'; - $attrib['class'] = 'notice'; - $attrib['style'] = 'display: none'; + $out = html::tag('ul', $attrib, $ol, html::$common_attrib); - $msg = Q(rcube_label('blockedimages')) . ' '; - $msg .= html::a(array('href' => "#loadimages", 'onclick' => JS_OBJECT_NAME.".command('load-images')"), Q(rcube_label('showimages'))); + $RCMAIL->output->set_env('attachments', $attachments); + } + + return $out; +} + +function rcmail_remote_objects_msg() +{ + global $MESSAGE, $RCMAIL; + + $attrib['id'] = 'remote-objects-message'; + $attrib['class'] = 'notice'; + $attrib['style'] = 'display: none'; + + $msg = rcube::Q($RCMAIL->gettext('blockedimages')) . ' '; + $msg .= html::a(array( + 'href' => "#loadimages", + 'onclick' => rcmail_output::JS_OBJECT_NAME.".command('load-images')" + ), + rcube::Q($RCMAIL->gettext('showimages'))); + + // add link to save sender in addressbook and reload message + if ($MESSAGE->sender['mailto'] && $RCMAIL->config->get('show_images') == 1) { + $msg .= ' ' . html::a(array( + 'href' => "#alwaysload", + 'onclick' => rcmail_output::JS_OBJECT_NAME.".command('always-load')", + 'style' => "white-space:nowrap" + ), + rcube::Q($RCMAIL->gettext(array('name' => 'alwaysshow', 'vars' => array('sender' => $MESSAGE->sender['mailto']))))); + } - // add link to save sender in addressbook and reload message - if ($MESSAGE->sender['mailto'] && $RCMAIL->config->get('show_images') == 1) { - $msg .= ' ' . html::a(array('href' => "#alwaysload", 'onclick' => JS_OBJECT_NAME.".command('always-load')", 'style' => "white-space:nowrap"), - Q(rcube_label(array('name' => 'alwaysshow', 'vars' => array('sender' => $MESSAGE->sender['mailto']))))); - } + $RCMAIL->output->add_gui_object('remoteobjectsmsg', $attrib['id']); - $RCMAIL->output->add_gui_object('remoteobjectsmsg', $attrib['id']); - return html::div($attrib, $msg); + return html::div($attrib, $msg); } function rcmail_message_buttons() { - global $RCMAIL; + global $RCMAIL; - $mbox = $RCMAIL->storage->get_folder(); - $delim = $RCMAIL->storage->get_hierarchy_delimiter(); - $dbox = $RCMAIL->config->get('drafts_mbox'); + $mbox = $RCMAIL->storage->get_folder(); + $delim = $RCMAIL->storage->get_hierarchy_delimiter(); + $dbox = $RCMAIL->config->get('drafts_mbox'); - // the message is not a draft - if ($mbox != $dbox && strpos($mbox, $dbox.$delim) !== 0) { - return ''; - } + // the message is not a draft + if ($mbox != $dbox && strpos($mbox, $dbox.$delim) !== 0) { + return ''; + } - $attrib['id'] = 'message-buttons'; - $attrib['class'] = 'notice'; + $attrib['id'] = 'message-buttons'; + $attrib['class'] = 'notice'; - $msg = Q(rcube_label('isdraft')) . ' '; - $msg .= html::a(array('href' => "#edit", 'onclick' => JS_OBJECT_NAME.".command('edit')"), Q(rcube_label('edit'))); + $msg = rcube::Q($RCMAIL->gettext('isdraft')) . ' '; + $msg .= html::a(array( + 'href' => "#edit", + 'onclick' => rcmail_output::JS_OBJECT_NAME.".command('edit')" + ), + rcube::Q($RCMAIL->gettext('edit'))); - return html::div($attrib, $msg); + return html::div($attrib, $msg); } function rcmail_message_objects($attrib) { - global $RCMAIL, $MESSAGE; + global $RCMAIL, $MESSAGE; - if (!$attrib['id']) - $attrib['id'] = 'message-objects'; + if (!$attrib['id']) + $attrib['id'] = 'message-objects'; - $content = array( - rcmail_message_buttons(), - rcmail_remote_objects_msg(), - ); + $content = array( + rcmail_message_buttons(), + rcmail_remote_objects_msg(), + ); - $plugin = $RCMAIL->plugins->exec_hook('message_objects', - array('content' => $content, 'message' => $MESSAGE)); + $plugin = $RCMAIL->plugins->exec_hook('message_objects', + array('content' => $content, 'message' => $MESSAGE)); - $content = implode("\n", $plugin['content']); + $content = implode("\n", $plugin['content']); - return html::div($attrib, $content); + return html::div($attrib, $content); } function rcmail_contact_exists($email) { - global $RCMAIL; + global $RCMAIL; - if ($email) { - // @TODO: search in all address books? - $CONTACTS = $RCMAIL->get_address_book(-1, true); + if ($email) { + // @TODO: search in all address books? + $CONTACTS = $RCMAIL->get_address_book(-1, true); - if (is_object($CONTACTS)) { - $existing = $CONTACTS->search('email', $email, true, false); - if ($existing->count) { - return true; - } + if (is_object($CONTACTS)) { + $existing = $CONTACTS->search('email', $email, true, false); + if ($existing->count) { + return true; + } + } } - } - return false; + return false; } function rcmail_message_contactphoto($attrib) { - global $RCMAIL, $MESSAGE; + global $RCMAIL, $MESSAGE; - $placeholder = $attrib['placeholder'] ? $RCMAIL->config->get('skin_path') . $attrib['placeholder'] : null; - if ($MESSAGE->sender) - $photo_img = $RCMAIL->url(array('_task' => 'addressbook', '_action' => 'photo', '_email' => $MESSAGE->sender['mailto'], '_alt' => $placeholder)); - else - $photo_img = $placeholder ? $placeholder : 'program/resources/blank.gif'; + $placeholder = $attrib['placeholder'] ? $RCMAIL->config->get('skin_path') . $attrib['placeholder'] : null; - return html::img(array('src' => $photo_img) + $attrib); -} - - -$OUTPUT->add_handlers(array( - 'messageattachments' => 'rcmail_message_attachments', - 'mailboxname' => 'rcmail_mailbox_name_display', - 'messageobjects' => 'rcmail_message_objects', - 'contactphoto' => 'rcmail_message_contactphoto', -)); - - -if ($RCMAIL->action == 'print' && $OUTPUT->template_exists('messageprint')) - $OUTPUT->send('messageprint', false); -else if ($RCMAIL->action == 'preview' && $OUTPUT->template_exists('messagepreview')) - $OUTPUT->send('messagepreview', false); -else - $OUTPUT->send('message', false); - - -// mark message as read -if ($MESSAGE && $MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN']) && - ($RCMAIL->action == 'show' || ($RCMAIL->action == 'preview' && intval($CONFIG['preview_pane_mark_read']) == 0))) -{ - if ($RCMAIL->storage->set_flag($MESSAGE->uid, 'SEEN')) { - if ($count = rcmail_get_unseen_count($mbox_name)) { - rcmail_set_unseen_count($mbox_name, $count - 1); + if ($MESSAGE->sender) { + $photo_img = $RCMAIL->url(array( + '_task' => 'addressbook', + '_action' => 'photo', + '_email' => $MESSAGE->sender['mailto'], + '_alt' => $placeholder + )); + } + else { + $photo_img = $placeholder ? $placeholder : 'program/resources/blank.gif'; } - } -} - -exit; + return html::img(array('src' => $photo_img) + $attrib); +} diff --git a/program/steps/mail/viewsource.inc b/program/steps/mail/viewsource.inc index c560d7d41..0328d9600 100644 --- a/program/steps/mail/viewsource.inc +++ b/program/steps/mail/viewsource.inc @@ -5,7 +5,7 @@ | program/steps/mail/viewsource.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -22,39 +22,39 @@ ob_end_clean(); // similar code as in program/steps/mail/get.inc -if ($uid = get_input_value('_uid', RCUBE_INPUT_GET)) -{ - $headers = $RCMAIL->storage->get_message_headers($uid); - $charset = $headers->charset ? $headers->charset : $CONFIG['default_charset']; - header("Content-Type: text/plain; charset={$charset}"); - - if (!empty($_GET['_save'])) { - $subject = rcube_mime::decode_header($headers->subject, $headers->charset); - $filename = ($subject ? $subject : $RCMAIL->config->get('product_name', 'email')) . '.eml'; - $browser = $RCMAIL->output->browser; - - if ($browser->ie && $browser->ver < 7) - $filename = rawurlencode(abbreviate_string($filename, 55)); - else if ($browser->ie) - $filename = rawurlencode($filename); - else - $filename = addcslashes($filename, '"'); - - header("Content-Length: {$headers->size}"); - header("Content-Disposition: attachment; filename=\"$filename\""); - } - - $RCMAIL->storage->print_raw_body($uid, empty($_GET['_save'])); +if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)) { + $headers = $RCMAIL->storage->get_message_headers($uid); + $charset = $headers->charset ? $headers->charset : $RCMAIL->config->get('default_charset'); + + header("Content-Type: text/plain; charset={$charset}"); + + if (!empty($_GET['_save'])) { + $subject = rcube_mime::decode_header($headers->subject, $headers->charset); + $filename = ($subject ? $subject : $RCMAIL->config->get('product_name', 'email')) . '.eml'; + $browser = $RCMAIL->output->browser; + + if ($browser->ie && $browser->ver < 7) + $filename = rawurlencode(abbreviate_string($filename, 55)); + else if ($browser->ie) + $filename = rawurlencode($filename); + else + $filename = addcslashes($filename, '"'); + + header("Content-Length: {$headers->size}"); + header("Content-Disposition: attachment; filename=\"$filename\""); + } + + $RCMAIL->storage->print_raw_body($uid, empty($_GET['_save'])); } -else -{ - raise_error(array( - 'code' => 500, - 'type' => 'php', - 'file' => __FILE__, 'line' => __LINE__, - 'message' => 'Message UID '.$uid.' not found'), - true, true); +else { + rcube::raise_error(array( + 'code' => 500, + 'type' => 'php', + 'file' => __FILE__, + 'line' => __LINE__, + 'message' => "Message UID $uid not found" + ), + true, true); } exit; - diff --git a/program/steps/settings/about.inc b/program/steps/settings/about.inc index 0fdefddda..026bfc1a2 100644 --- a/program/steps/settings/about.inc +++ b/program/steps/settings/about.inc @@ -5,8 +5,8 @@ | program/steps/settings/about.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2011, The Roundcube Dev Team | - | Copyright (C) 2011, Kolab Systems AG | + | Copyright (C) 2005-2013, The Roundcube Dev Team | + | Copyright (C) 2011-2013, Kolab Systems AG | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -21,78 +21,83 @@ */ +$OUTPUT->set_pagetitle($RCMAIL->gettext('about')); + +$OUTPUT->add_handler('supportlink', 'rcmail_supportlink'); +$OUTPUT->add_handler('pluginlist', 'rcmail_plugins_list'); + +$OUTPUT->send('about'); + + + function rcmail_supportlink($attrib) { - global $RCMAIL; + global $RCMAIL; + + if ($url = $RCMAIL->config->get('support_url')) { + $label = $attrib['label'] ? $attrib['label'] : 'support'; + $attrib['href'] = $url; - if ($url = $RCMAIL->config->get('support_url')) { - $label = $attrib['label'] ? $attrib['label'] : 'support'; - $attrib['href'] = $url; - return html::a($attrib, rcube_label($label)); - } + return html::a($attrib, $RCMAIL->gettext($label)); + } } function rcmail_plugins_list($attrib) { - global $RCMAIL; - - if (!$attrib['id']) - $attrib['id'] = 'rcmpluginlist'; - - $plugins = array_filter((array) $RCMAIL->config->get('plugins')); - $plugin_info = array(); - - foreach ($plugins as $name) { - if ($info = $RCMAIL->plugins->get_info($name)) - $plugin_info[$name] = $info; - } - - // load info from required plugins, too - foreach ($plugin_info as $name => $info) { - if (is_array($info['required']) && !empty($info['required'])) { - foreach ($info['required'] as $req_name) { - if (!isset($plugin_info[$req_name]) && ($req_info = $RCMAIL->plugins->get_info($req_name))) - $plugin_info[$req_name] = $req_info; - } - } - } + global $RCMAIL; - if (empty($plugin_info)) { - return ''; - } + if (!$attrib['id']) { + $attrib['id'] = 'rcmpluginlist'; + } - ksort($plugin_info, SORT_LOCALE_STRING); + $plugins = array_filter((array) $RCMAIL->config->get('plugins')); + $plugin_info = array(); - $table = new html_table($attrib); + foreach ($plugins as $name) { + if ($info = $RCMAIL->plugins->get_info($name)) { + $plugin_info[$name] = $info; + } + } - // add table header - $table->add_header('name', rcube_label('plugin')); - $table->add_header('version', rcube_label('version')); - $table->add_header('license', rcube_label('license')); - $table->add_header('source', rcube_label('source')); + // load info from required plugins, too + foreach ($plugin_info as $name => $info) { + if (is_array($info['required']) && !empty($info['required'])) { + foreach ($info['required'] as $req_name) { + if (!isset($plugin_info[$req_name]) && ($req_info = $RCMAIL->plugins->get_info($req_name))) { + $plugin_info[$req_name] = $req_info; + } + } + } + } - foreach ($plugin_info as $name => $data) { - $uri = $data['src_uri'] ? $data['src_uri'] : $data['uri']; - if ($uri && stripos($uri, 'http') !== 0) { - $uri = 'http://' . $uri; + if (empty($plugin_info)) { + return ''; } - $table->add_row(); - $table->add('name', Q($data['name'] ? $data['name'] : $name)); - $table->add('version', Q($data['version'])); - $table->add('license', $data['license_uri'] ? html::a(array('target' => '_blank', href=> Q($data['license_uri'])), - Q($data['license'])) : $data['license']); - $table->add('source', $uri ? html::a(array('target' => '_blank', href=> Q($uri)), - Q(rcube_label('download'))) : ''); - } + ksort($plugin_info, SORT_LOCALE_STRING); + + $table = new html_table($attrib); + + // add table header + $table->add_header('name', $RCMAIL->gettext('plugin')); + $table->add_header('version', $RCMAIL->gettext('version')); + $table->add_header('license', $RCMAIL->gettext('license')); + $table->add_header('source', $RCMAIL->gettext('source')); + + foreach ($plugin_info as $name => $data) { + $uri = $data['src_uri'] ? $data['src_uri'] : $data['uri']; + if ($uri && stripos($uri, 'http') !== 0) { + $uri = 'http://' . $uri; + } + + $table->add_row(); + $table->add('name', rcube::Q($data['name'] ? $data['name'] : $name)); + $table->add('version', rcube::Q($data['version'])); + $table->add('license', $data['license_uri'] ? html::a(array('target' => '_blank', href=> rcube::Q($data['license_uri'])), + rcube::Q($data['license'])) : $data['license']); + $table->add('source', $uri ? html::a(array('target' => '_blank', href=> rcube::Q($uri)), + rcube::Q($RCMAIL->gettext('download'))) : ''); + } - return $table->show(); + return $table->show(); } - - -$OUTPUT->set_pagetitle(rcube_label('about')); - -$OUTPUT->add_handler('supportlink', 'rcmail_supportlink'); -$OUTPUT->add_handler('pluginlist', 'rcmail_plugins_list'); - -$OUTPUT->send('about'); diff --git a/program/steps/settings/delete_identity.inc b/program/steps/settings/delete_identity.inc index d5146db66..f77620438 100644 --- a/program/steps/settings/delete_identity.inc +++ b/program/steps/settings/delete_identity.inc @@ -5,7 +5,7 @@ | program/steps/settings/delete_identity.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,33 +19,37 @@ +-----------------------------------------------------------------------+ */ -$iid = get_input_value('_iid', RCUBE_INPUT_GPC); +$iid = rcube_utils::get_input_value('_iid', rcube_utils::INPUT_GPC); // check request token -if (!$OUTPUT->ajax_call && !$RCMAIL->check_request(RCUBE_INPUT_GPC)) { - $OUTPUT->show_message('invalidrequest', 'error'); - rcmail_overwrite_action('identities'); - return; +if (!$OUTPUT->ajax_call && !$RCMAIL->check_request(rcube_utils::INPUT_GPC)) { + $OUTPUT->show_message('invalidrequest', 'error'); + $RCMAIL->overwrite_action('identities'); + return; } -if ($iid && preg_match('/^[0-9]+(,[0-9]+)*$/', $iid)) -{ - $plugin = $RCMAIL->plugins->exec_hook('identity_delete', array('id' => $iid)); - - $deleted = !$plugin['abort'] ? $RCMAIL->user->delete_identity($iid) : $plugin['result']; +if ($iid && preg_match('/^[0-9]+(,[0-9]+)*$/', $iid)) { + $plugin = $RCMAIL->plugins->exec_hook('identity_delete', array('id' => $iid)); - if ($deleted > 0 && $deleted !== false) - $OUTPUT->show_message('deletedsuccessfully', 'confirmation', null, false); - else - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : ($deleted < 0 ? 'nodeletelastidentity' : 'errorsaving'), 'error', null, false); + $deleted = !$plugin['abort'] ? $RCMAIL->user->delete_identity($iid) : $plugin['result']; - // send response - if ($OUTPUT->ajax_call) - $OUTPUT->send(); + if ($deleted > 0 && $deleted !== false) { + $OUTPUT->show_message('deletedsuccessfully', 'confirmation', null, false); + } + else { + $msg = $plugin['message'] ? $plugin['message'] : ($deleted < 0 ? 'nodeletelastidentity' : 'errorsaving'); + $OUTPUT->show_message($msg, 'error', null, false); + } + + // send response + if ($OUTPUT->ajax_call) { + $OUTPUT->send(); + } } -if ($OUTPUT->ajax_call) - exit; +if ($OUTPUT->ajax_call) { + exit; +} // go to identities page -rcmail_overwrite_action('identities'); +$RCMAIL->overwrite_action('identities'); diff --git a/program/steps/settings/edit_folder.inc b/program/steps/settings/edit_folder.inc index f19e2177b..fc6b2cd16 100644 --- a/program/steps/settings/edit_folder.inc +++ b/program/steps/settings/edit_folder.inc @@ -5,7 +5,7 @@ | program/steps/settings/edit_folder.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,7 +19,17 @@ +-----------------------------------------------------------------------+ */ -// WARNING: folder names in UI are encoded with RCMAIL_CHARSET +// register UI objects +$OUTPUT->add_handlers(array( + 'folderdetails' => 'rcmail_folder_form', +)); + +$OUTPUT->add_label('nonamewarning'); + +$OUTPUT->send('folderedit'); + + +// WARNING: folder names in UI are encoded with RCUBE_CHARSET function rcmail_folder_form($attrib) { @@ -28,12 +38,12 @@ function rcmail_folder_form($attrib) $storage = $RCMAIL->get_storage(); // edited folder name (empty in create-folder mode) - $mbox = trim(get_input_value('_mbox', RCUBE_INPUT_GPC, true)); - $mbox_imap = rcube_charset_convert($mbox, RCMAIL_CHARSET, 'UTF7-IMAP'); + $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_GPC, true); + $mbox_imap = rcube_charset::convert($mbox, RCUBE_CHARSET, 'UTF7-IMAP'); // predefined path for new folder - $parent = trim(get_input_value('_path', RCUBE_INPUT_GPC, true)); - $parent_imap = rcube_charset_convert($parent, RCMAIL_CHARSET, 'UTF7-IMAP'); + $parent = rcube_utils::get_input_value('_path', rcube_utils::INPUT_GPC, true); + $parent_imap = rcube_charset::convert($parent, RCUBE_CHARSET, 'UTF7-IMAP'); $threading_supported = $storage->get_capability('THREAD'); $delimiter = $storage->get_hierarchy_delimiter(); @@ -46,7 +56,7 @@ function rcmail_folder_form($attrib) $path = explode($delimiter, $mbox_imap); $folder = array_pop($path); $path = implode($delimiter, $path); - $folder = rcube_charset_convert($folder, 'UTF7-IMAP'); + $folder = rcube_charset::convert($folder, 'UTF7-IMAP'); $hidden_fields = array('name' => '_mbox', 'value' => $mbox); } @@ -73,33 +83,33 @@ function rcmail_folder_form($attrib) // General tab $form['props'] = array( - 'name' => rcube_label('properties'), + 'name' => $RCMAIL->gettext('properties'), ); // Location (name) if ($options['protected']) { - $foldername = str_replace($delimiter, ' » ', Q(rcmail_localize_folderpath($mbox_imap))); + $foldername = str_replace($delimiter, ' » ', rcube::Q($RCMAIL->localize_folderpath($mbox_imap))); } else if ($options['norename']) { - $foldername = Q($folder); + $foldername = rcube::Q($folder); } else { if (isset($_POST['_name'])) - $folder = trim(get_input_value('_name', RCUBE_INPUT_POST, true)); + $folder = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true)); $foldername = new html_inputfield(array('name' => '_name', 'id' => '_name', 'size' => 30)); $foldername = $foldername->show($folder); if ($options['special']) { - $foldername .= ' (' . Q(rcmail_localize_foldername($mbox_imap)) .')'; + $foldername .= ' (' . rcube::Q($RCMAIL->localize_foldername($mbox_imap)) .')'; } } $form['props']['fieldsets']['location'] = array( - 'name' => rcube_label('location'), + 'name' => $RCMAIL->gettext('location'), 'content' => array( 'name' => array( - 'label' => rcube_label('foldername'), + 'label' => $RCMAIL->gettext('foldername'), 'value' => $foldername, ), ), @@ -121,7 +131,7 @@ function rcmail_folder_form($attrib) $exceptions[] = substr($prefix, 0, -1); } - $select = rcmail_mailbox_select(array( + $select = $RCMAIL->folder_selector(array( 'name' => '_parent', 'noselection' => '---', 'realnames' => false, @@ -132,21 +142,21 @@ function rcmail_folder_form($attrib) )); $form['props']['fieldsets']['location']['content']['path'] = array( - 'label' => rcube_label('parentfolder'), + 'label' => $RCMAIL->gettext('parentfolder'), 'value' => $select->show($selected), ); } // Settings $form['props']['fieldsets']['settings'] = array( - 'name' => rcube_label('settings'), + 'name' => $RCMAIL->gettext('settings'), ); // Settings: threading if ($threading_supported && ($mbox_imap == 'INBOX' || (!$options['noselect'] && !$options['is_root']))) { $select = new html_select(array('name' => '_viewmode', 'id' => '_listmode')); - $select->add(rcube_label('list'), 0); - $select->add(rcube_label('threads'), 1); + $select->add($RCMAIL->gettext('list'), 0); + $select->add($RCMAIL->gettext('threads'), 1); if (isset($_POST['_viewmode'])) { $value = (int) $_POST['_viewmode']; @@ -157,38 +167,38 @@ function rcmail_folder_form($attrib) } $form['props']['fieldsets']['settings']['content']['viewmode'] = array( - 'label' => rcube_label('listmode'), + 'label' => $RCMAIL->gettext('listmode'), 'value' => $select->show($value), ); } /* // Settings: sorting column $select = new html_select(array('name' => '_sortcol', 'id' => '_sortcol')); - $select->add(rcube_label('nonesort'), ''); - $select->add(rcube_label('arrival'), 'arrival'); - $select->add(rcube_label('sentdate'), 'date'); - $select->add(rcube_label('subject'), 'subject'); - $select->add(rcube_label('fromto'), 'from'); - $select->add(rcube_label('replyto'), 'replyto'); - $select->add(rcube_label('cc'), 'cc'); - $select->add(rcube_label('size'), 'size'); + $select->add($RCMAIL->gettext('nonesort'), ''); + $select->add($RCMAIL->gettext('arrival'), 'arrival'); + $select->add($RCMAIL->gettext('sentdate'), 'date'); + $select->add($RCMAIL->gettext('subject'), 'subject'); + $select->add($RCMAIL->gettext('fromto'), 'from'); + $select->add($RCMAIL->gettext('replyto'), 'replyto'); + $select->add($RCMAIL->gettext('cc'), 'cc'); + $select->add($RCMAIL->gettext('size'), 'size'); $value = isset($_POST['_sortcol']) ? $_POST['_sortcol'] : ''; $form['props']['fieldsets']['settings']['content']['sortcol'] = array( - 'label' => rcube_label('listsorting'), + 'label' => $RCMAIL->gettext('listsorting'), 'value' => $select->show($value), ); // Settings: sorting order $select = new html_select(array('name' => '_sortord', 'id' => '_sortord')); - $select->add(rcube_label('asc'), 'ASC'); - $select->add(rcube_label('desc'), 'DESC'); + $select->add($RCMAIL->gettext('asc'), 'ASC'); + $select->add($RCMAIL->gettext('desc'), 'DESC'); $value = isset($_POST['_sortord']) ? $_POST['_sortord'] : ''; $form['props']['fieldsets']['settings']['content']['sortord'] = array( - 'label' => rcube_label('listorder'), + 'label' => $RCMAIL->gettext('listorder'), 'value' => $select->show(), ); */ @@ -196,7 +206,7 @@ function rcmail_folder_form($attrib) if (strlen($mbox)) { // Number of messages $form['props']['fieldsets']['info'] = array( - 'name' => rcube_label('info'), + 'name' => $RCMAIL->gettext('info'), 'content' => array() ); @@ -207,9 +217,9 @@ function rcmail_folder_form($attrib) if ($msgcount) { // create link with folder-size command $onclick = sprintf("return %s.command('folder-size', '%s', this)", - JS_OBJECT_NAME, JQ($mbox_imap)); + rcmail_output::JS_OBJECT_NAME, rcube::JQ($mbox_imap)); $size = html::a(array('href' => '#', 'onclick' => $onclick, - 'id' => 'folder-size'), rcube_label('getfoldersize')); + 'id' => 'folder-size'), $RCMAIL->gettext('getfoldersize')); } else { // no messages -> zero size @@ -217,11 +227,11 @@ function rcmail_folder_form($attrib) } $form['props']['fieldsets']['info']['content']['count'] = array( - 'label' => rcube_label('messagecount'), + 'label' => $RCMAIL->gettext('messagecount'), 'value' => (int) $msgcount ); $form['props']['fieldsets']['info']['content']['size'] = array( - 'label' => rcube_label('size'), + 'label' => $RCMAIL->gettext('size'), 'value' => $size, ); } @@ -229,8 +239,8 @@ function rcmail_folder_form($attrib) // show folder type only if we have non-private namespaces if (!empty($namespace['shared']) || !empty($namespace['others'])) { $form['props']['fieldsets']['info']['content']['foldertype'] = array( - 'label' => rcube_label('foldertype'), - 'value' => rcube_label($options['namespace'] . 'folder')); + 'label' => $RCMAIL->gettext('foldertype'), + 'value' => $RCMAIL->gettext($options['namespace'] . 'folder')); } } @@ -256,7 +266,8 @@ function rcmail_folder_form($attrib) foreach ($tab['fieldsets'] as $fieldset) { $subcontent = rcmail_get_form_part($fieldset, $attrib); if ($subcontent) { - $content .= html::tag('fieldset', null, html::tag('legend', null, Q($fieldset['name'])) . $subcontent) ."\n"; + $subcontent = html::tag('legend', null, rcube::Q($fieldset['name'])) . $subcontent; + $content .= html::tag('fieldset', null, $subcontent) ."\n"; } } } @@ -265,7 +276,7 @@ function rcmail_folder_form($attrib) } if ($content && sizeof($form) > 1) { - $out .= html::tag('fieldset', null, html::tag('legend', null, Q($tab['name'])) . $content) ."\n"; + $out .= html::tag('fieldset', null, html::tag('legend', null, rcube::Q($tab['name'])) . $content) ."\n"; } else { $out .= $content ."\n"; @@ -287,9 +298,9 @@ function rcmail_get_form_part($form, $attrib = array()) $table = new html_table(array('cols' => 2)); foreach ($form['content'] as $col => $colprop) { $colprop['id'] = '_'.$col; - $label = !empty($colprop['label']) ? $colprop['label'] : rcube_label($col); + $label = !empty($colprop['label']) ? $colprop['label'] : $RCMAIL->gettext($col); - $table->add('title', html::label($colprop['id'], Q($label))); + $table->add('title', html::label($colprop['id'], rcube::Q($label))); $table->add(null, $colprop['value']); } $content = $table->show($attrib); @@ -300,15 +311,3 @@ function rcmail_get_form_part($form, $attrib = array()) return $content; } - - -//$OUTPUT->set_pagetitle(rcube_label('folders')); - -// register UI objects -$OUTPUT->add_handlers(array( - 'folderdetails' => 'rcmail_folder_form', -)); - -$OUTPUT->add_label('nonamewarning'); - -$OUTPUT->send('folderedit'); diff --git a/program/steps/settings/edit_identity.inc b/program/steps/settings/edit_identity.inc index edd4ba60d..f208c8a05 100644 --- a/program/steps/settings/edit_identity.inc +++ b/program/steps/settings/edit_identity.inc @@ -5,7 +5,7 @@ | program/steps/settings/edit_identity.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2011, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -23,152 +23,158 @@ define('IDENTITIES_LEVEL', intval($RCMAIL->config->get('identities_level', 0))); // edit-identity if (($_GET['_iid'] || $_POST['_iid']) && $RCMAIL->action=='edit-identity') { - $IDENTITY_RECORD = $RCMAIL->user->get_identity(get_input_value('_iid', RCUBE_INPUT_GPC)); - - if (is_array($IDENTITY_RECORD)) - $OUTPUT->set_env('iid', $IDENTITY_RECORD['identity_id']); - else { - $OUTPUT->show_message('dberror', 'error'); - // go to identities page - rcmail_overwrite_action('identities'); - return; - } + $id = rcube_utils::get_input_value('_iid', rcube_utils::INPUT_GPC); + $IDENTITY_RECORD = $RCMAIL->user->get_identity($id); + + if (is_array($IDENTITY_RECORD)) { + $OUTPUT->set_env('iid', $IDENTITY_RECORD['identity_id']); + } + else { + $OUTPUT->show_message('dberror', 'error'); + // go to identities page + $RCMAIL->overwrite_action('identities'); + return; + } } // add-identity else { - if (IDENTITIES_LEVEL > 1) { - $OUTPUT->show_message('opnotpermitted', 'error'); - // go to identities page - rcmail_overwrite_action('identities'); - return; - } - else if (IDENTITIES_LEVEL == 1) { - $IDENTITY_RECORD['email'] = $RCMAIL->get_user_email(); - } + if (IDENTITIES_LEVEL > 1) { + $OUTPUT->show_message('opnotpermitted', 'error'); + // go to identities page + $RCMAIL->overwrite_action('identities'); + return; + } + else if (IDENTITIES_LEVEL == 1) { + $IDENTITY_RECORD['email'] = $RCMAIL->get_user_email(); + } +} + +$OUTPUT->include_script('list.js'); +$OUTPUT->add_handler('identityform', 'rcube_identity_form'); +$OUTPUT->set_env('identities_level', IDENTITIES_LEVEL); +$OUTPUT->add_label('deleteidentityconfirm'); + +$OUTPUT->set_pagetitle($RCMAIL->gettext(($RCMAIL->action == 'add-identity' ? 'newidentity' : 'edititem'))); + +if ($RCMAIL->action == 'add-identity' && $OUTPUT->template_exists('identityadd')) { + $OUTPUT->send('identityadd'); } +$OUTPUT->send('identityedit'); + function rcube_identity_form($attrib) { - global $IDENTITY_RECORD, $RCMAIL, $OUTPUT; - - // Add HTML editor script(s) - rcube_html_editor('identity'); - - // add some labels to client - $OUTPUT->add_label('noemailwarning', 'nonamewarning', 'converting', 'editorwarning'); - - $i_size = !empty($attrib['size']) ? $attrib['size'] : 40; - $t_rows = !empty($attrib['textarearows']) ? $attrib['textarearows'] : 6; - $t_cols = !empty($attrib['textareacols']) ? $attrib['textareacols'] : 40; - - // list of available cols - $form = array( - 'addressing' => array( - 'name' => rcube_label('settings'), - 'content' => array( - 'name' => array('type' => 'text', 'size' => $i_size), - 'email' => array('type' => 'text', 'size' => $i_size), - 'organization' => array('type' => 'text', 'size' => $i_size), - 'reply-to' => array('type' => 'text', 'size' => $i_size), - 'bcc' => array('type' => 'text', 'size' => $i_size), - 'standard' => array('type' => 'checkbox', 'label' => rcube_label('setdefault')), - )), - 'signature' => array( - 'name' => rcube_label('signature'), - 'content' => array( - 'signature' => array('type' => 'textarea', 'size' => $t_cols, 'rows' => $t_rows, - 'spellcheck' => true), - 'html_signature' => array('type' => 'checkbox', 'label' => rcube_label('htmlsignature'), - 'onclick' => 'return rcmail_toggle_editor(this, \'rcmfd_signature\');'), - )) - ); - - // Enable TinyMCE editor - if ($IDENTITY_RECORD['html_signature']) { - $form['signature']['content']['signature']['class'] = 'mce_editor'; - $form['signature']['content']['signature']['is_escaped'] = true; - - // Correctly handle HTML entities in HTML editor (#1488483) - $IDENTITY_RECORD['signature'] = htmlspecialchars($IDENTITY_RECORD['signature'], ENT_NOQUOTES, RCMAIL_CHARSET); - } - - // disable some field according to access level - if (IDENTITIES_LEVEL == 1 || IDENTITIES_LEVEL == 3) { - $form['addressing']['content']['email']['disabled'] = true; - $form['addressing']['content']['email']['class'] = 'disabled'; - } - - if (IDENTITIES_LEVEL == 4) { - foreach($form['addressing']['content'] as $formfield => $value){ - $form['addressing']['content'][$formfield]['disabled'] = true; - $form['addressing']['content'][$formfield]['class'] = 'disabled'; + global $IDENTITY_RECORD, $RCMAIL, $OUTPUT; + + // Add HTML editor script(s) + $RCMAIL->html_editor('identity'); + + // add some labels to client + $OUTPUT->add_label('noemailwarning', 'nonamewarning', 'converting', 'editorwarning'); + + $i_size = !empty($attrib['size']) ? $attrib['size'] : 40; + $t_rows = !empty($attrib['textarearows']) ? $attrib['textarearows'] : 6; + $t_cols = !empty($attrib['textareacols']) ? $attrib['textareacols'] : 40; + + // list of available cols + $form = array( + 'addressing' => array( + 'name' => $RCMAIL->gettext('settings'), + 'content' => array( + 'name' => array('type' => 'text', 'size' => $i_size), + 'email' => array('type' => 'text', 'size' => $i_size), + 'organization' => array('type' => 'text', 'size' => $i_size), + 'reply-to' => array('type' => 'text', 'size' => $i_size), + 'bcc' => array('type' => 'text', 'size' => $i_size), + 'standard' => array('type' => 'checkbox', 'label' => $RCMAIL->gettext('setdefault')), + )), + 'signature' => array( + 'name' => $RCMAIL->gettext('signature'), + 'content' => array( + 'signature' => array('type' => 'textarea', 'size' => $t_cols, 'rows' => $t_rows, + 'spellcheck' => true), + 'html_signature' => array('type' => 'checkbox', + 'label' => $RCMAIL->gettext('htmlsignature'), + 'onclick' => 'return rcmail_toggle_editor(this, \'rcmfd_signature\');'), + )) + ); + + // Enable TinyMCE editor + if ($IDENTITY_RECORD['html_signature']) { + $form['signature']['content']['signature']['class'] = 'mce_editor'; + $form['signature']['content']['signature']['is_escaped'] = true; + + // Correctly handle HTML entities in HTML editor (#1488483) + $IDENTITY_RECORD['signature'] = htmlspecialchars($IDENTITY_RECORD['signature'], ENT_NOQUOTES, RCUBE_CHARSET); } - } - $IDENTITY_RECORD['email'] = rcube_idn_to_utf8($IDENTITY_RECORD['email']); + // disable some field according to access level + if (IDENTITIES_LEVEL == 1 || IDENTITIES_LEVEL == 3) { + $form['addressing']['content']['email']['disabled'] = true; + $form['addressing']['content']['email']['class'] = 'disabled'; + } - // Allow plugins to modify identity form content - $plugin = $RCMAIL->plugins->exec_hook('identity_form', array( - 'form' => $form, 'record' => $IDENTITY_RECORD)); + if (IDENTITIES_LEVEL == 4) { + foreach($form['addressing']['content'] as $formfield => $value){ + $form['addressing']['content'][$formfield]['disabled'] = true; + $form['addressing']['content'][$formfield]['class'] = 'disabled'; + } + } - $form = $plugin['form']; - $IDENTITY_RECORD = $plugin['record']; + $IDENTITY_RECORD['email'] = rcube_utils::idn_to_utf8($IDENTITY_RECORD['email']); - // Set form tags and hidden fields - list($form_start, $form_end) = get_form_tags($attrib, 'save-identity', - intval($IDENTITY_RECORD['identity_id']), - array('name' => '_iid', 'value' => $IDENTITY_RECORD['identity_id'])); + // Allow plugins to modify identity form content + $plugin = $RCMAIL->plugins->exec_hook('identity_form', array( + 'form' => $form, 'record' => $IDENTITY_RECORD)); - unset($plugin); - unset($attrib['form'], $attrib['id']); + $form = $plugin['form']; + $IDENTITY_RECORD = $plugin['record']; - // return the complete edit form as table - $out = "$form_start\n"; + // Set form tags and hidden fields + list($form_start, $form_end) = get_form_tags($attrib, 'save-identity', + intval($IDENTITY_RECORD['identity_id']), + array('name' => '_iid', 'value' => $IDENTITY_RECORD['identity_id'])); - foreach ($form as $fieldset) { - if (empty($fieldset['content'])) - continue; + unset($plugin); + unset($attrib['form'], $attrib['id']); - $content = ''; - if (is_array($fieldset['content'])) { - $table = new html_table(array('cols' => 2)); - foreach ($fieldset['content'] as $col => $colprop) { - $colprop['id'] = 'rcmfd_'.$col; + // return the complete edit form as table + $out = "$form_start\n"; - $label = !empty($colprop['label']) ? $colprop['label'] : - rcube_label(str_replace('-', '', $col)); + foreach ($form as $fieldset) { + if (empty($fieldset['content'])) { + continue; + } - $value = !empty($colprop['value']) ? $colprop['value'] : - rcmail_get_edit_field($col, $IDENTITY_RECORD[$col], $colprop, $colprop['type']); + $content = ''; + if (is_array($fieldset['content'])) { + $table = new html_table(array('cols' => 2)); - $table->add('title', html::label($colprop['id'], Q($label))); - $table->add(null, $value); - } - $content = $table->show($attrib); - } - else { - $content = $fieldset['content']; - } + foreach ($fieldset['content'] as $col => $colprop) { + $colprop['id'] = 'rcmfd_'.$col; - $out .= html::tag('fieldset', null, html::tag('legend', null, Q($fieldset['name'])) . $content) ."\n"; - } + $label = !empty($colprop['label']) ? $colprop['label'] : + $RCMAIL->gettext(str_replace('-', '', $col)); - $out .= $form_end; + $value = !empty($colprop['value']) ? $colprop['value'] : + rcube_output::get_edit_field($col, $IDENTITY_RECORD[$col], $colprop, $colprop['type']); - return $out; -} + $table->add('title', html::label($colprop['id'], rcube::Q($label))); + $table->add(null, $value); + } -$OUTPUT->include_script('list.js'); -$OUTPUT->add_handler('identityform', 'rcube_identity_form'); -$OUTPUT->set_env('identities_level', IDENTITIES_LEVEL); -$OUTPUT->add_label('deleteidentityconfirm'); - -$OUTPUT->set_pagetitle(rcube_label(($RCMAIL->action=='add-identity' ? 'newidentity' : 'edititem'))); - -if ($RCMAIL->action=='add-identity' && $OUTPUT->template_exists('identityadd')) - $OUTPUT->send('identityadd'); + $content = $table->show($attrib); + } + else { + $content = $fieldset['content']; + } -$OUTPUT->send('identityedit'); + $content = html::tag('legend', null, rcube::Q($fieldset['name'])) . $content; + $out .= html::tag('fieldset', null, $content) . "\n"; + } + $out .= $form_end; + return $out; +} diff --git a/program/steps/settings/edit_prefs.inc b/program/steps/settings/edit_prefs.inc index adf6b1623..05f4db6a6 100644 --- a/program/steps/settings/edit_prefs.inc +++ b/program/steps/settings/edit_prefs.inc @@ -5,7 +5,7 @@ | program/steps/settings/edit_prefs.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2007, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,65 +19,65 @@ +-----------------------------------------------------------------------+ */ -if (!$OUTPUT->ajax_call) - $OUTPUT->set_pagetitle(rcube_label('preferences')); +if (!$OUTPUT->ajax_call) { + $OUTPUT->set_pagetitle($RCMAIL->gettext('preferences')); +} -$CURR_SECTION = get_input_value('_section', RCUBE_INPUT_GPC); +$CURR_SECTION = rcube_utils::get_input_value('_section', rcube_utils::INPUT_GPC); list($SECTIONS,) = rcmail_user_prefs($CURR_SECTION); +// register UI objects +$OUTPUT->add_handlers(array( + 'userprefs' => 'rcmail_user_prefs_form', + 'sectionname' => 'rcmail_prefs_section_name', +)); + +$OUTPUT->send('settingsedit'); + + + function rcmail_user_prefs_form($attrib) { - global $RCMAIL, $CURR_SECTION, $SECTIONS; + global $RCMAIL, $CURR_SECTION, $SECTIONS; - // add some labels to client - $RCMAIL->output->add_label('nopagesizewarning'); + // add some labels to client + $RCMAIL->output->add_label('nopagesizewarning'); - unset($attrib['form']); + unset($attrib['form']); - list($form_start, $form_end) = get_form_tags($attrib, 'save-prefs', null, - array('name' => '_section', 'value' => $CURR_SECTION)); + list($form_start, $form_end) = get_form_tags($attrib, 'save-prefs', null, + array('name' => '_section', 'value' => $CURR_SECTION)); - $out = $form_start; + $out = $form_start; - foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $class => $block) { - if (!empty($block['options'])) { - $table = new html_table(array('cols' => 2)); + foreach ($SECTIONS[$CURR_SECTION]['blocks'] as $class => $block) { + if (!empty($block['options'])) { + $table = new html_table(array('cols' => 2)); - foreach ($block['options'] as $option) { - if (isset($option['title'])) { - $table->add('title', $option['title']); - $table->add(null, $option['content']); + foreach ($block['options'] as $option) { + if (isset($option['title'])) { + $table->add('title', $option['title']); + $table->add(null, $option['content']); + } + else { + $table->add(array('colspan' => 2), $option['content']); + } + } + + $out .= html::tag('fieldset', $class, html::tag('legend', null, $block['name']) . $table->show($attrib)); } - else { - $table->add(array('colspan' => 2), $option['content']); + else if (!empty($block['content'])) { + $out .= html::tag('fieldset', null, html::tag('legend', null, $block['name']) . $block['content']); } - } - - $out .= html::tag('fieldset', $class, html::tag('legend', null, $block['name']) . $table->show($attrib)); } - else if (!empty($block['content'])) { - $out .= html::tag('fieldset', null, html::tag('legend', null, $block['name']) . $block['content']); - } - } - return $out . $form_end; + return $out . $form_end; } function rcmail_prefs_section_name() { - global $SECTIONS, $CURR_SECTION; - - return $SECTIONS[$CURR_SECTION]['section']; -} - - -// register UI objects -$OUTPUT->add_handlers(array( - 'userprefs' => 'rcmail_user_prefs_form', - 'sectionname' => 'rcmail_prefs_section_name', -)); - -$OUTPUT->send('settingsedit'); - + global $SECTIONS, $CURR_SECTION; + return $SECTIONS[$CURR_SECTION]['section']; +} diff --git a/program/steps/settings/edit_response.inc b/program/steps/settings/edit_response.inc new file mode 100644 index 000000000..760f28290 --- /dev/null +++ b/program/steps/settings/edit_response.inc @@ -0,0 +1,108 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | program/steps/settings/edit_response.inc | + | | + | This file is part of the Roundcube Webmail client | + | Copyright (C) 2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + | PURPOSE: | + | Show edit form for a canned response record or to add a new one | + | | + +-----------------------------------------------------------------------+ + | Author: Thomas Bruederli <roundcube@gmail.com> | + +-----------------------------------------------------------------------+ +*/ + +$responses = $RCMAIL->get_compose_responses(); + +// edit-response +if (($key = rcube_utils::get_input_value('_key', rcube_utils::INPUT_GPC))) { + foreach ($responses as $i => $response) { + if ($response['key'] == $key) { + $RESPONSE_RECORD = $response; + $RESPONSE_RECORD['index'] = $i; + break; + } + } +} + +// save response +if ($RCMAIL->action == 'save-response' && isset($_POST['_name']) && !$RESPONSE_RECORD['static']) { + $name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST)); + $text = trim(rcube_utils::get_input_value('_text', rcube_utils::INPUT_POST)); + + if (!empty($name) && !empty($text)) { + $dupes = 0; + foreach ($responses as $i => $resp) { + if ($RESPONSE_RECORD && $RESPONSE_RECORD['index'] === $i) + continue; + if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0) + $dupes++; + } + if ($dupes) { // require a unique name + $name .= ' (' . ++$dupes . ')'; + } + + $response = array('name' => $name, 'text' => $text, 'format' => 'text', 'key' => substr(md5($name), 0, 16)); + if ($RESPONSE_RECORD && $responses[$RESPONSE_RECORD['index']]) { + $responses[$RESPONSE_RECORD['index']] = $response; + } + else { + $responses[] = $response; + } + + $responses = array_filter($responses, function($item){ return empty($item['static']); }); + if ($RCMAIL->user->save_prefs(array('compose_responses' => array_values($responses)))) { + $RCMAIL->output->show_message('successfullysaved', 'confirmation'); + $RCMAIL->output->command('parent.update_response_row', $response, $key); + $RCMAIL->overwrite_action('edit-response'); + $RESPONSE_RECORD = $response; + } + } + else { + $RCMAIL->output->show_message('formincomplete', 'error'); + } +} + +$OUTPUT->set_env('readonly', !empty($RESPONSE_RECORD['static'])); +$OUTPUT->add_handler('responseform', 'rcube_response_form'); +$OUTPUT->set_pagetitle($RCMAIL->gettext($RCMAIL->action == 'add-response' ? 'savenewresponse' : 'editresponse')); + +$OUTPUT->send('responseedit'); + + +function rcube_response_form($attrib) +{ + global $RCMAIL, $OUTPUT, $RESPONSE_RECORD; + + // Set form tags and hidden fields + $disabled = !empty($RESPONSE_RECORD['static']); + $key = $RESPONSE_RECORD['key']; + list($form_start, $form_end) = get_form_tags($attrib, 'save-response', $key, array('name' => '_key', 'value' => $key)); + unset($attrib['form'], $attrib['id']); + + // return the complete edit form as table + $out = "$form_start\n"; + + $table = new html_table(array('cols' => 2)); + $label = $RCMAIL->gettext('responsename'); + + $table->add('title', html::label('ffname', rcube::Q($RCMAIL->gettext('responsename')))); + $table->add(null, rcube_output::get_edit_field('name', $RESPONSE_RECORD['name'], + array('id' => 'ffname', 'size' => $attrib['size'], 'disabled' => $disabled), 'text')); + + $table->add('title', html::label('fftext', rcube::Q($RCMAIL->gettext('responsetext')))); + $table->add(null, rcube_output::get_edit_field('text', $RESPONSE_RECORD['text'], + array('id' => 'fftext', 'size' => $attrib['textareacols'], 'rows' => $attrib['textarearows'], 'disabled' => $disabled), 'textarea')); + + $out .= $table->show($attrib); + $out .= $form_end; + + return $out; +} diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc index 64af18d62..b09ea03ce 100644 --- a/program/steps/settings/folders.inc +++ b/program/steps/settings/folders.inc @@ -5,7 +5,7 @@ | program/steps/settings/folders.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -20,15 +20,15 @@ +-----------------------------------------------------------------------+ */ -// WARNING: folder names in UI are encoded with RCMAIL_CHARSET +// WARNING: folder names in UI are encoded with RCUBE_CHARSET // init IMAP connection $STORAGE = $RCMAIL->get_storage(); // subscribe mailbox -if ($RCMAIL->action == 'subscribe') -{ - $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true, 'UTF7-IMAP'); +if ($RCMAIL->action == 'subscribe') { + $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true, 'UTF7-IMAP'); + if (strlen($mbox)) { $result = $STORAGE->subscribe(array($mbox)); @@ -53,28 +53,24 @@ if ($RCMAIL->action == 'subscribe') $OUTPUT->show_message('foldersubscribed', 'confirmation'); } else - rcmail_display_server_error('errorsaving'); + $RCMAIL->display_server_error('errorsaving'); } } - // unsubscribe mailbox -else if ($RCMAIL->action == 'unsubscribe') -{ - $mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true, 'UTF7-IMAP'); +else if ($RCMAIL->action == 'unsubscribe') { + $mbox = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true, 'UTF7-IMAP'); if (strlen($mbox)) { $result = $STORAGE->unsubscribe(array($mbox)); if ($result) $OUTPUT->show_message('folderunsubscribed', 'confirmation'); else - rcmail_display_server_error('errorsaving'); + $RCMAIL->display_server_error('errorsaving'); } } - // delete an existing mailbox -else if ($RCMAIL->action == 'delete-folder') -{ - $mbox_utf8 = get_input_value('_mbox', RCUBE_INPUT_POST, true); - $mbox = rcube_charset_convert($mbox_utf8, RCMAIL_CHARSET, 'UTF7-IMAP'); +else if ($RCMAIL->action == 'delete-folder') { + $mbox_utf8 = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true); + $mbox = rcube_charset::convert($mbox_utf8, RCUBE_CHARSET, 'UTF7-IMAP'); if (strlen($mbox)) { $plugin = $RCMAIL->plugins->exec_hook('folder_delete', array('name' => $mbox)); @@ -98,22 +94,20 @@ else if ($RCMAIL->action == 'delete-folder') $OUTPUT->show_message('folderdeleted', 'confirmation'); // Clear content frame $OUTPUT->command('subscription_select'); - $OUTPUT->command('set_quota', rcmail_quota_content()); + $OUTPUT->command('set_quota', $RCMAIL->quota_content()); } else if (!$deleted) { - rcmail_display_server_error('errorsaving'); + $RCMAIL->display_server_error('errorsaving'); } } - // rename an existing mailbox -else if ($RCMAIL->action == 'rename-folder') -{ - $name_utf8 = trim(get_input_value('_folder_newname', RCUBE_INPUT_POST, true)); - $oldname_utf8 = trim(get_input_value('_folder_oldname', RCUBE_INPUT_POST, true)); +else if ($RCMAIL->action == 'rename-folder') { + $name_utf8 = trim(rcube_utils::get_input_value('_folder_newname', rcube_utils::INPUT_POST, true)); + $oldname_utf8 = rcube_utils::get_input_value('_folder_oldname', rcube_utils::INPUT_POST, true); if (strlen($name_utf8) && strlen($oldname_utf8)) { - $name = rcube_charset_convert($name_utf8, RCMAIL_CHARSET, 'UTF7-IMAP'); - $oldname = rcube_charset_convert($oldname_utf8, RCMAIL_CHARSET, 'UTF7-IMAP'); + $name = rcube_charset::convert($name_utf8, RCUBE_CHARSET, 'UTF7-IMAP'); + $oldname = rcube_charset::convert($oldname_utf8, RCUBE_CHARSET, 'UTF7-IMAP'); $rename = rcmail_rename_folder($oldname, $name); } @@ -122,20 +116,19 @@ else if ($RCMAIL->action == 'rename-folder') rcmail_update_folder_row($name, $oldname); } else if (!$rename) { - rcmail_display_server_error('errorsaving'); + $RCMAIL->display_server_error('errorsaving'); } } - // clear mailbox -else if ($RCMAIL->action == 'purge') -{ - $mbox_utf8 = get_input_value('_mbox', RCUBE_INPUT_POST, true); - $mbox = rcube_charset_convert($mbox_utf8, RCMAIL_CHARSET, 'UTF7-IMAP'); - $delimiter = $STORAGE->get_hierarchy_delimiter(); - $trash_regexp = '/^' . preg_quote($CONFIG['trash_mbox'] . $delimiter, '/') . '/'; +else if ($RCMAIL->action == 'purge') { + $mbox_utf8 = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true); + $mbox = rcube_charset::convert($mbox_utf8, RCUBE_CHARSET, 'UTF7-IMAP'); + $delimiter = $STORAGE->get_hierarchy_delimiter(); + $trash_mbox = $RCMAIL->config->get('trash_mbox'); + $trash_regexp = '/^' . preg_quote($trash . $delimiter, '/') . '/'; // we should only be purging trash (or their subfolders) - if (!strlen($CONFIG['trash_mbox']) || $mbox == $CONFIG['trash_mbox'] + if (!strlen($trash_mbox) || $mbox === $trash_mbox || preg_match($trash_regexp, $mbox) ) { $success = $STORAGE->delete_message('*', $mbox); @@ -143,7 +136,7 @@ else if ($RCMAIL->action == 'purge') } // copy to Trash else { - $success = $STORAGE->move_message('1:*', $CONFIG['trash_mbox'], $mbox); + $success = $STORAGE->move_message('1:*', $trash_mbox, $mbox); $delete = false; } @@ -151,7 +144,7 @@ else if ($RCMAIL->action == 'purge') $OUTPUT->set_env('messagecount', 0); if ($delete) { $OUTPUT->show_message('folderpurged', 'confirmation'); - $OUTPUT->command('set_quota', rcmail_quota_content()); + $OUTPUT->command('set_quota', $RCMAIL->quota_content()); } else { $OUTPUT->show_message('messagemoved', 'confirmation'); @@ -160,29 +153,48 @@ else if ($RCMAIL->action == 'purge') $OUTPUT->command('show_folder', $mbox_utf8, null, true); } else { - rcmail_display_server_error('errorsaving'); + $RCMAIL->display_server_error('errorsaving'); } } - // get mailbox size -else if ($RCMAIL->action == 'folder-size') -{ - $name = trim(get_input_value('_mbox', RCUBE_INPUT_POST, true)); +else if ($RCMAIL->action == 'folder-size') { + $name = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true); $size = $STORAGE->folder_size($name); // @TODO: check quota and show percentage usage of specified mailbox? if ($size !== false) { - $OUTPUT->command('folder_size_update', show_bytes($size)); + $OUTPUT->command('folder_size_update', $RCMAIL->show_bytes($size)); } else { - rcmail_display_server_error(); + $RCMAIL->display_server_error(); } } -if ($OUTPUT->ajax_call) +if ($OUTPUT->ajax_call) { $OUTPUT->send(); +} + +$OUTPUT->set_pagetitle($RCMAIL->gettext('folders')); +$OUTPUT->include_script('list.js'); +$OUTPUT->set_env('prefix_ns', $STORAGE->get_namespace('prefix')); +if ($STORAGE->get_capability('QUOTA')) { + $OUTPUT->set_env('quota', true); +} + +// add some labels to client +$OUTPUT->add_label('deletefolderconfirm', 'purgefolderconfirm', 'folderdeleting', + 'foldermoving', 'foldersubscribing', 'folderunsubscribing', 'quota'); + +// register UI objects +$OUTPUT->add_handlers(array( + 'foldersubscription' => 'rcube_subscription_form', + 'folderframe' => 'rcmail_folder_frame', + 'quotadisplay' => array($RCMAIL, 'quota_display'), +)); + +$OUTPUT->send('folders'); // build table with all folders listed by server @@ -200,7 +212,7 @@ function rcube_subscription_form($attrib) if ($attrib['noheader'] !== true && $attrib['noheader'] != "true") { // add table header - $table->add_header('name', rcube_label('foldername')); + $table->add_header('name', $RCMAIL->gettext('foldername')); $table->add_header('subscribed', ''); } @@ -225,7 +237,7 @@ function rcube_subscription_form($attrib) $folder_id = $folder; $folder = $STORAGE->mod_folder($folder); $foldersplit = explode($delimiter, $folder); - $name = rcube_charset_convert(array_pop($foldersplit), 'UTF7-IMAP'); + $name = rcube_charset::convert(array_pop($foldersplit), 'UTF7-IMAP'); $parent_folder = join($delimiter, $foldersplit); $level = count($foldersplit); @@ -234,7 +246,7 @@ function rcube_subscription_form($attrib) for ($i=1; $i<=$level; $i++) { $ancestor_folder = join($delimiter, array_slice($foldersplit, 0, $i)); if ($ancestor_folder && !$seen[$ancestor_folder]++) { - $ancestor_name = rcube_charset_convert($foldersplit[$i-1], 'UTF7-IMAP'); + $ancestor_name = rcube_charset::convert($foldersplit[$i-1], 'UTF7-IMAP'); $list_folders[] = array( 'id' => $ancestor_folder, 'name' => $ancestor_name, @@ -270,8 +282,8 @@ function rcube_subscription_form($attrib) $checkbox_subscribe = new html_checkbox(array( 'name' => '_subscribed[]', - 'title' => rcube_label('changesubscription'), - 'onclick' => JS_OBJECT_NAME.".command(this.checked?'subscribe':'unsubscribe',this.value)", + 'title' => $RCMAIL->gettext('changesubscription'), + 'onclick' => rcmail_output::JS_OBJECT_NAME.".command(this.checked?'subscribe':'unsubscribe',this.value)", )); // create list of available folders @@ -283,9 +295,9 @@ function rcube_subscription_form($attrib) $noselect = false; $classes = array($i%2 ? 'even' : 'odd'); - $folder_utf8 = rcube_charset_convert($folder['id'], 'UTF7-IMAP'); + $folder_utf8 = rcube_charset::convert($folder['id'], 'UTF7-IMAP'); $display_folder = str_repeat(' ', $folder['level']) - . Q($protected ? rcmail_localize_foldername($folder['id']) : $folder['name']); + . rcube::Q($protected ? $RCMAIL->localize_foldername($folder['id']) : $folder['name']); if ($folder['virtual']) { $classes[] = 'virtual'; @@ -366,8 +378,9 @@ function rcmail_folder_frame($attrib) { global $OUTPUT; - if (!$attrib['id']) + if (!$attrib['id']) { $attrib['id'] = 'rcmfolderframe'; + } return $OUTPUT->frame($attrib, true); } @@ -416,25 +429,3 @@ function rcmail_rename_folder($oldname, $newname) return false; } - - -$OUTPUT->set_pagetitle(rcube_label('folders')); -$OUTPUT->include_script('list.js'); -$OUTPUT->set_env('prefix_ns', $STORAGE->get_namespace('prefix')); -if ($STORAGE->get_capability('QUOTA')) { - $OUTPUT->set_env('quota', true); -} - -// add some labels to client -$OUTPUT->add_label('deletefolderconfirm', 'purgefolderconfirm', 'folderdeleting', - 'foldermoving', 'foldersubscribing', 'folderunsubscribing', 'quota'); - -// register UI objects -$OUTPUT->add_handlers(array( - 'foldersubscription' => 'rcube_subscription_form', - 'folderframe' => 'rcmail_folder_frame', - 'quotadisplay' => 'rcmail_quota_display', -)); - -$OUTPUT->send('folders'); - diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc index af278e5fa..7c36df3b1 100644 --- a/program/steps/settings/func.inc +++ b/program/steps/settings/func.inc @@ -5,7 +5,7 @@ | program/steps/settings/func.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2012, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -20,9 +20,33 @@ */ if (!$OUTPUT->ajax_call) { - $OUTPUT->set_pagetitle(rcube_label('preferences')); + $OUTPUT->set_pagetitle($RCMAIL->gettext('preferences')); } +// register UI objects +$OUTPUT->add_handlers(array( + 'settingstabs' => 'rcmail_settings_tabs', + 'prefsframe' => 'rcmail_preferences_frame', + 'sectionslist' => 'rcmail_sections_list', + 'identitieslist' => 'rcmail_identities_list', +)); + +// register action aliases +$RCMAIL->register_action_map(array( + 'folders' => 'folders.inc', + 'rename-folder' => 'folders.inc', + 'delete-folder' => 'folders.inc', + 'subscribe' => 'folders.inc', + 'unsubscribe' => 'folders.inc', + 'purge' => 'folders.inc', + 'folder-size' => 'folders.inc', + 'add-identity' => 'edit_identity.inc', + 'add-response' => 'edit_response.inc', + 'save-response' => 'edit_response.inc', + 'delete-response' => 'responses.inc', +)); + + // similar function as /steps/settings/identities.inc::rcmail_identity_frame() function rcmail_preferences_frame($attrib) { @@ -48,7 +72,7 @@ function rcmail_sections_list($attrib) list($list, $cols) = rcmail_user_prefs(); // create XHTML table - $out = rcube_table_output($attrib, $list, $cols, 'id'); + $out = $RCMAIL->table_output($attrib, $list, $cols, 'id'); // set client env $RCMAIL->output->add_gui_object('sectionslist', $attrib['id']); @@ -70,7 +94,7 @@ function rcmail_identities_list($attrib) // get identities list and define 'mail' column $list = $RCMAIL->user->list_identities(); foreach ($list as $idx => $row) { - $list[$idx]['mail'] = trim($row['name'] . ' <' . rcube_idn_to_utf8($row['email']) .'>'); + $list[$idx]['mail'] = trim($row['name'] . ' <' . rcube_utils::idn_to_utf8($row['email']) .'>'); } // get all identites from DB and define list of cols to be displayed @@ -81,7 +105,7 @@ function rcmail_identities_list($attrib) // @TODO: use <UL> instead of <TABLE> for identities list // create XHTML table - $out = rcube_table_output($attrib, $plugin['list'], $plugin['cols'], 'identity_id'); + $out = $RCMAIL->table_output($attrib, $plugin['list'], $plugin['cols'], 'identity_id'); // set client env $OUTPUT->add_gui_object('identitieslist', $attrib['id']); @@ -127,13 +151,13 @@ function rcmail_user_prefs($current = null) { global $RCMAIL; - $sections['general'] = array('id' => 'general', 'section' => rcube_label('uisettings')); - $sections['mailbox'] = array('id' => 'mailbox', 'section' => rcube_label('mailboxview')); - $sections['mailview'] = array('id' => 'mailview','section' => rcube_label('messagesdisplaying')); - $sections['compose'] = array('id' => 'compose', 'section' => rcube_label('messagescomposition')); - $sections['addressbook'] = array('id' => 'addressbook','section' => rcube_label('addressbook')); - $sections['folders'] = array('id' => 'folders', 'section' => rcube_label('specialfolders')); - $sections['server'] = array('id' => 'server', 'section' => rcube_label('serversettings')); + $sections['general'] = array('id' => 'general', 'section' => $RCMAIL->gettext('uisettings')); + $sections['mailbox'] = array('id' => 'mailbox', 'section' => $RCMAIL->gettext('mailboxview')); + $sections['mailview'] = array('id' => 'mailview','section' => $RCMAIL->gettext('messagesdisplaying')); + $sections['compose'] = array('id' => 'compose', 'section' => $RCMAIL->gettext('messagescomposition')); + $sections['addressbook'] = array('id' => 'addressbook','section' => $RCMAIL->gettext('addressbook')); + $sections['folders'] = array('id' => 'folders', 'section' => $RCMAIL->gettext('specialfolders')); + $sections['server'] = array('id' => 'server', 'section' => $RCMAIL->gettext('serversettings')); // hook + define list cols $plugin = $RCMAIL->plugins->exec_hook('preferences_sections_list', @@ -155,10 +179,10 @@ function rcmail_user_prefs($current = null) // general case 'general': $blocks = array( - 'main' => array('name' => Q(rcube_label('mainoptions'))), - 'skin' => array('name' => Q(rcube_label('skin'))), - 'browser' => array('name' => Q(rcube_label('browseroptions'))), - 'advanced'=> array('name' => Q(rcube_label('advancedoptions'))), + 'main' => array('name' => rcube::Q($RCMAIL->gettext('mainoptions'))), + 'skin' => array('name' => rcube::Q($RCMAIL->gettext('skin'))), + 'browser' => array('name' => rcube::Q($RCMAIL->gettext('browseroptions'))), + 'advanced'=> array('name' => rcube::Q($RCMAIL->gettext('advancedoptions'))), ); // language selection @@ -175,7 +199,7 @@ function rcmail_user_prefs($current = null) $select->add(array_values($a_lang), array_keys($a_lang)); $blocks['main']['options']['language'] = array( - 'title' => html::label($field_id, Q(rcube_label('language'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('language'))), 'content' => $select->show($RCMAIL->user->language), ); } @@ -188,7 +212,7 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_timezone'; $select = new html_select(array('name' => '_timezone', 'id' => $field_id)); - $select->add(rcube_label('autodetect'), 'auto'); + $select->add($RCMAIL->gettext('autodetect'), 'auto'); $zones = array(); foreach (DateTimeZone::listIdentifiers() as $i => $tzs) { @@ -210,7 +234,7 @@ function rcmail_user_prefs($current = null) } $blocks['main']['options']['timezone'] = array( - 'title' => html::label($field_id, Q(rcube_label('timezone'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('timezone'))), 'content' => $select->show((string)$config['timezone']), ); } @@ -232,7 +256,7 @@ function rcmail_user_prefs($current = null) } $blocks['main']['options']['time_format'] = array( - 'title' => html::label($field_id, Q(rcube_label('timeformat'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('timeformat'))), 'content' => $select->show($RCMAIL->config->get('time_format')), ); } @@ -253,7 +277,7 @@ function rcmail_user_prefs($current = null) } $blocks['main']['options']['date_format'] = array( - 'title' => html::label($field_id, Q(rcube_label('dateformat'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('dateformat'))), 'content' => $select->show($config['date_format']), ); } @@ -268,7 +292,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_pretty_date', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['prettydate'] = array( - 'title' => html::label($field_id, Q(rcube_label('prettydate'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('prettydate'))), 'content' => $input->show($config['prettydate']?1:0), ); } @@ -281,16 +305,16 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_refresh_interval'; $select = new html_select(array('name' => '_refresh_interval', 'id' => $field_id)); - $select->add(rcube_label('never'), 0); + $select->add($RCMAIL->gettext('never'), 0); foreach (array(1, 3, 5, 10, 15, 30, 60) as $min) { if (!$config['min_refresh_interval'] || $config['min_refresh_interval'] <= $min * 60) { - $label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))); + $label = $RCMAIL->gettext(array('name' => 'everynminutes', 'vars' => array('n' => $min))); $select->add($label, $min); } } $blocks['main']['options']['refresh_interval'] = array( - 'title' => html::label($field_id, Q(rcube_label('refreshinterval'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('refreshinterval'))), 'content' => $select->show($config['refresh_interval']/60), ); } @@ -318,16 +342,16 @@ function rcmail_user_prefs($current = null) if (is_array($meta) && $meta['name']) { $skinname = $meta['name']; - $author_link = $meta['url'] ? html::a(array('href' => $meta['url'], 'target' => '_blank'), Q($meta['author'])) : Q($meta['author']); - $license_link = $meta['license-url'] ? html::a(array('href' => $meta['license-url'], 'target' => '_blank'), Q($meta['license'])) : Q($meta['license']); + $author_link = $meta['url'] ? html::a(array('href' => $meta['url'], 'target' => '_blank'), rcube::Q($meta['author'])) : rcube::Q($meta['author']); + $license_link = $meta['license-url'] ? html::a(array('href' => $meta['license-url'], 'target' => '_blank'), rcube::Q($meta['license'])) : rcube::Q($meta['license']); } $blocks['skin']['options'][$skin]['content'] = html::label(array('class' => 'skinselection'), html::span('skinitem', $input->show($config['skin'], array('value' => $skin, 'id' => $field_id.$skin))) . html::span('skinitem', html::img(array('src' => $thumbnail, 'class' => 'skinthumbnail', 'alt' => $skin, 'width' => 64, 'height' => 64))) . - html::span('skinitem', html::span('skinname', Q($skinname)) . html::br() . + html::span('skinitem', html::span('skinname', rcube::Q($skinname)) . html::br() . html::span('skinauthor', $author_link ? 'by ' . $author_link : '') . html::br() . - html::span('skinlicense', $license_link ? rcube_label('license').': ' . $license_link : '')) + html::span('skinlicense', $license_link ? $RCMAIL->gettext('license').': ' . $license_link : '')) ); } } @@ -344,7 +368,7 @@ function rcmail_user_prefs($current = null) $checkbox = new html_checkbox(array('name' => '_standard_windows', 'id' => $field_id, 'value' => 1)); $blocks['browser']['options']['standard_windows'] = array( - 'title' => html::label($field_id, Q(rcube_label('standardwindows'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('standardwindows'))), 'content' => $checkbox->show($config['standard_windows']?1:0), ); } @@ -352,13 +376,13 @@ function rcmail_user_prefs($current = null) if ($current) { $product_name = $RCMAIL->config->get('product_name', 'Roundcube Webmail'); $RCMAIL->output->add_script(sprintf("%s.check_protocol_handler('%s', '#mailtoprotohandler');", - JS_OBJECT_NAME, JQ($product_name)), 'foot'); + rcmail_output::JS_OBJECT_NAME, rcube::JQ($product_name)), 'foot'); } $blocks['browser']['options']['mailtoprotohandler'] = array( 'content' => html::a(array( 'href' => '#', - 'id' => 'mailtoprotohandler'), Q(rcube_label('mailtoprotohandler'))), + 'id' => 'mailtoprotohandler'), rcube::Q($RCMAIL->gettext('mailtoprotohandler'))), ); break; @@ -366,9 +390,9 @@ function rcmail_user_prefs($current = null) // Mailbox view (mail screen) case 'mailbox': $blocks = array( - 'main' => array('name' => Q(rcube_label('mainoptions'))), - 'new_message' => array('name' => Q(rcube_label('newmessage'))), - 'advanced' => array('name' => Q(rcube_label('advancedoptions'))), + 'main' => array('name' => rcube::Q($RCMAIL->gettext('mainoptions'))), + 'new_message' => array('name' => rcube::Q($RCMAIL->gettext('newmessage'))), + 'advanced' => array('name' => rcube::Q($RCMAIL->gettext('advancedoptions'))), ); // show config parameter for preview pane @@ -382,7 +406,7 @@ function rcmail_user_prefs($current = null) 'onchange' => "$('#rcmfd_preview_pane_mark_read').prop('disabled', !this.checked)")); $blocks['main']['options']['preview_pane'] = array( - 'title' => html::label($field_id, Q(rcube_label('previewpane'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('previewpane'))), 'content' => $input->show($config['preview_pane']?1:0), ); } @@ -400,16 +424,16 @@ function rcmail_user_prefs($current = null) $select = new html_select(array('name' => '_preview_pane_mark_read', 'id' => $field_id, 'disabled' => $config['preview_pane']?0:1)); - $select->add(rcube_label('never'), '-1'); - $select->add(rcube_label('immediately'), 0); + $select->add($RCMAIL->gettext('never'), '-1'); + $select->add($RCMAIL->gettext('immediately'), 0); foreach (array(5, 10, 20, 30) as $sec) { - $label = rcube_label(array('name' => 'afternseconds', 'vars' => array('n' => $sec))); + $label = $RCMAIL->gettext(array('name' => 'afternseconds', 'vars' => array('n' => $sec))); $select->add($label, $sec); } $blocks['main']['options']['preview_pane_mark_read'] = array( - 'title' => html::label($field_id, Q(rcube_label('previewpanemarkread'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('previewpanemarkread'))), 'content' => $select->show(intval($config['preview_pane_mark_read'])), ); } @@ -421,14 +445,14 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_mdn_requests'; $select = new html_select(array('name' => '_mdn_requests', 'id' => $field_id)); - $select->add(rcube_label('askuser'), 0); - $select->add(rcube_label('autosend'), 1); - $select->add(rcube_label('autosendknown'), 3); - $select->add(rcube_label('autosendknownignore'), 4); - $select->add(rcube_label('ignore'), 2); + $select->add($RCMAIL->gettext('askuser'), 0); + $select->add($RCMAIL->gettext('autosend'), 1); + $select->add($RCMAIL->gettext('autosendknown'), 3); + $select->add($RCMAIL->gettext('autosendknownignore'), 4); + $select->add($RCMAIL->gettext('ignore'), 2); $blocks['main']['options']['mdn_requests'] = array( - 'title' => html::label($field_id, Q(rcube_label('mdnrequests'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('mdnrequests'))), 'content' => $select->show($config['mdn_requests']), ); } @@ -444,12 +468,12 @@ function rcmail_user_prefs($current = null) if ($supported) { $field_id = 'rcmfd_autoexpand_threads'; $select = new html_select(array('name' => '_autoexpand_threads', 'id' => $field_id)); - $select->add(rcube_label('never'), 0); - $select->add(rcube_label('do_expand'), 1); - $select->add(rcube_label('expand_only_unread'), 2); + $select->add($RCMAIL->gettext('never'), 0); + $select->add($RCMAIL->gettext('do_expand'), 1); + $select->add($RCMAIL->gettext('expand_only_unread'), 2); $blocks['main']['options']['autoexpand_threads'] = array( - 'title' => html::label($field_id, Q(rcube_label('autoexpand_threads'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('autoexpand_threads'))), 'content' => $select->show($config['autoexpand_threads']), ); } @@ -466,7 +490,7 @@ function rcmail_user_prefs($current = null) $size = intval($config['mail_pagesize'] ? $config['mail_pagesize'] : $config['pagesize']); $blocks['main']['options']['pagesize'] = array( - 'title' => html::label($field_id, Q(rcube_label('pagesize'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('pagesize'))), 'content' => $input->show($size ? $size : 50), ); } @@ -480,7 +504,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1)); $blocks['new_message']['options']['check_all_folders'] = array( - 'title' => html::label($field_id, Q(rcube_label('checkallfolders'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('checkallfolders'))), 'content' => $input->show($config['check_all_folders']?1:0), ); } @@ -489,8 +513,8 @@ function rcmail_user_prefs($current = null) // Message viewing case 'mailview': $blocks = array( - 'main' => array('name' => Q(rcube_label('mainoptions'))), - 'advanced' => array('name' => Q(rcube_label('advancedoptions'))), + 'main' => array('name' => rcube::Q($RCMAIL->gettext('mainoptions'))), + 'advanced' => array('name' => rcube::Q($RCMAIL->gettext('advancedoptions'))), ); // show checkbox to open message view in new window @@ -503,7 +527,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_message_extwin', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['message_extwin'] = array( - 'title' => html::label($field_id, Q(rcube_label('showinextwin'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('showinextwin'))), 'content' => $input->show($config['message_extwin']?1:0), ); } @@ -518,7 +542,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_message_show_email', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['message_show_email'] = array( - 'title' => html::label($field_id, Q(rcube_label('showemail'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('showemail'))), 'content' => $input->show($config['message_show_email']?1:0), ); } @@ -534,7 +558,7 @@ function rcmail_user_prefs($current = null) 'onchange' => "$('#rcmfd_show_images').prop('disabled', !this.checked).val(0)")); $blocks['main']['options']['prefer_html'] = array( - 'title' => html::label($field_id, Q(rcube_label('preferhtml'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('preferhtml'))), 'content' => $input->show($config['prefer_html']?1:0), ); } @@ -547,7 +571,7 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_default_charset'; $blocks['advanced']['options']['default_charset'] = array( - 'title' => html::label($field_id, Q(rcube_label('defaultcharset'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('defaultcharset'))), 'content' => $RCMAIL->output->charset_selector(array( 'id' => $field_id, 'name' => '_default_charset', 'selected' => $config['default_charset'] ))); @@ -562,12 +586,12 @@ function rcmail_user_prefs($current = null) $input = new html_select(array('name' => '_show_images', 'id' => $field_id, 'disabled' => !$config['prefer_html'])); - $input->add(rcube_label('never'), 0); - $input->add(rcube_label('fromknownsenders'), 1); - $input->add(rcube_label('always'), 2); + $input->add($RCMAIL->gettext('never'), 0); + $input->add($RCMAIL->gettext('fromknownsenders'), 1); + $input->add($RCMAIL->gettext('always'), 2); $blocks['main']['options']['show_images'] = array( - 'title' => html::label($field_id, Q(rcube_label('showremoteimages'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('showremoteimages'))), 'content' => $input->show($config['prefer_html'] ? $config['show_images'] : 0), ); } @@ -581,7 +605,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_inline_images', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['inline_images'] = array( - 'title' => html::label($field_id, Q(rcube_label('showinlineimages'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('showinlineimages'))), 'content' => $input->show($config['inline_images']?1:0), ); } @@ -596,7 +620,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_display_next', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['display_next'] = array( - 'title' => html::label($field_id, Q(rcube_label('displaynext'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('displaynext'))), 'content' => $input->show($config['display_next']?1:0), ); } @@ -605,10 +629,10 @@ function rcmail_user_prefs($current = null) // Mail composition case 'compose': $blocks = array( - 'main' => array('name' => Q(rcube_label('mainoptions'))), - 'sig' => array('name' => Q(rcube_label('signatureoptions'))), - 'spellcheck' => array('name' => Q(rcube_label('spellcheckoptions'))), - 'advanced' => array('name' => Q(rcube_label('advancedoptions'))), + 'main' => array('name' => rcube::Q($RCMAIL->gettext('mainoptions'))), + 'sig' => array('name' => rcube::Q($RCMAIL->gettext('signatureoptions'))), + 'spellcheck' => array('name' => rcube::Q($RCMAIL->gettext('spellcheckoptions'))), + 'advanced' => array('name' => rcube::Q($RCMAIL->gettext('advancedoptions'))), ); // show checkbox to compose messages in a new window @@ -621,7 +645,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_compose_extwin', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['compose_extwin'] = array( - 'title' => html::label($field_id, Q(rcube_label('composeextwin'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('composeextwin'))), 'content' => $input->show($config['compose_extwin']?1:0), ); } @@ -634,13 +658,13 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_htmleditor'; $select = new html_select(array('name' => '_htmleditor', 'id' => $field_id)); - $select->add(rcube_label('never'), 0); - $select->add(rcube_label('always'), 1); - $select->add(rcube_label('htmlonreply'), 2); - $select->add(rcube_label('htmlonreplyandforward'), 3); + $select->add($RCMAIL->gettext('never'), 0); + $select->add($RCMAIL->gettext('always'), 1); + $select->add($RCMAIL->gettext('htmlonreply'), 2); + $select->add($RCMAIL->gettext('htmlonreplyandforward'), 3); $blocks['main']['options']['htmleditor'] = array( - 'title' => html::label($field_id, Q(rcube_label('htmleditor'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('htmleditor'))), 'content' => $select->show(intval($config['htmleditor'])), ); } @@ -653,14 +677,14 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_autosave'; $select = new html_select(array('name' => '_draft_autosave', 'id' => $field_id, 'disabled' => empty($config['drafts_mbox']))); - $select->add(rcube_label('never'), 0); + $select->add($RCMAIL->gettext('never'), 0); foreach (array(1, 3, 5, 10) as $i => $min) { - $label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))); + $label = $RCMAIL->gettext(array('name' => 'everynminutes', 'vars' => array('n' => $min))); $select->add($label, $min*60); } $blocks['main']['options']['draft_autosave'] = array( - 'title' => html::label($field_id, Q(rcube_label('autosavedraft'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('autosavedraft'))), 'content' => $select->show($config['draft_autosave']), ); } @@ -673,12 +697,12 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_param_folding'; $select = new html_select(array('name' => '_mime_param_folding', 'id' => $field_id)); - $select->add(rcube_label('2231folding'), 0); - $select->add(rcube_label('miscfolding'), 1); - $select->add(rcube_label('2047folding'), 2); + $select->add($RCMAIL->gettext('2231folding'), 0); + $select->add($RCMAIL->gettext('miscfolding'), 1); + $select->add($RCMAIL->gettext('2047folding'), 2); $blocks['advanced']['options']['mime_param_folding'] = array( - 'title' => html::label($field_id, Q(rcube_label('mimeparamfolding'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('mimeparamfolding'))), 'content' => $select->show($config['mime_param_folding']), ); } @@ -692,7 +716,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_force_7bit', 'id' => $field_id, 'value' => 1)); $blocks['advanced']['options']['force_7bit'] = array( - 'title' => html::label($field_id, Q(rcube_label('force7bit'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('force7bit'))), 'content' => $input->show($config['force_7bit']?1:0), ); } @@ -706,7 +730,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_mdn_default', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['mdn_default'] = array( - 'title' => html::label($field_id, Q(rcube_label('reqmdn'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('reqmdn'))), 'content' => $input->show($config['mdn_default']?1:0), ); } @@ -720,7 +744,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_dsn_default', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['dsn_default'] = array( - 'title' => html::label($field_id, Q(rcube_label('reqdsn'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('reqdsn'))), 'content' => $input->show($config['dsn_default']?1:0), ); } @@ -734,7 +758,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_reply_same_folder', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['reply_same_folder'] = array( - 'title' => html::label($field_id, Q(rcube_label('replysamefolder'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('replysamefolder'))), 'content' => $input->show($config['reply_same_folder']?1:0), ); } @@ -747,12 +771,12 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_reply_mode'; $select = new html_select(array('name' => '_reply_mode', 'id' => $field_id)); - $select->add(rcube_label('replyempty'), -1); - $select->add(rcube_label('replybottomposting'), 0); - $select->add(rcube_label('replytopposting'), 1); + $select->add($RCMAIL->gettext('replyempty'), -1); + $select->add($RCMAIL->gettext('replybottomposting'), 0); + $select->add($RCMAIL->gettext('replytopposting'), 1); $blocks['main']['options']['reply_mode'] = array( - 'title' => html::label($field_id, Q(rcube_label('whenreplying'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('whenreplying'))), 'content' => $select->show(intval($config['reply_mode'])), ); } @@ -766,7 +790,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_spellcheck_before_send', 'id' => $field_id, 'value' => 1)); $blocks['spellcheck']['options']['spellcheck_before_send'] = array( - 'title' => html::label($field_id, Q(rcube_label('spellcheckbeforesend'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('spellcheckbeforesend'))), 'content' => $input->show($config['spellcheck_before_send']?1:0), ); } @@ -782,7 +806,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_'.$key, 'id' => 'rcmfd_'.$key, 'value' => 1)); $blocks['spellcheck']['options'][$key] = array( - 'title' => html::label($field_id, Q(rcube_label(str_replace('_', '', $key)))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext(str_replace('_', '', $key)))), 'content' => $input->show($config[$key]?1:0), ); } @@ -797,13 +821,13 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_show_sig'; $select = new html_select(array('name' => '_show_sig', 'id' => $field_id)); - $select->add(rcube_label('never'), 0); - $select->add(rcube_label('always'), 1); - $select->add(rcube_label('newmessageonly'), 2); - $select->add(rcube_label('replyandforwardonly'), 3); + $select->add($RCMAIL->gettext('never'), 0); + $select->add($RCMAIL->gettext('always'), 1); + $select->add($RCMAIL->gettext('newmessageonly'), 2); + $select->add($RCMAIL->gettext('replyandforwardonly'), 3); $blocks['sig']['options']['show_sig'] = array( - 'title' => html::label($field_id, Q(rcube_label('autoaddsignature'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('autoaddsignature'))), 'content' => $select->show($RCMAIL->config->get('show_sig', 1)), ); } @@ -817,7 +841,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_strip_existing_sig', 'id' => $field_id, 'value' => 1)); $blocks['sig']['options']['strip_existing_sig'] = array( - 'title' => html::label($field_id, Q(rcube_label('replyremovesignature'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('replyremovesignature'))), 'content' => $input->show($config['strip_existing_sig']?1:0), ); } @@ -830,11 +854,11 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_forward_attachment'; $select = new html_select(array('name' => '_forward_attachment', 'id' => $field_id)); - $select->add(rcube_label('inline'), 0); - $select->add(rcube_label('asattachment'), 1); + $select->add($RCMAIL->gettext('inline'), 0); + $select->add($RCMAIL->gettext('asattachment'), 1); $blocks['main']['options']['forward_attachment'] = array( - 'title' => html::label($field_id, Q(rcube_label('forwardmode'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('forwardmode'))), 'content' => $select->show(intval($config['forward_attachment'])), ); } @@ -858,24 +882,42 @@ function rcmail_user_prefs($current = null) $select_default_font = new html_select(array('name' => '_default_font', 'id' => $field_id)); $select_default_font->add('', ''); - $fonts = rcube_fontdefs(); + $fonts = rcmail::font_defs(); foreach ($fonts as $fname => $font) { $select_default_font->add($fname, $fname); } $blocks['main']['options']['default_font'] = array( - 'title' => html::label($field_id, Q(rcube_label('defaultfont'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('defaultfont'))), 'content' => $select_default_font->show($RCMAIL->config->get('default_font', 1)) . $select_default_font_size->show($RCMAIL->config->get('default_font_size', 1)) ); } + + if (!isset($no_override['reply_all_mode'])) { + if (!$current) { + continue 2; + } + + $field_id = 'rcmfd_reply_all_mode'; + $select = new html_select(array('name' => '_reply_all_mode', 'id' => $field_id)); + + $select->add($RCMAIL->gettext('replyalldefault'), 0); + $select->add($RCMAIL->gettext('replyalllist'), 1); + + $blocks['main']['options']['reply_all_mode'] = array( + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('replyallmode'))), + 'content' => $select->show(intval($config['reply_all_mode'])), + ); + } + break; // Addressbook config case 'addressbook': $blocks = array( - 'main' => array('name' => Q(rcube_label('mainoptions'))), - 'advanced' => array('name' => Q(rcube_label('advancedoptions'))), + 'main' => array('name' => rcube::Q($RCMAIL->gettext('mainoptions'))), + 'advanced' => array('name' => rcube::Q($RCMAIL->gettext('advancedoptions'))), ); if (!isset($no_override['default_addressbook']) @@ -893,7 +935,7 @@ function rcmail_user_prefs($current = null) } $blocks['main']['options']['default_addressbook'] = array( - 'title' => html::label($field_id, Q(rcube_label('defaultabook'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('defaultabook'))), 'content' => $select->show($config['default_addressbook']), ); } @@ -907,13 +949,13 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_addressbook_name_listing'; $select = new html_select(array('name' => '_addressbook_name_listing', 'id' => $field_id)); - $select->add(rcube_label('name'), 0); - $select->add(rcube_label('firstname') . ' ' . rcube_label('surname'), 1); - $select->add(rcube_label('surname') . ' ' . rcube_label('firstname'), 2); - $select->add(rcube_label('surname') . ', ' . rcube_label('firstname'), 3); + $select->add($RCMAIL->gettext('name'), 0); + $select->add($RCMAIL->gettext('firstname') . ' ' . $RCMAIL->gettext('surname'), 1); + $select->add($RCMAIL->gettext('surname') . ' ' . $RCMAIL->gettext('firstname'), 2); + $select->add($RCMAIL->gettext('surname') . ', ' . $RCMAIL->gettext('firstname'), 3); $blocks['main']['options']['list_name_listing'] = array( - 'title' => html::label($field_id, Q(rcube_label('listnamedisplay'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('listnamedisplay'))), 'content' => $select->show($config['addressbook_name_listing']), ); } @@ -927,12 +969,12 @@ function rcmail_user_prefs($current = null) $field_id = 'rcmfd_addressbook_sort_col'; $select = new html_select(array('name' => '_addressbook_sort_col', 'id' => $field_id)); - $select->add(rcube_label('name'), 'name'); - $select->add(rcube_label('firstname'), 'firstname'); - $select->add(rcube_label('surname'), 'surname'); + $select->add($RCMAIL->gettext('name'), 'name'); + $select->add($RCMAIL->gettext('firstname'), 'firstname'); + $select->add($RCMAIL->gettext('surname'), 'surname'); $blocks['main']['options']['sort_col'] = array( - 'title' => html::label($field_id, Q(rcube_label('listsorting'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('listsorting'))), 'content' => $select->show($config['addressbook_sort_col']), ); } @@ -948,7 +990,7 @@ function rcmail_user_prefs($current = null) $size = intval($config['addressbook_pagesize'] ? $config['addressbook_pagesize'] : $config['pagesize']); $blocks['main']['options']['pagesize'] = array( - 'title' => html::label($field_id, Q(rcube_label('pagesize'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('pagesize'))), 'content' => $input->show($size ? $size : 50), ); } @@ -962,7 +1004,7 @@ function rcmail_user_prefs($current = null) $checkbox = new html_checkbox(array('name' => '_autocomplete_single', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['autocomplete_single'] = array( - 'title' => html::label($field_id, Q(rcube_label('autocompletesingle'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('autocompletesingle'))), 'content' => $checkbox->show($config['autocomplete_single']?1:0), ); } @@ -971,8 +1013,8 @@ function rcmail_user_prefs($current = null) // Special IMAP folders case 'folders': $blocks = array( - 'main' => array('name' => Q(rcube_label('mainoptions'))), - 'advanced' => array('name' => Q(rcube_label('advancedoptions'))), + 'main' => array('name' => rcube::Q($RCMAIL->gettext('mainoptions'))), + 'advanced' => array('name' => rcube::Q($RCMAIL->gettext('advancedoptions'))), ); if (!isset($no_override['show_real_foldernames'])) { @@ -984,14 +1026,14 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_show_real_foldernames', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['show_real_foldernames'] = array( - 'title' => html::label($field_id, Q(rcube_label('show_real_foldernames'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('show_real_foldernames'))), 'content' => $input->show($config['show_real_foldernames']?1:0), ); } // Configure special folders if (!isset($no_override['default_folders']) && $current) { - $select = rcmail_mailbox_select(array( + $select = $RCMAIL->folder_selector(array( 'noselection' => '---', 'realnames' => true, 'maxlength' => 30, @@ -1009,7 +1051,7 @@ function rcmail_user_prefs($current = null) } $blocks['main']['options']['drafts_mbox'] = array( - 'title' => Q(rcube_label('drafts')), + 'title' => rcube::Q($RCMAIL->gettext('drafts')), 'content' => $select->show($config['drafts_mbox'], array('name' => "_drafts_mbox", 'onchange' => $onchange)), ); } @@ -1020,7 +1062,7 @@ function rcmail_user_prefs($current = null) } $blocks['main']['options']['sent_mbox'] = array( - 'title' => Q(rcube_label('sent')), + 'title' => rcube::Q($RCMAIL->gettext('sent')), 'content' => $select->show($config['sent_mbox'], array('name' => "_sent_mbox", 'onchange' => '')), ); } @@ -1031,7 +1073,7 @@ function rcmail_user_prefs($current = null) } $blocks['main']['options']['junk_mbox'] = array( - 'title' => Q(rcube_label('junk')), + 'title' => rcube::Q($RCMAIL->gettext('junk')), 'content' => $select->show($config['junk_mbox'], array('name' => "_junk_mbox", 'onchange' => $onchange)), ); } @@ -1042,7 +1084,7 @@ function rcmail_user_prefs($current = null) } $blocks['main']['options']['trash_mbox'] = array( - 'title' => Q(rcube_label('trash')), + 'title' => rcube::Q($RCMAIL->gettext('trash')), 'content' => $select->show($config['trash_mbox'], array('name' => "_trash_mbox", 'onchange' => $onchange)), ); } @@ -1051,9 +1093,9 @@ function rcmail_user_prefs($current = null) // Server settings case 'server': $blocks = array( - 'main' => array('name' => Q(rcube_label('mainoptions'))), - 'maintenance' => array('name' => Q(rcube_label('maintenance'))), - 'advanced' => array('name' => Q(rcube_label('advancedoptions'))), + 'main' => array('name' => rcube::Q($RCMAIL->gettext('mainoptions'))), + 'maintenance' => array('name' => rcube::Q($RCMAIL->gettext('maintenance'))), + 'advanced' => array('name' => rcube::Q($RCMAIL->gettext('advancedoptions'))), ); if (!isset($no_override['read_when_deleted'])) { @@ -1065,7 +1107,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_read_when_deleted', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['read_when_deleted'] = array( - 'title' => html::label($field_id, Q(rcube_label('readwhendeleted'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('readwhendeleted'))), 'content' => $input->show($config['read_when_deleted']?1:0), ); } @@ -1079,7 +1121,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_flag_for_deletion', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['flag_for_deletion'] = array( - 'title' => html::label($field_id, Q(rcube_label('flagfordeletion'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('flagfordeletion'))), 'content' => $input->show($config['flag_for_deletion']?1:0), ); } @@ -1094,7 +1136,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_skip_deleted', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['skip_deleted'] = array( - 'title' => html::label($field_id, Q(rcube_label('skipdeleted'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('skipdeleted'))), 'content' => $input->show($config['skip_deleted']?1:0), ); } @@ -1108,7 +1150,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_delete_always', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['delete_always'] = array( - 'title' => html::label($field_id, Q(rcube_label('deletealways'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('deletealways'))), 'content' => $input->show($config['delete_always']?1:0), ); } @@ -1122,7 +1164,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_delete_junk', 'id' => $field_id, 'value' => 1)); $blocks['main']['options']['delete_junk'] = array( - 'title' => html::label($field_id, Q(rcube_label('deletejunk'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('deletejunk'))), 'content' => $input->show($config['delete_junk']?1:0), ); } @@ -1137,7 +1179,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_logout_purge', 'id' => $field_id, 'value' => 1)); $blocks['maintenance']['options']['logout_purge'] = array( - 'title' => html::label($field_id, Q(rcube_label('logoutclear'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('logoutclear'))), 'content' => $input->show($config['logout_purge']?1:0), ); } @@ -1152,7 +1194,7 @@ function rcmail_user_prefs($current = null) $input = new html_checkbox(array('name' => '_logout_expunge', 'id' => $field_id, 'value' => 1)); $blocks['maintenance']['options']['logout_expunge'] = array( - 'title' => html::label($field_id, Q(rcube_label('logoutcompact'))), + 'title' => html::label($field_id, rcube::Q($RCMAIL->gettext('logoutcompact'))), 'content' => $input->show($config['logout_expunge']?1:0), ); } @@ -1162,14 +1204,31 @@ function rcmail_user_prefs($current = null) $data = $RCMAIL->plugins->exec_hook('preferences_list', array('section' => $sect['id'], 'blocks' => $blocks, 'current' => $current)); + $advanced_prefs = (array) $RCMAIL->config->get('advanced_prefs'); + // create output - foreach ($data['blocks'] as $block) { + foreach ($data['blocks'] as $key => $block) { if (!empty($block['content']) || !empty($block['options'])) { $found = true; - break; + } + // move some options to the 'advanced' block as configured by admin + if ($key != 'advanced') { + foreach ($advanced_prefs as $opt) { + if ($block['options'][$opt]) { + $data['blocks']['advanced']['options'][$opt] = $block['options'][$opt]; + unset($data['blocks'][$key]['options'][$opt]); + } + } } } + // move 'advanced' block to the end of the list + if (!empty($data['blocks']['advanced'])) { + $adv = $data['blocks']['advanced']; + unset($data['blocks']['advanced']); + $data['blocks']['advanced'] = $adv; + } + if (!$found) unset($sections[$idx]); else @@ -1230,20 +1289,22 @@ function rcmail_update_folder_row($name, $oldname=null, $subscribe=false, $class $storage = $RCMAIL->get_storage(); $delimiter = $storage->get_hierarchy_delimiter(); - $name_utf8 = rcube_charset_convert($name, 'UTF7-IMAP'); + $name_utf8 = rcube_charset::convert($name, 'UTF7-IMAP'); $protected = $protect_folders && in_array($name, $default_folders); $foldersplit = explode($delimiter, $storage->mod_folder($name)); $level = count($foldersplit) - 1; $display_name = str_repeat(' ', $level) - . Q($protected ? rcmail_localize_foldername($name) : rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP')); + . rcube::Q($protected ? $RCMAIL->localize_foldername($name) : rcube_charset::convert($foldersplit[$level], 'UTF7-IMAP')); - if ($oldname === null) + if ($oldname === null) { $OUTPUT->command('add_folder_row', $name_utf8, $display_name, $protected, $subscribe, false, $class_name); - else - $OUTPUT->command('replace_folder_row', rcube_charset_convert($oldname, 'UTF7-IMAP'), + } + else { + $OUTPUT->command('replace_folder_row', rcube_charset::convert($oldname, 'UTF7-IMAP'), $name_utf8, $display_name, $protected, $class_name); + } } /** @@ -1260,17 +1321,18 @@ function rcmail_settings_tabs($attrib) array('command' => 'preferences', 'type' => 'link', 'label' => 'preferences', 'title' => 'editpreferences'), array('command' => 'folders', 'type' => 'link', 'label' => 'folders', 'title' => 'managefolders'), array('command' => 'identities', 'type' => 'link', 'label' => 'identities', 'title' => 'manageidentities'), + array('command' => 'responses', 'type' => 'link', 'label' => 'responses', 'title' => 'editresponses'), ); // get all identites from DB and define list of cols to be displayed $plugin = $RCMAIL->plugins->exec_hook('settings_actions', array( 'actions' => $default_actions, - 'attrib' => $attrib, + 'attrib' => $attrib, )); - $attrib = $plugin['attrib']; + $attrib = $plugin['attrib']; $tagname = $attrib['tagname']; - $tabs = array(); + $tabs = array(); foreach ($plugin['actions'] as $k => $action) { if (!$action['command'] && !$action['href'] && $action['action']) { @@ -1278,13 +1340,15 @@ function rcmail_settings_tabs($attrib) } $button = $OUTPUT->button($action); - $attr = $attrib; + $attr = $attrib; $cmd = $action['action'] ? $action['action'] : $action['command']; - $id = $action['id'] ? $action['id'] : $cmd; + $id = $action['id'] ? $action['id'] : $cmd; + if (!empty($id)) { $attr['id'] = preg_replace('/[^a-z0-9]/i', '', $attrib['idprefix'] . $id); } + $classnames = array($attrib['class']); if (!empty($action['class'])) { $classnames[] = $action['class']; @@ -1295,30 +1359,10 @@ function rcmail_settings_tabs($attrib) if ($RCMAIL->action == $cmd) { $classnames[] = $attrib['selclass']; } + $attr['class'] = join(' ', $classnames); $tabs[] = html::tag($tagname, $attr, $button, html::$common_attrib); } return join('', $tabs); } - - -// register UI objects -$OUTPUT->add_handlers(array( - 'settingstabs' => 'rcmail_settings_tabs', - 'prefsframe' => 'rcmail_preferences_frame', - 'sectionslist' => 'rcmail_sections_list', - 'identitieslist' => 'rcmail_identities_list', -)); - -// register action aliases -$RCMAIL->register_action_map(array( - 'folders' => 'folders.inc', - 'rename-folder' => 'folders.inc', - 'delete-folder' => 'folders.inc', - 'subscribe' => 'folders.inc', - 'unsubscribe' => 'folders.inc', - 'purge' => 'folders.inc', - 'folder-size' => 'folders.inc', - 'add-identity' => 'edit_identity.inc', -)); diff --git a/program/steps/settings/identities.inc b/program/steps/settings/identities.inc index 82a1841a3..e19c16c79 100644 --- a/program/steps/settings/identities.inc +++ b/program/steps/settings/identities.inc @@ -5,7 +5,7 @@ | program/steps/settings/identities.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2007, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -21,23 +21,24 @@ define('IDENTITIES_LEVEL', intval($RCMAIL->config->get('identities_level', 0))); -$OUTPUT->set_pagetitle(rcube_label('identities')); +$OUTPUT->set_pagetitle($RCMAIL->gettext('identities')); $OUTPUT->include_script('list.js'); - -// similar function as /steps/addressbook/func.inc::rcmail_contact_frame() -function rcmail_identity_frame($attrib) - { - global $OUTPUT; - - if (!$attrib['id']) - $attrib['id'] = 'rcmIdentityFrame'; - - return $OUTPUT->frame($attrib, true); - } - $OUTPUT->add_handler('identityframe', 'rcmail_identity_frame'); $OUTPUT->set_env('identities_level', IDENTITIES_LEVEL); $OUTPUT->add_label('deleteidentityconfirm'); $OUTPUT->send('identities'); + + +// similar function as /steps/addressbook/func.inc::rcmail_contact_frame() +function rcmail_identity_frame($attrib) +{ + global $OUTPUT; + + if (!$attrib['id']) { + $attrib['id'] = 'rcmIdentityFrame'; + } + + return $OUTPUT->frame($attrib, true); +} diff --git a/program/steps/settings/responses.inc b/program/steps/settings/responses.inc new file mode 100644 index 000000000..35a2a1b64 --- /dev/null +++ b/program/steps/settings/responses.inc @@ -0,0 +1,133 @@ +<?php + +/* + +-----------------------------------------------------------------------+ + | program/steps/settings/responses.inc | + | | + | This file is part of the Roundcube Webmail client | + | Copyright (C) 2013, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | + | | + | PURPOSE: | + | Manage and save canned response texts | + | | + +-----------------------------------------------------------------------+ + | Author: Thomas Bruederli <roundcube@gmail.com> | + +-----------------------------------------------------------------------+ +*/ + + +if (!empty($_POST['_insert'])) { + $name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST)); + $text = trim(rcube_utils::get_input_value('_text', rcube_utils::INPUT_POST)); + + if (!empty($name) && !empty($text)) { + $dupes = 0; + $responses = $RCMAIL->get_compose_responses(false, true); + foreach ($responses as $resp) { + if (strcasecmp($name, preg_replace('/\s\(\d+\)$/', '', $resp['name'])) == 0) + $dupes++; + } + if ($dupes) { // require a unique name + $name .= ' (' . ++$dupes . ')'; + } + + $response = array('name' => $name, 'text' => $text, 'format' => 'text', 'key' => substr(md5($name), 0, 16)); + $responses[] = $response; + + if ($RCMAIL->user->save_prefs(array('compose_responses' => $responses))) { + $RCMAIL->output->command('add_response_item', $response); + $RCMAIL->output->command('display_message', $RCMAIL->gettext('successfullysaved'), 'confirmation'); + } + else { + $RCMAIL->output->command('display_message', $RCMAIL->gettext('errorsaving'), 'error'); + } + } + + // send response + $RCMAIL->output->send(); +} + +if ($RCMAIL->action == 'delete-response') { + if ($key = rcube_utils::get_input_value('_key', rcube_utils::INPUT_GPC)) { + $responses = $RCMAIL->get_compose_responses(false, true); + foreach ($responses as $i => $response) { + if (empty($response['key'])) + $response['key'] = substr(md5($response['name']), 0, 16); + if ($response['key'] == $key) { + unset($responses[$i]); + $deleted = $RCMAIL->user->save_prefs(array('compose_responses' => $responses)); + break; + } + } + } + + if ($deleted) { + $RCMAIL->output->command('display_message', $RCMAIL->gettext('deletedsuccessfully'), 'confirmation'); + $RCMAIL->output->command('remove_response', $key); + } + + if ($RCMAIL->output->ajax_call) { + $RCMAIL->output->send(); + } +} + + +$OUTPUT->set_pagetitle($RCMAIL->gettext('responses')); +$OUTPUT->include_script('list.js'); + +$OUTPUT->add_handlers(array( + 'responseframe' => 'rcmail_response_frame', + 'responseslist' => 'rcmail_responses_list', +)); +$OUTPUT->add_label('deleteresponseconfirm'); + +$OUTPUT->send('responses'); + + +/** + * + */ +function rcmail_responses_list($attrib) +{ + global $RCMAIL, $OUTPUT; + + $attrib += array('id' => 'rcmresponseslist', 'tagname' => 'table', 'cols' => 1); + + $plugin = $RCMAIL->plugins->exec_hook('responses_list', array( + 'list' => $RCMAIL->get_compose_responses(true), + 'cols' => array('name') + )); + + $out = $RCMAIL->table_output($attrib, $plugin['list'], $plugin['cols'], 'key'); + + $readonly_responses = array(); + foreach ($plugin['list'] as $item) { + if (!empty($item['static'])) { + $readonly_responses[] = $item['key']; + } + } + + // set client env + $OUTPUT->add_gui_object('responseslist', $attrib['id']); + $OUTPUT->set_env('readonly_responses', $readonly_responses); + + return $out; +} + +// similar function as /steps/addressbook/func.inc::rcmail_contact_frame() +function rcmail_response_frame($attrib) +{ + global $OUTPUT; + + if (!$attrib['id']) { + $attrib['id'] = 'rcmResponseFrame'; + } + + $OUTPUT->set_env('contentframe', $attrib['id']); + + return $OUTPUT->frame($attrib, true); +} diff --git a/program/steps/settings/save_folder.inc b/program/steps/settings/save_folder.inc index 877b0fbbe..d1449bb38 100644 --- a/program/steps/settings/save_folder.inc +++ b/program/steps/settings/save_folder.inc @@ -1,11 +1,11 @@ <?php -/** +/* +-----------------------------------------------------------------------+ | program/steps/settings/save_folder.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2012, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,18 +19,17 @@ +-----------------------------------------------------------------------+ */ -// WARNING: folder names in UI are encoded with RCMAIL_CHARSET +// WARNING: folder names in UI are encoded with RCUBE_CHARSET // init IMAP connection $STORAGE = $RCMAIL->get_storage(); +$name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true)); +$old = rcube_utils::get_input_value('_mbox', rcube_utils::INPUT_POST, true); +$path = rcube_utils::get_input_value('_parent', rcube_utils::INPUT_POST, true); -$name = trim(get_input_value('_name', RCUBE_INPUT_POST, true)); -$old = trim(get_input_value('_mbox', RCUBE_INPUT_POST, true)); -$path = trim(get_input_value('_parent', RCUBE_INPUT_POST, true)); - -$name_imap = rcube_charset_convert($name, RCMAIL_CHARSET, 'UTF7-IMAP'); -$old_imap = rcube_charset_convert($old, RCMAIL_CHARSET, 'UTF7-IMAP'); +$name_imap = rcube_charset::convert($name, RCUBE_CHARSET, 'UTF7-IMAP'); +$old_imap = rcube_charset::convert($old, RCUBE_CHARSET, 'UTF7-IMAP'); // $path is in UTF7-IMAP already $delimiter = $STORAGE->get_hierarchy_delimiter(); @@ -40,16 +39,16 @@ $options = strlen($old_imap) ? rcmail_folder_options($old_imap) : array(); if ($options['protected'] || $options['norename']) { } else if (!strlen($name)) { - $error = rcube_label('cannotbeempty'); + $error = $RCMAIL->gettext('namecannotbeempty'); } else if (mb_strlen($name) > 128) { - $error = rcube_label('nametoolong'); + $error = $RCMAIL->gettext('nametoolong'); } else { // these characters are problematic e.g. when used in LIST/LSUB foreach (array($delimiter, '%', '*') as $char) { if (strpos($name, $delimiter) !== false) { - $error = rcube_label('forbiddencharacter') . " ($char)"; + $error = $RCMAIL->gettext('forbiddencharacter') . " ($char)"; break; } } @@ -76,7 +75,7 @@ if (!$error && strlen($path) && (!strlen($old_imap) || $old_imap != $name_imap)) if ($parent_opts['namespace'] != 'personal' && (empty($parent_opts['rights']) || !preg_match('/[ck]/', implode($parent_opts['rights']))) ) { - $error = rcube_label('parentnotwritable'); + $error = $RCMAIL->gettext('parentnotwritable'); } } @@ -90,15 +89,14 @@ else { $folder['options'] = $options; $folder['settings'] = array( // List view mode: 0-list, 1-threads - 'view_mode' => (int) get_input_value('_viewmode', RCUBE_INPUT_POST), - 'sort_column' => get_input_value('_sortcol', RCUBE_INPUT_POST), - 'sort_order' => get_input_value('_sortord', RCUBE_INPUT_POST), + 'view_mode' => (int) rcube_utils::get_input_value('_viewmode', rcube_utils::INPUT_POST), + 'sort_column' => rcube_utils::get_input_value('_sortcol', rcube_utils::INPUT_POST), + 'sort_order' => rcube_utils::get_input_value('_sortord', rcube_utils::INPUT_POST), ); } // create a new mailbox if (!$error && !strlen($old)) { - $folder['subscribe'] = true; $plugin = $RCMAIL->plugins->exec_hook('folder_create', array('record' => $folder)); @@ -136,7 +134,6 @@ if (!$error && !strlen($old)) { $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false); } } - // update a mailbox else if (!$error) { $plugin = $RCMAIL->plugins->exec_hook('folder_update', array('record' => $folder)); @@ -192,6 +189,9 @@ else if (!$error) { rcmail_update_folder_row($folder['name'], $folder['oldname'], $folder['subscribe'], $folder['class']); $OUTPUT->send('iframe'); } + else if (!empty($folder['class'])) { + rcmail_update_folder_row($folder['name'], $folder['oldname'], $folder['subscribe'], $folder['class']); + } } else { // show error message @@ -199,4 +199,4 @@ else if (!$error) { } } -rcmail_overwrite_action('edit-folder'); +$RCMAIL->overwrite_action('edit-folder'); diff --git a/program/steps/settings/save_identity.inc b/program/steps/settings/save_identity.inc index d3b132f8b..1584c5f00 100644 --- a/program/steps/settings/save_identity.inc +++ b/program/steps/settings/save_identity.inc @@ -5,7 +5,7 @@ | program/steps/settings/save_identity.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -21,161 +21,173 @@ define('IDENTITIES_LEVEL', intval($RCMAIL->config->get('identities_level', 0))); -$a_save_cols = array('name', 'email', 'organization', 'reply-to', 'bcc', 'standard', 'signature', 'html_signature'); +$a_save_cols = array('name', 'email', 'organization', 'reply-to', 'bcc', 'standard', 'signature', 'html_signature'); $a_boolean_cols = array('standard', 'html_signature'); $updated = $default_id = false; // check input if (IDENTITIES_LEVEL != 4 && (empty($_POST['_name']) || (empty($_POST['_email']) && IDENTITIES_LEVEL != 1 && IDENTITIES_LEVEL != 3))) { - $OUTPUT->show_message('formincomplete', 'warning'); - rcmail_overwrite_action('edit-identity'); - return; + $OUTPUT->show_message('formincomplete', 'warning'); + $RCMAIL->overwrite_action('edit-identity'); + return; } $save_data = array(); foreach ($a_save_cols as $col) { - $fname = '_'.$col; - if (isset($_POST[$fname])) - $save_data[$col] = get_input_value($fname, RCUBE_INPUT_POST, true); + $fname = '_'.$col; + if (isset($_POST[$fname])) { + $save_data[$col] = rcube_utils::get_input_value($fname, rcube_utils::INPUT_POST, true); + } } // set "off" values for checkboxes that were not checked, and therefore // not included in the POST body. foreach ($a_boolean_cols as $col) { - $fname = '_' . $col; - if (!isset($_POST[$fname])) - $save_data[$col] = 0; + $fname = '_' . $col; + if (!isset($_POST[$fname])) { + $save_data[$col] = 0; + } } // unset email address if user has no rights to change it if (IDENTITIES_LEVEL == 1 || IDENTITIES_LEVEL == 3) { - unset($save_data['email']); + unset($save_data['email']); } // unset all fields except signature else if (IDENTITIES_LEVEL == 4) { - foreach ($save_data as $idx => $value) { - if ($idx != 'signature' && $idx != 'html_signature') { - unset($save_data[$idx]); + foreach ($save_data as $idx => $value) { + if ($idx != 'signature' && $idx != 'html_signature') { + unset($save_data[$idx]); + } } - } } // Validate e-mail addresses -$email_checks = array(rcube_idn_to_ascii($save_data['email'])); +$email_checks = array(rcube_utils::idn_to_ascii($save_data['email'])); foreach (array('reply-to', 'bcc') as $item) { - foreach (rcube_mime::decode_address_list($save_data[$item], null, false) as $rcpt) - $email_checks[] = rcube_idn_to_ascii($rcpt['mailto']); + foreach (rcube_mime::decode_address_list($save_data[$item], null, false) as $rcpt) { + $email_checks[] = rcube_utils::idn_to_ascii($rcpt['mailto']); + } } foreach ($email_checks as $email) { - if ($email && !check_email($email)) { - // show error message - $OUTPUT->show_message('emailformaterror', 'error', array('email' => rcube_idn_to_utf8($email)), false); - rcmail_overwrite_action('edit-identity'); - return; - } + if ($email && !rcube_utils::check_email($email)) { + // show error message + $OUTPUT->show_message('emailformaterror', 'error', array('email' => rcube_utils::idn_to_utf8($email)), false); + $RCMAIL->overwrite_action('edit-identity'); + return; + } } // XSS protection in HTML signature (#1489251) if (!empty($save_data['signature']) && !empty($save_data['html_signature'])) { - $save_data['signature'] = rcmail_wash_html($save_data['signature']); + $save_data['signature'] = rcmail_wash_html($save_data['signature']); - // clear POST data of signature, we want to use safe content - // when the form is displayed again - unset($_POST['_signature']); + // clear POST data of signature, we want to use safe content + // when the form is displayed again + unset($_POST['_signature']); } // update an existing contact if ($_POST['_iid']) { - $iid = get_input_value('_iid', RCUBE_INPUT_POST); - - if (in_array(IDENTITIES_LEVEL, array(1,3,4))) { - // merge with old identity data, fixes #1488834 - $identity = $RCMAIL->user->get_identity($iid); - $save_data = array_merge($identity, $save_data); - unset($save_data['changed'], $save_data['del'], $save_data['user_id'], $save_data['identity_id']); - } - - $plugin = $RCMAIL->plugins->exec_hook('identity_update', array('id' => $iid, 'record' => $save_data)); - $save_data = $plugin['record']; - - if ($save_data['email']) - $save_data['email'] = rcube_idn_to_ascii($save_data['email']); - if (!$plugin['abort']) - $updated = $RCMAIL->user->update_identity($iid, $save_data); - else - $updated = $plugin['result']; - - if ($updated) { - $OUTPUT->show_message('successfullysaved', 'confirmation'); - - if (!empty($save_data['standard'])) - $default_id = $iid; - - if ($_POST['_framed']) { - // update the changed col in list - $OUTPUT->command('parent.update_identity_row', $iid, Q(trim($save_data['name'] . ' <' . rcube_idn_to_utf8($save_data['email']) .'>'))); + $iid = rcube_utils::get_input_value('_iid', rcube_utils::INPUT_POST); + + if (in_array(IDENTITIES_LEVEL, array(1,3,4))) { + // merge with old identity data, fixes #1488834 + $identity = $RCMAIL->user->get_identity($iid); + $save_data = array_merge($identity, $save_data); + + unset($save_data['changed'], $save_data['del'], $save_data['user_id'], $save_data['identity_id']); } - } - else { - // show error message - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false); - rcmail_overwrite_action('edit-identity'); - return; - } -} + $plugin = $RCMAIL->plugins->exec_hook('identity_update', array('id' => $iid, 'record' => $save_data)); + $save_data = $plugin['record']; + + if ($save_data['email']) { + $save_data['email'] = rcube_utils::idn_to_ascii($save_data['email']); + } + + if (!$plugin['abort']) + $updated = $RCMAIL->user->update_identity($iid, $save_data); + else + $updated = $plugin['result']; + + if ($updated) { + $OUTPUT->show_message('successfullysaved', 'confirmation'); + + if (!empty($save_data['standard'])) { + $default_id = $iid; + } + + if ($_POST['_framed']) { + // update the changed col in list + $name = $save_data['name'] . ' <' . rcube_utils::idn_to_utf8($save_data['email']) .'>'; + $OUTPUT->command('parent.update_identity_row', $iid, rcube::Q(trim($name))); + } + } + else { + // show error message + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false); + $RCMAIL->overwrite_action('edit-identity'); + return; + } +} // insert a new identity record else if (IDENTITIES_LEVEL < 2) { - if (IDENTITIES_LEVEL == 1) { - $save_data['email'] = $RCMAIL->get_user_email(); - } + if (IDENTITIES_LEVEL == 1) { + $save_data['email'] = $RCMAIL->get_user_email(); + } - $plugin = $RCMAIL->plugins->exec_hook('identity_create', array('record' => $save_data)); - $save_data = $plugin['record']; + $plugin = $RCMAIL->plugins->exec_hook('identity_create', array('record' => $save_data)); + $save_data = $plugin['record']; - if ($save_data['email']) - $save_data['email'] = rcube_idn_to_ascii($save_data['email']); + if ($save_data['email']) { + $save_data['email'] = rcube_utils::idn_to_ascii($save_data['email']); + } - if (!$plugin['abort']) - $insert_id = $save_data['email'] ? $RCMAIL->user->insert_identity($save_data) : null; - else - $insert_id = $plugin['result']; + if (!$plugin['abort']) + $insert_id = $save_data['email'] ? $RCMAIL->user->insert_identity($save_data) : null; + else + $insert_id = $plugin['result']; - if ($insert_id) { - $OUTPUT->show_message('successfullysaved', 'confirmation', null, false); + if ($insert_id) { + $OUTPUT->show_message('successfullysaved', 'confirmation', null, false); - $_GET['_iid'] = $insert_id; + $_GET['_iid'] = $insert_id; - if (!empty($save_data['standard'])) - $default_id = $insert_id; + if (!empty($save_data['standard'])) { + $default_id = $insert_id; + } - if ($_POST['_framed']) { - // add a new row to the list - $OUTPUT->command('parent.update_identity_row', $insert_id, Q(trim($save_data['name'] . ' <' . rcube_idn_to_utf8($save_data['email']) .'>')), true); + if ($_POST['_framed']) { + // add a new row to the list + $name = $save_data['name'] . ' <' . rcube_utils::idn_to_utf8($save_data['email']) .'>'; + $OUTPUT->command('parent.update_identity_row', $insert_id, rcube::Q(trim($name)), true); + } + } + else { + // show error message + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false); + $RCMAIL->overwrite_action('edit-identity'); + return; } - } - else { - // show error message - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error', null, false); - rcmail_overwrite_action('edit-identity'); - return; - } } -else - $OUTPUT->show_message('opnotpermitted', 'error'); - +else { + $OUTPUT->show_message('opnotpermitted', 'error'); +} // mark all other identities as 'not-default' -if ($default_id) - $RCMAIL->user->set_default($default_id); +if ($default_id) { + $RCMAIL->user->set_default($default_id); +} // go to next step if (!empty($_REQUEST['_framed'])) { - rcmail_overwrite_action('edit-identity'); + $RCMAIL->overwrite_action('edit-identity'); +} +else { + $RCMAIL->overwrite_action('identities'); } -else - rcmail_overwrite_action('identities'); /** @@ -185,16 +197,16 @@ function rcmail_wash_html($html) { // Add header with charset spec., washtml cannot work without that $html = '<html><head>' - . '<meta http-equiv="Content-Type" content="text/html; charset='.RCMAIL_CHARSET.'" />' + . '<meta http-equiv="Content-Type" content="text/html; charset='.RCUBE_CHARSET.'" />' . '</head><body>' . $html . '</body></html>'; // clean HTML with washhtml by Frederic Motte $wash_opts = array( - 'show_washed' => false, - 'allow_remote' => 1, - 'charset' => RCMAIL_CHARSET, + 'show_washed' => false, + 'allow_remote' => 1, + 'charset' => RCUBE_CHARSET, 'html_elements' => array('body', 'link'), - 'html_attribs' => array('rel', 'type'), + 'html_attribs' => array('rel', 'type'), ); // initialize HTML washer @@ -204,12 +216,12 @@ function rcmail_wash_html($html) //$washer->add_callback('style', 'rcmail_washtml_callback'); // Remove non-UTF8 characters (#1487813) - $html = rc_utf8_clean($html); + $html = rcube_charset::clean($html); $html = $washer->wash($html); // remove unwanted comments and tags (produced by washtml) $html = preg_replace(array('/<!--[^>]+-->/', '/<\/?body>/'), '', $html); - return $html; + return $html; } diff --git a/program/steps/settings/save_prefs.inc b/program/steps/settings/save_prefs.inc index 717c7ad8c..f71eee39a 100644 --- a/program/steps/settings/save_prefs.inc +++ b/program/steps/settings/save_prefs.inc @@ -5,7 +5,7 @@ | program/steps/settings/save_prefs.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2009, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,190 +19,191 @@ +-----------------------------------------------------------------------+ */ -$CURR_SECTION = get_input_value('_section', RCUBE_INPUT_POST); - +$CURR_SECTION = rcube_utils::get_input_value('_section', rcube_utils::INPUT_POST); $a_user_prefs = array(); // set options for specified section -switch ($CURR_SECTION) -{ - case 'general': +switch ($CURR_SECTION) { +case 'general': $a_user_prefs = array( - 'language' => isset($_POST['_language']) ? get_input_value('_language', RCUBE_INPUT_POST) : $CONFIG['language'], - 'timezone' => isset($_POST['_timezone']) ? get_input_value('_timezone', RCUBE_INPUT_POST) : $CONFIG['timezone'], - 'date_format' => isset($_POST['_date_format']) ? get_input_value('_date_format', RCUBE_INPUT_POST) : $CONFIG['date_format'], - 'time_format' => isset($_POST['_time_format']) ? get_input_value('_time_format', RCUBE_INPUT_POST) : ($CONFIG['time_format'] ? $CONFIG['time_format'] : 'H:i'), - 'prettydate' => isset($_POST['_pretty_date']) ? TRUE : FALSE, - 'refresh_interval' => isset($_POST['_refresh_interval']) ? intval($_POST['_refresh_interval'])*60 : $CONFIG['refresh_interval'], - 'standard_windows' => isset($_POST['_standard_windows']) ? TRUE : FALSE, - 'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'], + 'language' => isset($_POST['_language']) ? rcube_utils::get_input_value('_language', rcube_utils::INPUT_POST) : $CONFIG['language'], + 'timezone' => isset($_POST['_timezone']) ? rcube_utils::get_input_value('_timezone', rcube_utils::INPUT_POST) : $CONFIG['timezone'], + 'date_format' => isset($_POST['_date_format']) ? rcube_utils::get_input_value('_date_format', rcube_utils::INPUT_POST) : $CONFIG['date_format'], + 'time_format' => isset($_POST['_time_format']) ? rcube_utils::get_input_value('_time_format', rcube_utils::INPUT_POST) : ($CONFIG['time_format'] ? $CONFIG['time_format'] : 'H:i'), + 'prettydate' => isset($_POST['_pretty_date']) ? true : false, + 'refresh_interval' => isset($_POST['_refresh_interval']) ? intval($_POST['_refresh_interval'])*60 : $CONFIG['refresh_interval'], + 'standard_windows' => isset($_POST['_standard_windows']) ? true : false, + 'skin' => isset($_POST['_skin']) ? rcube_utils::get_input_value('_skin', rcube_utils::INPUT_POST) : $CONFIG['skin'], ); // compose derived date/time format strings if ((isset($_POST['_date_format']) || isset($_POST['_time_format'])) && $a_user_prefs['date_format'] && $a_user_prefs['time_format']) { - $a_user_prefs['date_short'] = 'D ' . $a_user_prefs['time_format']; - $a_user_prefs['date_long'] = $a_user_prefs['date_format'] . ' ' . $a_user_prefs['time_format']; + $a_user_prefs['date_short'] = 'D ' . $a_user_prefs['time_format']; + $a_user_prefs['date_long'] = $a_user_prefs['date_format'] . ' ' . $a_user_prefs['time_format']; } - break; + break; - case 'mailbox': +case 'mailbox': $a_user_prefs = array( - 'preview_pane' => isset($_POST['_preview_pane']) ? TRUE : FALSE, - 'preview_pane_mark_read' => isset($_POST['_preview_pane_mark_read']) ? intval($_POST['_preview_pane_mark_read']) : $CONFIG['preview_pane_mark_read'], - 'autoexpand_threads' => isset($_POST['_autoexpand_threads']) ? intval($_POST['_autoexpand_threads']) : 0, - 'mdn_requests' => isset($_POST['_mdn_requests']) ? intval($_POST['_mdn_requests']) : 0, - 'check_all_folders' => isset($_POST['_check_all_folders']) ? TRUE : FALSE, - 'mail_pagesize' => is_numeric($_POST['_mail_pagesize']) ? max(2, intval($_POST['_mail_pagesize'])) : $CONFIG['mail_pagesize'], + 'preview_pane' => isset($_POST['_preview_pane']) ? true : false, + 'preview_pane_mark_read' => isset($_POST['_preview_pane_mark_read']) ? intval($_POST['_preview_pane_mark_read']) : $CONFIG['preview_pane_mark_read'], + 'autoexpand_threads' => isset($_POST['_autoexpand_threads']) ? intval($_POST['_autoexpand_threads']) : 0, + 'mdn_requests' => isset($_POST['_mdn_requests']) ? intval($_POST['_mdn_requests']) : 0, + 'check_all_folders' => isset($_POST['_check_all_folders']) ? true : false, + 'mail_pagesize' => is_numeric($_POST['_mail_pagesize']) ? max(2, intval($_POST['_mail_pagesize'])) : $CONFIG['mail_pagesize'], ); - break; + break; - case 'mailview': +case 'mailview': $a_user_prefs = array( - 'message_extwin' => intval($_POST['_message_extwin']), - 'message_show_email' => isset($_POST['_message_show_email']) ? TRUE : FALSE, - 'prefer_html' => isset($_POST['_prefer_html']) ? TRUE : FALSE, - 'inline_images' => isset($_POST['_inline_images']) ? TRUE : FALSE, - 'show_images' => isset($_POST['_show_images']) ? intval($_POST['_show_images']) : 0, - 'display_next' => isset($_POST['_display_next']) ? TRUE : FALSE, - 'default_charset' => get_input_value('_default_charset', RCUBE_INPUT_POST), + 'message_extwin' => intval($_POST['_message_extwin']), + 'message_show_email' => isset($_POST['_message_show_email']) ? true : false, + 'prefer_html' => isset($_POST['_prefer_html']) ? true : false, + 'inline_images' => isset($_POST['_inline_images']) ? true : false, + 'show_images' => isset($_POST['_show_images']) ? intval($_POST['_show_images']) : 0, + 'display_next' => isset($_POST['_display_next']) ? true : false, + 'default_charset' => rcube_utils::get_input_value('_default_charset', rcube_utils::INPUT_POST), ); - break; + break; - case 'compose': +case 'compose': $a_user_prefs = array( - 'compose_extwin' => intval($_POST['_compose_extwin']), - 'htmleditor' => intval($_POST['_htmleditor']), - 'draft_autosave' => isset($_POST['_draft_autosave']) ? intval($_POST['_draft_autosave']) : 0, - 'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0, - 'force_7bit' => isset($_POST['_force_7bit']) ? TRUE : FALSE, - 'mdn_default' => isset($_POST['_mdn_default']) ? TRUE : FALSE, - 'dsn_default' => isset($_POST['_dsn_default']) ? TRUE : FALSE, - 'reply_same_folder' => isset($_POST['_reply_same_folder']) ? TRUE : FALSE, - 'spellcheck_before_send' => isset($_POST['_spellcheck_before_send']) ? TRUE : FALSE, - 'spellcheck_ignore_syms' => isset($_POST['_spellcheck_ignore_syms']) ? TRUE : FALSE, - 'spellcheck_ignore_nums' => isset($_POST['_spellcheck_ignore_nums']) ? TRUE : FALSE, - 'spellcheck_ignore_caps' => isset($_POST['_spellcheck_ignore_caps']) ? TRUE : FALSE, - 'show_sig' => isset($_POST['_show_sig']) ? intval($_POST['_show_sig']) : 1, - 'reply_mode' => isset($_POST['_reply_mode']) ? intval($_POST['_reply_mode']) : 0, - 'strip_existing_sig' => isset($_POST['_strip_existing_sig']), - 'default_font' => get_input_value('_default_font', RCUBE_INPUT_POST), - 'default_font_size' => get_input_value('_default_font_size', RCUBE_INPUT_POST), - 'forward_attachment' => !empty($_POST['_forward_attachment']), + 'compose_extwin' => intval($_POST['_compose_extwin']), + 'htmleditor' => intval($_POST['_htmleditor']), + 'draft_autosave' => isset($_POST['_draft_autosave']) ? intval($_POST['_draft_autosave']) : 0, + 'mime_param_folding' => isset($_POST['_mime_param_folding']) ? intval($_POST['_mime_param_folding']) : 0, + 'force_7bit' => isset($_POST['_force_7bit']) ? true : false, + 'mdn_default' => isset($_POST['_mdn_default']) ? true : false, + 'dsn_default' => isset($_POST['_dsn_default']) ? true : false, + 'reply_same_folder' => isset($_POST['_reply_same_folder']) ? true : false, + 'spellcheck_before_send' => isset($_POST['_spellcheck_before_send']) ? true : false, + 'spellcheck_ignore_syms' => isset($_POST['_spellcheck_ignore_syms']) ? true : false, + 'spellcheck_ignore_nums' => isset($_POST['_spellcheck_ignore_nums']) ? true : false, + 'spellcheck_ignore_caps' => isset($_POST['_spellcheck_ignore_caps']) ? true : false, + 'show_sig' => isset($_POST['_show_sig']) ? intval($_POST['_show_sig']) : 1, + 'reply_mode' => isset($_POST['_reply_mode']) ? intval($_POST['_reply_mode']) : 0, + 'strip_existing_sig' => isset($_POST['_strip_existing_sig']), + 'default_font' => rcube_utils::get_input_value('_default_font', rcube_utils::INPUT_POST), + 'default_font_size' => rcube_utils::get_input_value('_default_font_size', rcube_utils::INPUT_POST), + 'reply_all_mode' => intval($_POST['_reply_all_mode']), + 'forward_attachment' => !empty($_POST['_forward_attachment']), ); - break; + break; - case 'addressbook': +case 'addressbook': $a_user_prefs = array( - 'default_addressbook' => get_input_value('_default_addressbook', RCUBE_INPUT_POST, true), - 'autocomplete_single' => isset($_POST['_autocomplete_single']) ? TRUE : FALSE, - 'addressbook_sort_col' => get_input_value('_addressbook_sort_col', RCUBE_INPUT_POST), - 'addressbook_name_listing' => intval(get_input_value('_addressbook_name_listing', RCUBE_INPUT_POST)), - 'addressbook_pagesize' => is_numeric($_POST['_addressbook_pagesize']) ? max(2, intval($_POST['_addressbook_pagesize'])) : $CONFIG['addressbook_pagesize'], + 'default_addressbook' => rcube_utils::get_input_value('_default_addressbook', rcube_utils::INPUT_POST, true), + 'autocomplete_single' => isset($_POST['_autocomplete_single']) ? true : false, + 'addressbook_sort_col' => rcube_utils::get_input_value('_addressbook_sort_col', rcube_utils::INPUT_POST), + 'addressbook_name_listing' => intval(rcube_utils::get_input_value('_addressbook_name_listing', rcube_utils::INPUT_POST)), + 'addressbook_pagesize' => is_numeric($_POST['_addressbook_pagesize']) ? max(2, intval($_POST['_addressbook_pagesize'])) : $CONFIG['addressbook_pagesize'], ); - break; + break; - case 'server': +case 'server': $a_user_prefs = array( - 'read_when_deleted' => isset($_POST['_read_when_deleted']) ? TRUE : FALSE, - 'skip_deleted' => isset($_POST['_skip_deleted']) ? TRUE : FALSE, - 'flag_for_deletion' => isset($_POST['_flag_for_deletion']) ? TRUE : FALSE, - 'delete_always' => isset($_POST['_delete_always']) ? TRUE : FALSE, - 'delete_junk' => isset($_POST['_delete_junk']) ? TRUE : FALSE, - 'logout_purge' => isset($_POST['_logout_purge']) ? TRUE : FALSE, - 'logout_expunge' => isset($_POST['_logout_expunge']) ? TRUE : FALSE, + 'read_when_deleted' => isset($_POST['_read_when_deleted']) ? true : false, + 'skip_deleted' => isset($_POST['_skip_deleted']) ? true : false, + 'flag_for_deletion' => isset($_POST['_flag_for_deletion']) ? true : false, + 'delete_always' => isset($_POST['_delete_always']) ? true : false, + 'delete_junk' => isset($_POST['_delete_junk']) ? true : false, + 'logout_purge' => isset($_POST['_logout_purge']) ? true : false, + 'logout_expunge' => isset($_POST['_logout_expunge']) ? true : false, ); - break; + break; - case 'folders': +case 'folders': $a_user_prefs = array( - 'show_real_foldernames' => - isset($_POST['_show_real_foldernames']) ? TRUE : FALSE, - 'drafts_mbox' => get_input_value('_drafts_mbox', RCUBE_INPUT_POST, true), - 'sent_mbox' => get_input_value('_sent_mbox', RCUBE_INPUT_POST, true), - 'junk_mbox' => get_input_value('_junk_mbox', RCUBE_INPUT_POST, true), - 'trash_mbox' => get_input_value('_trash_mbox', RCUBE_INPUT_POST, true), + 'show_real_foldernames' => isset($_POST['_show_real_foldernames']) ? true : false, + 'drafts_mbox' => rcube_utils::get_input_value('_drafts_mbox', rcube_utils::INPUT_POST, true), + 'sent_mbox' => rcube_utils::get_input_value('_sent_mbox', rcube_utils::INPUT_POST, true), + 'junk_mbox' => rcube_utils::get_input_value('_junk_mbox', rcube_utils::INPUT_POST, true), + 'trash_mbox' => rcube_utils::get_input_value('_trash_mbox', rcube_utils::INPUT_POST, true), ); - break; + break; } $plugin = rcmail::get_instance()->plugins->exec_hook('preferences_save', - array('prefs' => $a_user_prefs, 'section' => $CURR_SECTION)); + array('prefs' => $a_user_prefs, 'section' => $CURR_SECTION)); $a_user_prefs = $plugin['prefs']; // don't override these parameters -foreach ((array)$CONFIG['dont_override'] as $p) - $a_user_prefs[$p] = $CONFIG[$p]; +foreach ((array)$CONFIG['dont_override'] as $p) { + $a_user_prefs[$p] = $CONFIG[$p]; +} // verify some options -switch ($CURR_SECTION) -{ - case 'general': - +switch ($CURR_SECTION) { +case 'general': // switch UI language if (isset($_POST['_language']) && $a_user_prefs['language'] != $_SESSION['language']) { - $RCMAIL->load_language($a_user_prefs['language']); - $OUTPUT->command('reload', 500); + $RCMAIL->load_language($a_user_prefs['language']); + $OUTPUT->command('reload', 500); } // switch skin (if valid, otherwise unset the pref and fall back to default) if (!$OUTPUT->set_skin($a_user_prefs['skin'])) - unset($a_user_prefs['skin']); + unset($a_user_prefs['skin']); else if ($RCMAIL->config->get('skin') != $a_user_prefs['skin']) - $OUTPUT->command('reload', 500); + $OUTPUT->command('reload', 500); $a_user_prefs['timezone'] = (string) $a_user_prefs['timezone']; if (!empty($a_user_prefs['refresh_interval']) && !empty($CONFIG['min_refresh_interval'])) { - if ($a_user_prefs['refresh_interval'] < $CONFIG['min_refresh_interval']) { - $a_user_prefs['refresh_interval'] = $CONFIG['min_refresh_interval']; - } + if ($a_user_prefs['refresh_interval'] < $CONFIG['min_refresh_interval']) { + $a_user_prefs['refresh_interval'] = $CONFIG['min_refresh_interval']; + } } break; - case 'mailbox': - +case 'mailbox': // force min size - if ($a_user_prefs['mail_pagesize'] < 1) - $a_user_prefs['mail_pagesize'] = 10; + if ($a_user_prefs['mail_pagesize'] < 1) { + $a_user_prefs['mail_pagesize'] = 10; + } - if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['mail_pagesize'] > $CONFIG['max_pagesize'])) - $a_user_prefs['mail_pagesize'] = (int) $CONFIG['max_pagesize']; + if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['mail_pagesize'] > $CONFIG['max_pagesize'])) { + $a_user_prefs['mail_pagesize'] = (int) $CONFIG['max_pagesize']; + } break; - case 'addressbook': - +case 'addressbook': // force min size - if ($a_user_prefs['addressbook_pagesize'] < 1) - $a_user_prefs['addressbook_pagesize'] = 10; + if ($a_user_prefs['addressbook_pagesize'] < 1) { + $a_user_prefs['addressbook_pagesize'] = 10; + } - if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['addressbook_pagesize'] > $CONFIG['max_pagesize'])) - $a_user_prefs['addressbook_pagesize'] = (int) $CONFIG['max_pagesize']; + if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['addressbook_pagesize'] > $CONFIG['max_pagesize'])) { + $a_user_prefs['addressbook_pagesize'] = (int) $CONFIG['max_pagesize']; + } break; - case 'folders': - +case 'folders': // special handling for 'default_folders' if (in_array('default_folders', (array)$CONFIG['dont_override'])) { - foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) - $a_user_prefs[$p] = $CONFIG[$p]; - } else { - $a_user_prefs['default_folders'] = array('INBOX'); - foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) { - if ($a_user_prefs[$p]) - $a_user_prefs['default_folders'][] = $a_user_prefs[$p]; - } + foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) { + $a_user_prefs[$p] = $CONFIG[$p]; + } + } + else { + $a_user_prefs['default_folders'] = array('INBOX'); + foreach (array('drafts_mbox','sent_mbox','junk_mbox','trash_mbox') as $p) { + if ($a_user_prefs[$p]) { + $a_user_prefs['default_folders'][] = $a_user_prefs[$p]; + } + } } break; @@ -210,15 +211,14 @@ switch ($CURR_SECTION) // Save preferences if (!$plugin['abort']) - $saved = $RCMAIL->user->save_prefs($a_user_prefs); + $saved = $RCMAIL->user->save_prefs($a_user_prefs); else - $saved = $plugin['result']; + $saved = $plugin['result']; if ($saved) - $OUTPUT->show_message('successfullysaved', 'confirmation'); + $OUTPUT->show_message('successfullysaved', 'confirmation'); else - $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); + $OUTPUT->show_message($plugin['message'] ? $plugin['message'] : 'errorsaving', 'error'); // display the form again -rcmail_overwrite_action('edit-prefs'); - +$RCMAIL->overwrite_action('edit-prefs'); diff --git a/program/steps/utils/error.inc b/program/steps/utils/error.inc index 9fb71c528..2a3a9a61e 100644 --- a/program/steps/utils/error.inc +++ b/program/steps/utils/error.inc @@ -5,7 +5,7 @@ | program/steps/utils/error.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2012, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -22,10 +22,10 @@ $rcmail = rcmail::get_instance(); // browser is not compatible with this application -if ($ERROR_CODE==409) { - $user_agent = htmlentities($_SERVER['HTTP_USER_AGENT']); - $__error_title = 'Your browser does not suit the requirements for this application'; - $__error_text = <<<EOF +if ($ERROR_CODE == 409) { + $user_agent = htmlentities($_SERVER['HTTP_USER_AGENT']); + $__error_title = 'Your browser does not suit the requirements for this application'; + $__error_text = <<<EOF <i>Supported browsers:</i><br /> » Microsoft Internet Explorer 7+<br /> » Mozilla Firefox 3+<br /> @@ -42,24 +42,24 @@ EOF; } // authorization error -else if ($ERROR_CODE==401) { - $__error_title = "AUTHORIZATION FAILED"; - $__error_text = "Could not verify that you are authorized to access this service!<br />\n". - "Please contact your server-administrator."; +else if ($ERROR_CODE == 401) { + $__error_title = "AUTHORIZATION FAILED"; + $__error_text = "Could not verify that you are authorized to access this service!<br />\n" + . "Please contact your server-administrator."; } // forbidden due to request check -else if ($ERROR_CODE==403) { - $__error_title = "REQUEST CHECK FAILED"; - $__error_text = "Access to this service was denied due to failing security checks!<br />\n". - "Please contact your server-administrator."; +else if ($ERROR_CODE == 403) { + $__error_title = "REQUEST CHECK FAILED"; + $__error_text = "Access to this service was denied due to failing security checks!<br />\n" + . "Please contact your server-administrator."; } // failed request (wrong step in URL) -else if ($ERROR_CODE==404) { - $__error_title = "REQUEST FAILED/FILE NOT FOUND"; - $request_url = htmlentities($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); - $__error_text = <<<EOF +else if ($ERROR_CODE == 404) { + $request_url = htmlentities($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']); + $__error_title = "REQUEST FAILED/FILE NOT FOUND"; + $__error_text = <<<EOF The requested page was not found!<br /> Please contact your server-administrator. @@ -69,35 +69,36 @@ EOF; } // database connection error -else if ($ERROR_CODE==601) -{ - $__error_title = "CONFIGURATION ERROR"; - $__error_text = nl2br($ERROR_MESSAGE) . "<br />Please read the INSTALL instructions!"; +else if ($ERROR_CODE == 601) { + $__error_title = "CONFIGURATION ERROR"; + $__error_text = nl2br($ERROR_MESSAGE) . "<br />Please read the INSTALL instructions!"; } // database connection error -else if ($ERROR_CODE==603) { - $__error_title = "DATABASE ERROR: CONNECTION FAILED!"; - $__error_text = "Unable to connect to the database!<br />Please contact your server-administrator."; +else if ($ERROR_CODE == 603) { + $__error_title = "DATABASE ERROR: CONNECTION FAILED!"; + $__error_text = "Unable to connect to the database!<br />Please contact your server-administrator."; } // system error else { - $__error_title = "SERVICE CURRENTLY NOT AVAILABLE!"; - $__error_text = "Please contact your server-administrator."; - - if (($rcmail->config->get('debug_level') & 4) && $ERROR_MESSAGE) - $__error_text = $ERROR_MESSAGE; - else - $__error_text = sprintf('Error No. [%s]', $ERROR_CODE); + $__error_title = "SERVICE CURRENTLY NOT AVAILABLE!"; + $__error_text = "Please contact your server-administrator."; + + if (($rcmail->config->get('debug_level') & 4) && $ERROR_MESSAGE) { + $__error_text = $ERROR_MESSAGE; + } + else { + $__error_text = sprintf('Error No. [%s]', $ERROR_CODE); + } } $HTTP_ERR_CODE = $ERROR_CODE && $ERROR_CODE < 600 ? $ERROR_CODE : 500; // Ajax request if ($rcmail->output && $rcmail->output->type == 'js') { - header("HTTP/1.0 $HTTP_ERR_CODE $__error_title"); - die; + header("HTTP/1.0 $HTTP_ERR_CODE $__error_title"); + die; } // compose page content @@ -109,8 +110,9 @@ $__page_content = <<<EOF EOF; if ($rcmail->output && $rcmail->output->template_exists('error')) { - $rcmail->output->reset(); - $rcmail->output->send('error'); + $rcmail->output->reset(); + $rcmail->output->set_env('server_error', $ERROR_CODE); + $rcmail->output->send('error'); } $__skin = $rcmail->config->get('skin', 'default'); @@ -136,4 +138,3 @@ $__page_content EOF; exit; - diff --git a/program/steps/utils/html2text.inc b/program/steps/utils/html2text.inc index c6481b197..c01443b22 100644 --- a/program/steps/utils/html2text.inc +++ b/program/steps/utils/html2text.inc @@ -22,7 +22,7 @@ $html = $HTTP_RAW_POST_DATA; // Replace emoticon images with its text representation -$html = rcmail_replace_emoticons($html); +$html = $RCMAIL->replace_emoticons($html); $converter = new rcube_html2text($html, false, true, 0); diff --git a/program/steps/utils/modcss.inc b/program/steps/utils/modcss.inc index 1a28c6598..c8a7cb524 100644 --- a/program/steps/utils/modcss.inc +++ b/program/steps/utils/modcss.inc @@ -55,7 +55,7 @@ $ctype = '~Content-Type:\s+text/(css|plain)~i'; if ($source !== false && preg_match($ctype, $headers)) { header('Content-Type: text/css'); - echo rcmail_mod_css_styles($source, preg_replace('/[^a-z0-9]/i', '', $_GET['_c'])); + echo rcube_utils::mod_css_styles($source, preg_replace('/[^a-z0-9]/i', '', $_GET['_c'])); exit; } diff --git a/program/steps/utils/save_pref.inc b/program/steps/utils/save_pref.inc index 7def8733d..183c398d3 100644 --- a/program/steps/utils/save_pref.inc +++ b/program/steps/utils/save_pref.inc @@ -5,7 +5,7 @@ | program/steps/utils/save_pref.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2010, The Roundcube Dev Team | + | Copyright (C) 2005-2013, The Roundcube Dev Team | | | | Licensed under the GNU General Public License version 3 or | | any later version with exceptions for skins & plugins. | @@ -19,17 +19,27 @@ +-----------------------------------------------------------------------+ */ -$name = get_input_value('_name', RCUBE_INPUT_POST); -$value = get_input_value('_value', RCUBE_INPUT_POST); +$name = rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST); +$value = rcube_utils::get_input_value('_value', rcube_utils::INPUT_POST); +$sessname = rcube_utils::get_input_value('_session', rcube_utils::INPUT_POST); + +// Whitelisted preferences and session variables, others +// can be added by plugins $whitelist = array( 'preview_pane', 'list_cols', 'collapsed_folders', 'collapsed_abooks', ); +$whitelist_sess = array( + 'list_attrib/columns', +); + +$whitelist = array_merge($whitelist, $RCMAIL->plugins->allowed_prefs); +$whitelist_sess = array_merge($whitelist_sess, $RCMAIL->plugins->allowed_session_prefs); -if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs))) { - raise_error(array('code' => 500, 'type' => 'php', +if (!in_array($name, $whitelist) || ($sessname && !in_array($sessname, $whitelist_sess))) { + rcube::raise_error(array('code' => 500, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => sprintf("Hack attempt detected (user: %s)", $RCMAIL->get_user_name())), true, false); @@ -42,7 +52,7 @@ if (!in_array($name, array_merge($whitelist, $RCMAIL->plugins->allowed_prefs))) $RCMAIL->user->save_prefs(array($name => $value)); // update also session if requested -if ($sessname = get_input_value('_session', RCUBE_INPUT_POST)) { +if ($sessname) { // Support multidimensional arrays... $vars = explode('/', $sessname); @@ -57,5 +67,3 @@ if ($sessname = get_input_value('_session', RCUBE_INPUT_POST)) { $OUTPUT->reset(); $OUTPUT->send(); - - diff --git a/program/steps/utils/spell.inc b/program/steps/utils/spell.inc index 1c68e8328..c8807e32f 100644 --- a/program/steps/utils/spell.inc +++ b/program/steps/utils/spell.inc @@ -20,7 +20,7 @@ */ // read input -$lang = get_input_value('lang', RCUBE_INPUT_GET); +$lang = rcube_utils::get_input_value('lang', rcube_utils::INPUT_GET); $data = file_get_contents('php://input'); $learn_word = strpos($data, '<learnword>'); @@ -29,13 +29,13 @@ $learn_word = strpos($data, '<learnword>'); $left = strpos($data, '<text>'); $right = strrpos($data, '</text>'); $data = substr($data, $left+6, $right-($left+6)); -$data = html_entity_decode($data, ENT_QUOTES, RCMAIL_CHARSET); +$data = html_entity_decode($data, ENT_QUOTES, RCUBE_CHARSET); $spellchecker = new rcube_spellchecker($lang); if ($learn_word) { $spellchecker->add_word($data); - $result = '<?xml version="1.0" encoding="'.RCMAIL_CHARSET.'"?><learnwordresult></learnwordresult>'; + $result = '<?xml version="1.0" encoding="'.RCUBE_CHARSET.'"?><learnwordresult></learnwordresult>'; } else { $spellchecker->check($data); @@ -47,12 +47,15 @@ if ($err = $spellchecker->error()) { 'file' => __FILE__, 'line' => __LINE__, 'message' => "Spell check engine error: " . trim($err)), true, false); + + header("HTTP/1.0 500 Internal Server Error"); + exit; } // set response length header("Content-Length: " . strlen($result)); // Don't use server's default Content-Type charset (#1486406) -header("Content-Type: text/xml; charset=" . RCMAIL_CHARSET); +header("Content-Type: text/xml; charset=" . RCUBE_CHARSET); print $result; exit; diff --git a/program/steps/utils/spell_html.inc b/program/steps/utils/spell_html.inc index 96b41e230..27b14acef 100644 --- a/program/steps/utils/spell_html.inc +++ b/program/steps/utils/spell_html.inc @@ -56,7 +56,7 @@ if ($error = $spellchecker->error()) { } // send output -header("Content-Type: text/xml; charset=".RCMAIL_CHARSET); +header("Content-Type: text/xml; charset=".RCUBE_CHARSET); echo json_encode($result); exit; |