Merge branch 'master' into dev/elastic

pull/5578/merge
Aleksander Machniak 6 years ago
commit 13ad9e6593

@ -57,6 +57,7 @@ CHANGELOG Roundcube Webmail
- Reset onerror on images if placeholder does not exist to prevent from requests storm
- Unified and simplified code for loading content frame for responses and identities
- Display contact import and advanced search in popup dialogs
- Display a dialog for mail import with supported format description and upload size hint
- Make possible to set (some) config options from a skin
- Added optional checkbox selection for the list widget
- Make 'compose' command always enabled
@ -66,6 +67,7 @@ CHANGELOG Roundcube Webmail
- Plugin API: Added 'show_bytes' hook (#5001)
- Add option to not indent quoted text on top-posting reply (#5105)
- Removed global $CONFIG variable
- Removed debug_level setting
- Support AUTHENTICATE LOGIN for IMAP connections (#5563)
- Support LDAP GSSAPI authentication (#5703)
- Localized timezone selector (#4983)
@ -88,6 +90,7 @@ CHANGELOG Roundcube Webmail
- Fix bug where some parts of quota information could have been ignored (#6280)
- Fix bug where some escape sequences in html styles could bypass security checks
- Fix bug where some forbidden characters on Cyrus-IMAP were not prevented from use in folder names
- Fix bug where only attachments with the same name would be ignored on zip download (#6301)
RELEASE 1.3.6
-------------

@ -76,7 +76,9 @@ and configure your installation to be not surprised by default behaviour.
Roundcube writes internal errors to the 'errors' log file located in the logs
directory which can be configured in config/config.inc.php. If you want ordinary
PHP errors to be logged there as well, set error_log php.ini or .htaccess file.
PHP errors to be logged there as well, set error_log in php.ini or .htaccess file.
Roundcube forces display_errors=Off and log_errors=On.
By default the session cookie settings of PHP are not modified by Roundcube.
However if you want to limit the session cookies to the directory where

@ -63,9 +63,6 @@ $config['db_max_allowed_packet'] = null;
// LOGGING/DEBUGGING
// ----------------------------------
// system error reporting, sum of: 1 = log; 4 = show
$config['debug_level'] = 1;
// log driver: 'syslog', 'stdout' or 'file'.
$config['log_driver'] = 'file';

@ -11,7 +11,6 @@ $RCI->bool_config_props = array(
'auto_create_user' => 1,
'smtp_log' => 1,
'prefer_html' => 1,
'debug_level' => 1,
);
// allow the current user to get to the next step
@ -196,21 +195,6 @@ echo $input_ilevel->show($RCI->getprop('identities_level'), 0);
<legend>Logging & Debugging</legend>
<dl class="loggingblock">
<dt class="propname">debug_level</dt>
<dd>
<?php
$value = $RCI->getprop('debug_level');
$check_debug = new html_checkbox(array('name' => '_debug_level[]'));
echo $check_debug->show(($value & 1) ? 1 : 0 , array('value' => 1, 'id' => 'cfgdebug1'));
echo '<label for="cfgdebug1">Log errors</label><br />';
echo $check_debug->show(($value & 4) ? 4 : 0, array('value' => 4, 'id' => 'cfgdebug4'));
echo '<label for="cfgdebug4">Print errors (to the browser)</label><br />';
?>
</dd>
<dt class="propname">log_driver</dt>
<dd>
<?php

@ -1508,8 +1508,10 @@ class rcube_sieve_engine
$out .= sprintf("\n" . '<div class="form-group row">'
. '<label for="%s" class="col-sm-4 col-form-label">%s</label>'
. '<div class="col-sm-8">%s</div></div>',
$field_id, rcube::Q($this->plugin->gettext('filterset')),
$this->filtersets_list(array('id' => 'sievescriptname'), true));
'sievescriptname',
rcube::Q($this->plugin->gettext('filterset')),
$this->filtersets_list(array('id' => 'sievescriptname'), true)
);
}
else if ($compact) {
$out .= sprintf("\n" . '<div class="form-group row form-check">'
@ -2396,9 +2398,10 @@ class rcube_sieve_engine
// mailbox select
if ($action['type'] == 'fileinto') {
$mailbox = $this->mod_mailbox($action['target'], 'out');
// make sure non-existing (or unsubscribed) mailbox is listed (#1489956)
$additional = array($mailbox);
if ($mailbox = $this->mod_mailbox($action['target'], 'out')) {
$additional = array($mailbox);
}
}
else {
$mailbox = '';

@ -17,7 +17,7 @@ class zipdownload extends rcube_plugin
public $task = 'mail';
private $charset = 'ASCII';
private $names = [];
private $names = array();
private $default_limit = '50MB';
// RFC4155: mbox date format
@ -213,7 +213,7 @@ class zipdownload extends rcube_plugin
* Adding a number before dot of extension on a name of file with same name on zip
* Ext: attach(1).txt on attach filename that has a attach.txt filename on same zip
*/
if (isset($this->name[$displayname])) {
if (isset($this->names[$displayname])) {
list($filename, $ext) = preg_split("/\.(?=[^\.]*$)/", $displayname);
$displayname = $filename . '(' . ($this->names[$displayname]++) . ').' . $ext;
$this->names[$displayname] = 1;

@ -206,16 +206,7 @@ class rcmail_install
}
// convert some form data
if ($prop == 'debug_level' && !$is_default) {
if (is_array($value)) {
$val = 0;
foreach ($value as $dbgval) {
$val += intval($dbgval);
}
$value = $val;
}
}
else if ($prop == 'db_dsnw' && !empty($_POST['_dbtype'])) {
if ($prop == 'db_dsnw' && !empty($_POST['_dbtype'])) {
if ($_POST['_dbtype'] == 'sqlite') {
$value = sprintf('%s://%s?mode=0646', $_POST['_dbtype'],
$_POST['_dbname']{0} == '/' ? '/' . $_POST['_dbname'] : $_POST['_dbname']);

@ -1430,7 +1430,13 @@ function rcube_webmail()
ret = false;
this.triggerEvent('actionafter', { props:props, action:command, aborted:aborted, ret:ret, originalEvent:event});
return ret === false ? false : obj ? false : true;
if (ret === false)
return false;
if (obj || aborted === true)
return false;
return true;
};
// set command(s) enabled or disabled

@ -1352,7 +1352,7 @@ class rcube
}
/**
* Report error according to configured debug_level
* Log an error
*
* @param array $arg_arr Named parameters
* @see self::raise_error()
@ -1360,58 +1360,31 @@ class rcube
public static function log_bug($arg_arr)
{
$program = strtoupper($arg_arr['type'] ?: 'php');
$level = self::get_instance()->config->get('debug_level');
// disable errors for ajax requests, write to log instead (#1487831)
if (($level & 4) && !empty($_REQUEST['_remote'])) {
$level = ($level ^ 4) | 1;
}
// write error to local log file
if (($level & 1) || !empty($arg_arr['fatal'])) {
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
foreach (array('_task', '_action') as $arg) {
if ($_POST[$arg] && !$_GET[$arg]) {
$post_query[$arg] = $_POST[$arg];
}
}
if (!empty($post_query)) {
$post_query = (strpos($_SERVER['REQUEST_URI'], '?') != false ? '&' : '?')
. http_build_query($post_query, '', '&');
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
foreach (array('_task', '_action') as $arg) {
if ($_POST[$arg] && !$_GET[$arg]) {
$post_query[$arg] = $_POST[$arg];
}
}
$log_entry = sprintf("%s Error: %s%s (%s %s)",
$program,
$arg_arr['message'],
$arg_arr['file'] ? sprintf(' in %s on line %d', $arg_arr['file'], $arg_arr['line']) : '',
$_SERVER['REQUEST_METHOD'],
$_SERVER['REQUEST_URI'] . $post_query);
if (!self::write_log('errors', $log_entry)) {
// send error to PHPs error handler if write_log didn't succeed
trigger_error($arg_arr['message'], E_USER_WARNING);
if (!empty($post_query)) {
$post_query = (strpos($_SERVER['REQUEST_URI'], '?') != false ? '&' : '?')
. http_build_query($post_query, '', '&');
}
}
// report the bug to the global bug reporting system
if ($level & 2) {
// TODO: Send error via HTTP
}
// show error if debug_mode is on
if ($level & 4) {
print "<b>$program Error";
if (!empty($arg_arr['file']) && !empty($arg_arr['line'])) {
print " in $arg_arr[file] ($arg_arr[line])";
}
$log_entry = sprintf("%s Error: %s%s (%s %s)",
$program,
$arg_arr['message'],
$arg_arr['file'] ? sprintf(' in %s on line %d', $arg_arr['file'], $arg_arr['line']) : '',
$_SERVER['REQUEST_METHOD'],
$_SERVER['REQUEST_URI'] . $post_query);
print ':</b>&nbsp;';
print nl2br($arg_arr['message']);
print '<br />';
flush();
if (!self::write_log('errors', $log_entry)) {
// send error to PHPs error handler if write_log didn't succeed
trigger_error($arg_arr['message'], E_USER_WARNING);
}
}

@ -245,20 +245,14 @@ class rcube_config
}
// set PHP error logging according to config
if ($this->prop['debug_level'] & 1) {
$error_log = $this->prop['log_driver'];
if ($error_log != 'syslog') {
$error_log = $this->prop['log_dir'] . '/errors';
$error_log .= isset($this->prop['log_file_ext']) ? $this->prop['log_file_ext'] : '.log';
}
$error_log = $this->prop['log_driver'];
if ($error_log != 'syslog') {
$error_log = $this->prop['log_dir'] . '/errors';
$error_log .= isset($this->prop['log_file_ext']) ? $this->prop['log_file_ext'] : '.log';
ini_set('error_log', $error_log);
ini_set('log_errors', 1);
}
// enable display_errors in 'show' level, but not for ajax requests
ini_set('display_errors', intval(empty($_REQUEST['_remote']) && ($this->prop['debug_level'] & 4)));
// remove deprecated properties
unset($this->prop['dst_active']);
}

@ -224,6 +224,8 @@ $labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
$labels['importmessages'] = 'Import messages';
$labels['mailimportdesc'] = 'You can upload mail using files in <a href="https://en.wikipedia.org/wiki/Email#Message_format">MIME</a> or <a href="https://en.wikipedia.org/wiki/Mbox">Mbox</a> format.';
$labels['mailimportzip'] = 'Multiple files can be compressed into zip archives.';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@ -481,7 +483,7 @@ $labels['importreplace'] = 'Replace the entire address book';
$labels['importgroups'] = 'Import group assignments';
$labels['importgroupsall'] = 'All (create groups if necessary)';
$labels['importgroupsexisting'] = 'Only for existing groups';
$labels['importdesc'] = 'You can upload contacts from an existing address book.<br/>We currently support importing addresses from the <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> or CSV (comma-separated) data format.';
$labels['importdesc'] = 'You can upload contacts from an existing address book.<br/>We currently support importing addresses from the <a href="https://en.wikipedia.org/wiki/VCard">vCard</a> or CSV (comma-separated) data format.';
$labels['done'] = 'Done';
// settings

@ -203,6 +203,7 @@ function rcmail_import_form($attrib)
$attrib += array('id' => "rcmImportForm");
$writable_books = $RCMAIL->get_address_sources(true, true);
$max_filesize = $RCMAIL->upload_init();
$form = '';
$table = new html_table(array('cols' => 2));
@ -216,7 +217,9 @@ function rcmail_import_form($attrib)
));
$table->add('title', html::label('rcmimportfile', $RCMAIL->gettext('importfromfile')));
$table->add(null, $upload->show());
$table->add(null, $upload->show()
. html::div('hint', $RCMAIL->gettext(array('id' => 'importfile', 'name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize))))
);
// addressbook selector
if (count($writable_books) > 1) {

@ -1687,16 +1687,23 @@ function rcmail_message_import_form($attrib = array())
{
global $RCMAIL;
$RCMAIL->output->add_label('selectimportfile','importwait');
$RCMAIL->output->add_label('selectimportfile', 'importwait', 'importmessages');
$input_attr = array(
$description = $RCMAIL->gettext('mailimportdesc');
$input_attr = array(
'multiple' => true,
'name' => '_file[]',
'accept' => ".eml, .mbox, message/rfc822, text/*",
'accept' => '.eml, .mbox, .msg, message/rfc822, text/*',
);
if (class_exists('ZipArchive', false)) {
$input_attr['accept'] .= '.zip, application/zip, application/x-zip';
$description .= ' ' . $RCMAIL->gettext('mailimportzip');
}
$attrib['prefix'] = html::tag('input', array('type' => 'hidden', 'name' => '_unlock', 'value' => ''))
. html::tag('input', array('type' => 'hidden', 'name' => '_framed', 'value' => '1'));
. html::tag('input', array('type' => 'hidden', 'name' => '_framed', 'value' => '1'))
. html::p(null, $description);
return $RCMAIL->upload_form($attrib, 'importform', 'import-messages', $input_attr);
}

@ -96,14 +96,7 @@ else if ($ERROR_CODE == 603) {
// 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_text = sprintf('Error No. [%s]', $ERROR_CODE);
}
// inform plugins

@ -92,6 +92,7 @@ input.smart-upload {
td.rowactions {
width: 1%;
.custom-select,
.form-control {
width: auto;
}

@ -63,7 +63,8 @@
<ul class="toolbarmenu listing" role="menu" aria-labelledby="aria-label-message-menu">
<roundcube:button type="link-menuitem" command="print" label="printmessage" class="print" classAct="print active" data-hidden="small"/>
<roundcube:if condition="template:name != 'message'" />
<roundcube:button type="link-menuitem" command="import-messages" label="import" class="import" classAct="import active" name="messageimport" onclick="if (rcmail.command_enabled('import-messages')) rcmail.upload_input('uploadform')" />
<roundcube:button type="link-menuitem" command="import-messages" label="import" class="import" classAct="import active"
name="messageimport" onclick="UI.import_dialog()" />
<roundcube:endif />
<roundcube:button type="link-menuitem" command="download" label="export" class="download" classAct="download active" />
<roundcube:button type="link-menuitem" command="edit" prop="new" label="editasnew" class="edit asnew" classAct="edit asnew active" />
@ -85,3 +86,7 @@
<roundcube:container name="markmenu" id="markmessage-menu" />
</ul>
</div>
<roundcube:if condition="template:name != 'message'" />
<roundcube:object name="messageimportform" id="uploadform" class="popupmenu formcontent" buttons="no" />
<roundcube:endif />

@ -204,6 +204,4 @@
<roundcube:add_label name="listoptionstitle" />
</div>
<roundcube:object name="messageimportform" id="uploadform" mode="smart" />
<roundcube:include file="includes/footer.html" />

@ -59,6 +59,7 @@ function rcube_elastic_ui()
this.popup_init = popup_init;
this.about_dialog = about_dialog;
this.headers_dialog = headers_dialog;
this.import_dialog = import_dialog;
this.headers_show = headers_show;
this.spellmenu = spellmenu;
this.searchmenu = searchmenu;
@ -112,6 +113,10 @@ function rcube_elastic_ui()
// Intercept jQuery-UI dialogs...
$.ui && $.widget('ui.dialog', $.ui.dialog, {
open: function() {
// .. to unify min width for iframe'd dialogs
if ($(this.element).is('.iframe')) {
this.options.width = Math.max(576, this.options.width);
}
this._super();
// ... to re-style them on dialog open
dialog_open(this);
@ -1977,6 +1982,7 @@ function rcube_elastic_ui()
break;
}
}
return false; // prevents from scrolling the whole page
}
});
@ -2267,8 +2273,7 @@ function rcube_elastic_ui()
dialog = rcmail.simple_dialog(dialog, rcmail.gettext('listoptionstitle'), save_func, {
closeOnEscape: true,
minWidth: 400,
width: width
minWidth: 400
});
};
@ -2290,7 +2295,6 @@ function rcube_elastic_ui()
button: support_button,
button_class: 'help',
cancel_button: 'close',
width: 600,
height: 400
});
};
@ -2314,11 +2318,28 @@ function rcube_elastic_ui()
rcmail.simple_dialog(dialog, rcmail.gettext('arialabelmessageheaders'), null, {
cancel_button: 'close',
width: 600,
height: 400
});
};
/**
* Mail import dialog
*/
function import_dialog()
{
var content = $('#uploadform'),
dialog = content.clone();
var save_func = function(e) {
return rcmail.command('import-messages', $(dialog.find('form')[0]));
};
rcmail.simple_dialog(dialog, rcmail.gettext('importmessages'), save_func, {
closeOnEscape: true,
minWidth: 400
});
};
/**
* Search options menu popup
*/
@ -2998,6 +3019,7 @@ function rcube_elastic_ui()
break;
}
}
return false; // prevents from scrolling the whole page
}
});

@ -171,7 +171,7 @@
<roundcube:button command="expunge" type="link-menuitem" label="compact" classAct="active" />
<roundcube:button command="purge" type="link-menuitem" label="empty" classAct="active" />
<roundcube:button command="mark-all-read" type="link-menuitem" label="markallread" classAct="active" />
<roundcube:button command="import-messages" type="link-menuitem" name="messageimport" classAct="active" label="importmessages" onclick="if (rcmail.command_enabled('import-messages')) rcmail.upload_input('uploadform')" />
<roundcube:button command="import-messages" type="link-menuitem" name="messageimport" classAct="active" label="importmessages" onclick="UI.import_dialog()" />
<roundcube:button command="folders" task="settings" type="link-menuitem" label="managefolders" classAct="active" />
<roundcube:container name="mailboxoptions" id="mailboxoptionsmenu" />
</ul>
@ -262,7 +262,7 @@
</div>
</div>
<roundcube:object name="messageimportform" id="uploadform" mode="smart" />
<roundcube:object name="messageimportform" id="uploadform" buttons="no" class="popupdialog" />
<roundcube:include file="/includes/footer.html" />

@ -40,9 +40,9 @@ function rcube_mail_ui()
this.show_popup = show_popup;
this.toggle_popup = toggle_popup;
this.add_popup = add_popup;
this.import_dialog = import_dialog;
this.set_searchmod = set_searchmod;
this.set_searchscope = set_searchscope;
this.show_uploadform = show_uploadform;
this.show_header_row = show_header_row;
this.hide_header_row = hide_header_row;
this.update_quota = update_quota;
@ -181,8 +181,7 @@ function rcube_mail_ui()
}
}
else if (rcmail.env.action == 'compose') {
rcmail.addEventListener('aftersend-attachment', show_uploadform)
.addEventListener('fileappended', function(e) { if (e.attachment.complete) attachmentmenu_append(e.item); })
rcmail.addEventListener('fileappended', function(e) { if (e.attachment.complete) attachmentmenu_append(e.item); })
.addEventListener('aftertoggle-editor', function(e) {
window.setTimeout(function() { layout_composeview() }, 200);
if (e && e.mode)
@ -235,8 +234,7 @@ function rcube_mail_ui()
rcmail.init_pagejumper('#pagejumper');
rcmail.addEventListener('setquota', update_quota)
.addEventListener('layout-change', mail_layout)
.addEventListener('afterimport-messages', show_uploadform);
.addEventListener('layout-change', mail_layout);
}
else if (rcmail.env.action == 'get') {
new rcube_splitter({ id:'mailpartsplitterv', p1:'#messagepartheader', p2:'#messagepartcontainer',
@ -300,8 +298,7 @@ function rcube_mail_ui()
}
/*** addressbook task ***/
else if (rcmail.env.task == 'addressbook') {
rcmail.addEventListener('afterupload-photo', show_uploadform)
.addEventListener('beforepushgroup', push_contactgroup)
rcmail.addEventListener('beforepushgroup', push_contactgroup)
.addEventListener('beforepopgroup', pop_contactgroup)
.addEventListener('menu-open', menu_toggle)
.addEventListener('menu-close', menu_toggle);
@ -1078,63 +1075,24 @@ function rcube_mail_ui()
});
}
function show_uploadform(e)
/**
* Mail import dialog
*/
function import_dialog()
{
var $dialog = $('#upload-dialog');
var content = $('#uploadform'),
dialog = content.clone().removeClass('popupdialog');
// close the dialog
if ($dialog.is(':visible')) {
$dialog.dialog('close');
return;
}
var save_func = function(e) {
return rcmail.command('import-messages', $(dialog.find('form')[0]));
};
// do nothing if mailvelope editor is active
if (rcmail.mailvelope_editor)
return;
// add icons to clone file input field
if (rcmail.env.action == 'compose' && !$dialog.data('extended')) {
$('<a>')
.addClass('iconlink add')
.attr('href', '#add')
.html('Add')
.appendTo($('input[type="file"]', $dialog).parent())
.click(add_uploadfile);
$dialog.data('extended', true);
}
$dialog.dialog({
modal: true,
resizable: false,
rcmail.simple_dialog(dialog, rcmail.gettext('importmessages'), save_func, {
closeOnEscape: true,
title: $dialog.attr('title'),
open: function(e) {
if (!document.all)
$('input[type=file]', $dialog).first().click();
},
close: function() {
try { $('#upload-dialog form').get(0).reset(); }
catch(e){ } // ignore errors
$dialog.dialog('destroy').hide();
$('div.addline', $dialog).remove();
},
width: 480
}).show();
}
function add_uploadfile(e)
{
var div = $(this).parent();
var clone = div.clone().addClass('addline').insertAfter(div);
clone.children('.iconlink').click(add_uploadfile);
clone.children('input').val('');
if (!document.all)
$('input[type=file]', clone).click();
minWidth: 400
});
}
/**
*
*/

Loading…
Cancel
Save