summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG29
-rw-r--r--INSTALL26
-rw-r--r--SQL/sqlite.initial.sql2
-rwxr-xr-xbin/update.sh14
-rw-r--r--config/defaults.inc.php74
-rw-r--r--installer/check.php46
-rw-r--r--installer/rcube_install.php52
-rw-r--r--installer/test.php36
-rw-r--r--plugins/acl/acl.php13
-rw-r--r--plugins/acl/config.inc.php.dist6
-rw-r--r--plugins/acl/localization/et_EE.inc4
-rw-r--r--plugins/acl/localization/gl_ES.inc64
-rw-r--r--plugins/acl/localization/he_IL.inc2
-rw-r--r--plugins/acl/localization/pl_PL.inc2
-rw-r--r--plugins/acl/localization/tr_TR.inc2
-rw-r--r--plugins/acl/package.xml2
-rw-r--r--plugins/archive/archive.js18
-rw-r--r--plugins/archive/localization/lv_LV.inc22
-rwxr-xr-xplugins/attachment_reminder/attachment_reminder.php10
-rw-r--r--plugins/enigma/skins/classic/templates/keys.html6
-rw-r--r--plugins/example_addressbook/example_addressbook.php3
-rw-r--r--plugins/filesystem_attachments/filesystem_attachments.php1
-rw-r--r--plugins/filesystem_attachments/package.xml2
-rw-r--r--plugins/help/config.inc.php.dist34
-rw-r--r--plugins/help/content/about.html27
-rw-r--r--plugins/help/content/license.html2
-rw-r--r--plugins/help/help.js25
-rw-r--r--plugins/help/help.php67
-rw-r--r--plugins/help/localization/de_DE.inc2
-rw-r--r--plugins/help/localization/gl_ES.inc2
-rw-r--r--plugins/help/package.xml9
-rw-r--r--plugins/help/skins/classic/help.css16
-rw-r--r--plugins/help/skins/classic/templates/help.html17
-rw-r--r--plugins/help/skins/larry/help.css1
-rw-r--r--plugins/help/skins/larry/templates/help.html8
-rw-r--r--plugins/jqueryui/jqueryui.php1
-rw-r--r--plugins/managesieve/Changelog3
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve.php12
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php2122
-rw-r--r--plugins/managesieve/lib/Roundcube/rcube_sieve_script.php12
-rw-r--r--plugins/managesieve/localization/en_US.inc23
-rw-r--r--plugins/managesieve/localization/es_ES.inc31
-rw-r--r--plugins/managesieve/localization/et_EE.inc29
-rw-r--r--plugins/managesieve/localization/fr_FR.inc43
-rw-r--r--plugins/managesieve/localization/lv_LV.inc163
-rw-r--r--plugins/managesieve/localization/pl_PL.inc31
-rw-r--r--plugins/managesieve/localization/pt_BR.inc27
-rw-r--r--plugins/managesieve/localization/ru_RU.inc27
-rw-r--r--plugins/managesieve/localization/sl_SI.inc31
-rw-r--r--plugins/managesieve/managesieve.js73
-rw-r--r--plugins/managesieve/managesieve.php1950
-rw-r--r--plugins/managesieve/package.xml10
-rw-r--r--plugins/managesieve/skins/classic/managesieve.css8
-rw-r--r--plugins/managesieve/skins/classic/templates/managesieve.html6
-rw-r--r--plugins/managesieve/skins/larry/managesieve.css11
-rw-r--r--plugins/markasjunk/localization/lv_LV.inc6
-rw-r--r--plugins/new_user_dialog/localization/lv_LV.inc4
-rw-r--r--plugins/new_user_identity/new_user_identity.php1
-rw-r--r--plugins/new_user_identity/package.xml2
-rw-r--r--plugins/newmail_notifier/localization/lv_LV.inc16
-rw-r--r--plugins/newmail_notifier/newmail_notifier.php12
-rw-r--r--plugins/newmail_notifier/package.xml2
-rw-r--r--plugins/password/README18
-rw-r--r--plugins/password/localization/gl_ES.inc2
-rw-r--r--plugins/password/localization/lv_LV.inc16
-rw-r--r--plugins/password/package.xml2
-rw-r--r--plugins/password/password.php48
-rw-r--r--plugins/show_additional_headers/package.xml2
-rw-r--r--plugins/show_additional_headers/show_additional_headers.php2
-rw-r--r--plugins/subscriptions_option/localization/gl_ES.inc2
-rw-r--r--plugins/subscriptions_option/package.xml2
-rw-r--r--plugins/subscriptions_option/subscriptions_option.php1
-rw-r--r--plugins/vcard_attachments/localization/gl_ES.inc4
-rw-r--r--plugins/virtuser_query/package.xml2
-rw-r--r--plugins/virtuser_query/virtuser_query.php1
-rw-r--r--program/include/rcmail.php12
-rw-r--r--program/include/rcmail_output_html.php77
-rw-r--r--program/js/app.js363
-rw-r--r--program/js/editor.js4
-rw-r--r--program/js/list.js57
-rw-r--r--program/lib/Mail/mime.php114
-rw-r--r--program/lib/Mail/mimePart.php40
-rw-r--r--program/lib/Roundcube/bootstrap.php4
-rw-r--r--program/lib/Roundcube/html.php4
-rw-r--r--program/lib/Roundcube/rcube.php30
-rw-r--r--program/lib/Roundcube/rcube_addressbook.php6
-rw-r--r--program/lib/Roundcube/rcube_imap.php139
-rw-r--r--program/lib/Roundcube/rcube_imap_generic.php197
-rw-r--r--program/lib/Roundcube/rcube_ldap.php1302
-rw-r--r--program/lib/Roundcube/rcube_ldap_generic.php1049
-rw-r--r--program/lib/Roundcube/rcube_ldap_result.php130
-rw-r--r--program/lib/Roundcube/rcube_session.php94
-rw-r--r--program/lib/Roundcube/rcube_spellchecker.php146
-rw-r--r--program/lib/Roundcube/rcube_storage.php13
-rw-r--r--program/lib/Roundcube/rcube_utils.php6
-rw-r--r--program/lib/Roundcube/rcube_vcard.php10
-rw-r--r--program/localization/ar_SA/labels.inc5
-rw-r--r--program/localization/ast/labels.inc5
-rw-r--r--program/localization/az_AZ/labels.inc5
-rw-r--r--program/localization/be_BE/labels.inc5
-rw-r--r--program/localization/bg_BG/labels.inc5
-rw-r--r--program/localization/bn_BD/labels.inc5
-rw-r--r--program/localization/br/labels.inc5
-rw-r--r--program/localization/bs_BA/labels.inc7
-rw-r--r--program/localization/ca_ES/labels.inc5
-rw-r--r--program/localization/cs_CZ/labels.inc7
-rw-r--r--program/localization/cs_CZ/messages.inc6
-rw-r--r--program/localization/cy_GB/labels.inc7
-rw-r--r--program/localization/da_DK/labels.inc7
-rw-r--r--program/localization/de_CH/labels.inc5
-rw-r--r--program/localization/de_CH/messages.inc2
-rw-r--r--program/localization/de_DE/labels.inc7
-rw-r--r--program/localization/el_GR/labels.inc5
-rw-r--r--program/localization/en_GB/labels.inc4
-rw-r--r--program/localization/en_US/labels.inc4
-rw-r--r--program/localization/en_US/messages.inc9
-rw-r--r--program/localization/eo/labels.inc5
-rw-r--r--program/localization/es_AR/labels.inc5
-rw-r--r--program/localization/es_ES/labels.inc7
-rw-r--r--program/localization/es_ES/messages.inc2
-rw-r--r--program/localization/et_EE/labels.inc15
-rw-r--r--program/localization/et_EE/messages.inc6
-rw-r--r--program/localization/eu_ES/labels.inc5
-rw-r--r--program/localization/fa_AF/labels.inc5
-rw-r--r--program/localization/fa_IR/labels.inc5
-rw-r--r--program/localization/fi_FI/labels.inc13
-rw-r--r--program/localization/fr_FR/labels.inc79
-rw-r--r--program/localization/fy_NL/labels.inc5
-rw-r--r--program/localization/fy_NL/messages.inc171
-rwxr-xr-xprogram/localization/ga_IE/labels.inc5
-rw-r--r--program/localization/gl_ES/labels.inc7
-rw-r--r--program/localization/gl_ES/messages.inc2
-rw-r--r--program/localization/he_IL/labels.inc5
-rw-r--r--program/localization/he_IL/messages.inc2
-rw-r--r--program/localization/hi_IN/labels.inc5
-rw-r--r--program/localization/hr_HR/labels.inc5
-rw-r--r--program/localization/hu_HU/labels.inc5
-rw-r--r--program/localization/hy_AM/labels.inc5
-rw-r--r--program/localization/ia/labels.inc5
-rw-r--r--program/localization/id_ID/labels.inc5
-rw-r--r--program/localization/is_IS/labels.inc5
-rw-r--r--program/localization/it_IT/labels.inc5
-rw-r--r--program/localization/ja_JP/labels.inc5
-rwxr-xr-xprogram/localization/ka_GE/labels.inc5
-rw-r--r--program/localization/km_KH/labels.inc5
-rw-r--r--program/localization/ko_KR/labels.inc5
-rw-r--r--program/localization/ku/labels.inc5
-rw-r--r--program/localization/lt_LT/labels.inc5
-rw-r--r--program/localization/lv_LV/labels.inc323
-rw-r--r--program/localization/lv_LV/messages.inc90
-rwxr-xr-xprogram/localization/mk_MK/labels.inc5
-rw-r--r--program/localization/ml_IN/labels.inc5
-rwxr-xr-xprogram/localization/mr_IN/labels.inc5
-rw-r--r--program/localization/ms_MY/labels.inc5
-rw-r--r--program/localization/nb_NO/labels.inc5
-rw-r--r--program/localization/ne_NP/labels.inc5
-rw-r--r--program/localization/nl_BE/labels.inc5
-rw-r--r--program/localization/nl_NL/labels.inc5
-rw-r--r--program/localization/nn_NO/labels.inc5
-rw-r--r--program/localization/pl_PL/labels.inc5
-rw-r--r--program/localization/pl_PL/messages.inc2
-rwxr-xr-xprogram/localization/ps/labels.inc5
-rw-r--r--program/localization/pt_BR/labels.inc9
-rw-r--r--program/localization/pt_PT/labels.inc5
-rw-r--r--program/localization/ro_RO/labels.inc79
-rw-r--r--program/localization/ru_RU/labels.inc5
-rw-r--r--program/localization/si_LK/labels.inc5
-rw-r--r--program/localization/sk_SK/labels.inc5
-rw-r--r--program/localization/sl_SI/labels.inc13
-rw-r--r--program/localization/sl_SI/messages.inc2
-rw-r--r--program/localization/sq_AL/labels.inc5
-rw-r--r--program/localization/sr_CS/labels.inc5
-rw-r--r--program/localization/sv_SE/labels.inc5
-rw-r--r--program/localization/ta_IN/labels.inc5
-rw-r--r--program/localization/th_TH/labels.inc5
-rw-r--r--program/localization/tr_TR/labels.inc7
-rw-r--r--program/localization/tr_TR/messages.inc2
-rw-r--r--program/localization/uk_UA/labels.inc5
-rw-r--r--program/localization/vi_VN/labels.inc5
-rw-r--r--program/localization/zh_CN/labels.inc5
-rw-r--r--program/localization/zh_TW/labels.inc5
-rw-r--r--program/steps/addressbook/copy.inc12
-rw-r--r--program/steps/addressbook/delete.inc38
-rw-r--r--program/steps/addressbook/func.inc116
-rw-r--r--program/steps/addressbook/list.inc49
-rw-r--r--program/steps/addressbook/move.inc208
-rw-r--r--program/steps/addressbook/save.inc4
-rw-r--r--program/steps/addressbook/show.inc5
-rw-r--r--program/steps/addressbook/undo.inc25
-rw-r--r--program/steps/mail/compose.inc59
-rw-r--r--program/steps/mail/func.inc141
-rw-r--r--program/steps/mail/get.inc76
-rw-r--r--program/steps/mail/import.inc105
-rw-r--r--program/steps/mail/list_contacts.inc43
-rw-r--r--program/steps/mail/move_del.inc4
-rw-r--r--program/steps/mail/search_contacts.inc19
-rw-r--r--program/steps/settings/folders.inc13
-rw-r--r--program/steps/settings/func.inc2
-rw-r--r--skins/classic/addressbook.css31
-rw-r--r--skins/classic/common.css9
-rw-r--r--skins/classic/functions.js115
-rw-r--r--skins/classic/images/contactgroup.pngbin0 -> 1038 bytes
-rw-r--r--skins/classic/images/mail_toolbar.pngbin36649 -> 40806 bytes
-rw-r--r--skins/classic/includes/messagetoolbar.html2
-rw-r--r--skins/classic/mail.css292
-rw-r--r--skins/classic/settings.css14
-rw-r--r--skins/classic/templates/about.html7
-rw-r--r--skins/classic/templates/addressbook.html15
-rw-r--r--skins/classic/templates/compose.html8
-rw-r--r--skins/classic/templates/contact.html2
-rw-r--r--skins/classic/templates/contactadd.html7
-rw-r--r--skins/classic/templates/contactedit.html7
-rw-r--r--skins/classic/templates/folders.html6
-rw-r--r--skins/classic/templates/mail.html16
-rw-r--r--skins/classic/templates/message.html8
-rw-r--r--skins/classic/templates/messageerror.html6
-rw-r--r--skins/classic/templates/messagepart.html38
-rw-r--r--skins/classic/templates/messagepreview.html6
-rw-r--r--skins/larry/addressbook.css49
-rw-r--r--skins/larry/ie7hacks.css1
-rw-r--r--skins/larry/images/buttons.pngbin37956 -> 50162 bytes
-rw-r--r--skins/larry/images/contactgroup.pngbin0 -> 2104 bytes
-rw-r--r--skins/larry/images/listicons.pngbin25486 -> 26384 bytes
-rw-r--r--skins/larry/includes/header.html6
-rw-r--r--skins/larry/mail.css306
-rw-r--r--skins/larry/settings.css10
-rw-r--r--skins/larry/styles.css27
-rw-r--r--skins/larry/templates/about.html4
-rw-r--r--skins/larry/templates/addressbook.html9
-rw-r--r--skins/larry/templates/contact.html2
-rw-r--r--skins/larry/templates/mail.html15
-rw-r--r--skins/larry/templates/message.html2
-rw-r--r--skins/larry/templates/messagepart.html34
-rw-r--r--skins/larry/ui.js81
-rw-r--r--tests/Framework/ImapGeneric.php23
235 files changed, 7831 insertions, 4618 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 9c67958a1..8dc8d4b0f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,7 +1,36 @@
CHANGELOG Roundcube Webmail
===========================
+- Fix bug where signature wasn't changed on identity selection when editing a draft (#1489229)
+- Fix IMAP SETMETADATA parameters quoting (#1489231)
+- Add support for 'enchant' spellcheck engine
+- Fix "could not load message" error on valid empty message body (#1489228)
+- Check filetype detection in installer and update script (#1489193)
+- Fix handling of message/rfc822 attachments on message forward and edit (#1489214)
+- Fix folder names truncation in Classic skin (#1489220)
+- Fix parsing of square bracket characters in IMAP response strings (#1489223)
+- Don't clear References and in-Reply-To when a message is "edited as new" (#1489216)
+- Make possible to disable some (broken) IMAP extensions with imap_disable_caps option (#1489184)
+- Contacts drag-n-drop default action is to move contacts (#1488751)
+- Added possibility to choose to move or copy contacts from drag-n-drop menu (#1488751)
+- Fix messages list sorting with THREAD=REFS
+- Fix Close link and remove About link on error pages (#1489109)
+- Remove deprecated (in PHP 5.5) PREG /e modifier usage (#1489174)
+- Fix empty messages list when register_globals is enabled (#1489157)
+- Improved/unified attachment preview screen, added print button
+- Fix lack of space between searchfiler and quicksearchbar in Larry skin (#1489158)
+- Fix so valid and set date.timezone is not required by installer checks (#1489180)
+- Canonize boolean ini_get() results (#1489189)
+- Cache LDAP's user_specific search and use vlv for better performance (#1489186)
+- LDAP: auto-detect and use VLV indices for all search operations
+- LDAP: additional group configuration options for address books
+- LDAP: separated address book implementation from a generic LDAP wrapper class
+- Allow address books to browse a multi-level group hierarchy in the contacts list
+- Fix so install do not fail when one of DB driver checks fails but other drivers exist (#1489178)
+- Fix so exported vCard specifies encoding in v3-compatible format (#1489183)
+- Fix session issues when local and database time differs (#1486132)
- Fix thread cache syncronization/validation (#1489028)
+- Added feature to import messages to the currently selected folder
- Add option show_real_foldernames to disable localization of special folders
- Fix database cache expunge issues (#1489149)
- Fix date format issues on MS SQL Server (#1488918)
diff --git a/INSTALL b/INSTALL
index b80d3323b..5b1c21dac 100644
--- a/INSTALL
+++ b/INSTALL
@@ -52,7 +52,8 @@ INSTALLATION
4. Point your browser to http://url-to-roundcube/installer/
5. Follow the instructions of the install script (or see MANUAL CONFIGURATION)
6. After creating and testing the configuration, remove the installer directory
-7. Done!
+7. Check Known Issues section of this file
+8. Done!
CONFIGURATION HINTS
@@ -95,18 +96,9 @@ mind: You need to specify this password later in 'config/db.inc.php'.
* SQLite
--------
-You need sqlite 2 (preferably 2.8) to setup the sqlite db
-(sqlite 3.x also doesn't work at the moment). Here is
-an example how you can setup the sqlite.db for roundcube:
-
-# sqlite -init SQL/sqlite.initial.sql sqlite.db
-Loading resources from SQL/sqlite.initial.sql
-SQLite version 2.8.16
-Enter ".help" for instructions
-sqlite> .exit
-# chmod o+rw sqlite.db
-
-Make sure your configuration points to the sqlite.db file and that the
+Versions of sqlite database engine older than 3 aren't supported.
+Database file and structure is created automatically by Roundcube.
+Make sure your configuration points to some file location and that the
webserver can write to the file and the directory containing the file.
@@ -137,7 +129,6 @@ bin/cleandb.sh which finally removes all records that are marked as deleted.
Best solution is to install a cronjob running this script daily.
-
MANUAL CONFIGURATION
====================
@@ -236,3 +227,10 @@ $HTTP["host"] == "www.example.com" {
compress.filetype = ("text/plain", "text/html", "text/javascript", "text/css", "text/xml", "image/gif", "image/png")
}
+
+
+KNOWN ISSUES
+============
+
+Installations with uw-imap server should set imap_disabled_caps = array('ESEARCH')
+in main configuration file. ESEARCH implementation in this server is broken (#1489184).
diff --git a/SQL/sqlite.initial.sql b/SQL/sqlite.initial.sql
index 28a43680d..e7f74ddfc 100644
--- a/SQL/sqlite.initial.sql
+++ b/SQL/sqlite.initial.sql
@@ -126,7 +126,7 @@ CREATE TABLE cache (
user_id integer NOT NULL default 0,
cache_key varchar(128) NOT NULL default '',
created datetime NOT NULL default '0000-00-00 00:00:00',
- expires datetime DEFAULT NOT,
+ expires datetime DEFAULT NULL,
data text NOT NULL
);
diff --git a/bin/update.sh b/bin/update.sh
index 133d9f7ab..71e2c630a 100755
--- a/bin/update.sh
+++ b/bin/update.sh
@@ -144,8 +144,18 @@ if ($RCI->configured) {
}
}
- // update database schema
- if ($RCI->config['db_dsnw'] && $opts['version'] && version_compare(version_parse($opts['version']), version_parse(RCMAIL_VERSION), '<')) {
+ // check file type detection
+ if ($RCI->check_mime_detection()) {
+ echo "WARNING: File type detection doesn't work properly!\n";
+ echo "Please check the 'mime_magic' config option or the finfo functions of PHP andrun this script again.\n";
+ }
+ if ($RCI->check_mime_extensions()) {
+ echo "WARNING: Mimetype to file extension mapping doesn't work properly!\n";
+ echo "Please check the 'mime_types' config option and run this script again.\n";
+ }
+
+ // check database schema
+ if ($RCI->config['db_dsnw']) {
echo "Executing database schema update.\n";
system(INSTALL_PATH . "bin/updatedb.sh --package=roundcube --version=" . $opts['version']
. " --dir=" . INSTALL_PATH . DIRECTORY_SEPARATOR . "SQL", $res);
diff --git a/config/defaults.inc.php b/config/defaults.inc.php
index a796e168c..042170437 100644
--- a/config/defaults.inc.php
+++ b/config/defaults.inc.php
@@ -129,12 +129,20 @@ $config['imap_force_caps'] = false;
// extension if available. Some servers (dovecot 1.x) returns wrong results
// for shared namespaces in this case. http://trac.roundcube.net/ticket/1486225
// Enable this option to force LSUB command usage instead.
+// Deprecated: Use imap_disabled_caps = array('LIST-EXTENDED')
$config['imap_force_lsub'] = false;
// Some server configurations (e.g. Courier) doesn't list folders in all namespaces
// Enable this option to force listing of folders in all namespaces
$config['imap_force_ns'] = false;
+// List of disabled imap extensions.
+// Use if your IMAP server has broken implementation of some feature
+// and you can't remove it from CAPABILITY string on server-side.
+// For example UW-IMAP server has broken ESEARCH.
+// Note: Because the list is cached, re-login is required after change.
+$rcmail_config['imap_disabled_caps'] = array();
+
// IMAP connection timeout, in seconds. Default: 0 (no limit)
$config['imap_timeout'] = 0;
@@ -201,6 +209,8 @@ $config['smtp_auth_pw'] = null;
$config['smtp_helo_host'] = '';
// SMTP connection timeout, in seconds. Default: 0 (no limit)
+// Note: There's a known issue where using ssl connection with
+// timeout > 0 causes connection errors (https://bugs.php.net/bug.php?id=54511)
$config['smtp_timeout'] = 0;
// ----------------------------------
@@ -524,8 +534,9 @@ $config['enable_spellcheck'] = true;
// Setting it to 'shared' will make the dictionary shared by all users.
$config['spellcheck_dictionary'] = false;
-// Set the spell checking engine. 'googie' is the default. 'pspell' is also available,
-// but requires the Pspell extensions. When using Nox Spell Server, also set 'googie' here.
+// Set the spell checking engine. 'googie' is the default.
+// 'pspell' and 'enchant' are also available, but they require
+// PHP Pspell or Enchant extensions. When using Nox Spell Server, also set 'googie' here.
$config['spellcheck_engine'] = 'googie';
// For a locally installed Nox Spell Server, please specify the URI to call it.
@@ -612,7 +623,7 @@ $config['ldap_public']['Verisign'] = array(
// For example %n = mail.domain.tld, %t = domain.tld
'hosts' => array('directory.verisign.com'),
'port' => 389,
- 'use_tls' => false,
+ 'use_tls' => false,
'ldap_version' => 3, // using LDAPv3
'network_timeout' => 10, // The timeout (in seconds) for connect + bind arrempts. This is only supported in PHP >= 5.3.0 with OpenLDAP 2.x
'user_specific' => false, // If true the base_dn, bind_dn and bind_pass default to the user's IMAP login.
@@ -673,6 +684,7 @@ $config['ldap_public']['Verisign'] = array(
'phone:work' => 'telephoneNumber',
'phone:mobile' => 'mobile',
'phone:pager' => 'pager',
+ 'phone:workfax' => 'facsimileTelephoneNumber',
'street' => 'street',
'zipcode' => 'postalCode',
'region' => 'st',
@@ -683,9 +695,8 @@ $config['ldap_public']['Verisign'] = array(
'department' => 'ou',
'jobtitle' => 'title',
'notes' => 'description',
+ 'photo' => 'jpegPhoto',
// these currently don't work:
- // 'phone:workfax' => 'facsimileTelephoneNumber',
- // 'photo' => 'jpegPhoto',
// 'manager' => 'manager',
// 'assistant' => 'secretary',
),
@@ -696,27 +707,50 @@ $config['ldap_public']['Verisign'] = array(
// 'uid' => 'md5(microtime())', // You may specify PHP code snippets which are then eval'ed
// 'mail' => '{givenname}.{sn}@mydomain.com', // or composite strings with placeholders for existing attributes
),
- 'sort' => 'cn', // The field to sort the listing by.
- 'scope' => 'sub', // search mode: sub|base|list
- 'filter' => '(objectClass=inetOrgPerson)', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act
- 'fuzzy_search' => true, // server allows wildcard search
- 'vlv' => false, // Enable Virtual List View to more efficiently fetch paginated data (if server supports it)
- 'numsub_filter' => '(objectClass=organizationalUnit)', // with VLV, we also use numSubOrdinates to query the total number of records. Set this filter to get all numSubOrdinates attributes for counting
- 'sizelimit' => '0', // Enables you to limit the count of entries fetched. Setting this to 0 means no limit.
- 'timelimit' => '0', // Sets the number of seconds how long is spend on the search. Setting this to 0 means no limit.
- 'referrals' => true|false, // Sets the LDAP_OPT_REFERRALS option. Mostly used in multi-domain Active Directory setups
+ 'sort' => 'cn', // The field to sort the listing by.
+ 'scope' => 'sub', // search mode: sub|base|list
+ 'filter' => '(objectClass=inetOrgPerson)', // used for basic listing (if not empty) and will be &'d with search queries. example: status=act
+ 'fuzzy_search' => true, // server allows wildcard search
+ 'vlv' => false, // Enable Virtual List View to more efficiently fetch paginated data (if server supports it)
+ 'vlv_search' => false, // Use Virtual List View functions for autocompletion searches (if server supports it)
+ 'numsub_filter' => '(objectClass=organizationalUnit)', // with VLV, we also use numSubOrdinates to query the total number of records. Set this filter to get all numSubOrdinates attributes for counting
+ 'config_root_dn' => 'cn=config', // Root DN to search config entries (e.g. vlv indexes)
+ 'sizelimit' => '0', // Enables you to limit the count of entries fetched. Setting this to 0 means no limit.
+ 'timelimit' => '0', // Sets the number of seconds how long is spend on the search. Setting this to 0 means no limit.
+ 'referrals' => false, // Sets the LDAP_OPT_REFERRALS option. Mostly used in multi-domain Active Directory setups
// definition for contact groups (uncomment if no groups are supported)
// for the groups base_dn, the user replacements %fu, %u, $d and %dc work as for base_dn (see above)
// if the groups base_dn is empty, the contact base_dn is used for the groups as well
// -> in this case, assure that groups and contacts are separated due to the concernig filters!
- 'groups' => array(
- 'base_dn' => '',
- 'scope' => 'sub', // search mode: sub|base|list
- 'filter' => '(objectClass=groupOfNames)',
+ 'groups' => array(
+ 'base_dn' => '',
+ 'scope' => 'sub', // Search mode: sub|base|list
+ 'filter' => '(objectClass=groupOfNames)',
'object_classes' => array("top", "groupOfNames"),
- 'member_attr' => 'member', // name of the member attribute, e.g. uniqueMember
- 'name_attr' => 'cn', // attribute to be used as group name
+ 'member_attr' => 'member', // Name of the member attribute, e.g. uniqueMember
+ 'name_attr' => 'cn', // Attribute to be used as group name
+ 'member_filter' => '(objectclass=*)', // Optional filter to use when querying for group members
+ 'vlv' => false, // Use VLV controls to list groups
+ ),
+ // this configuration replaces the regular groups listing in the directory tree with
+ // a hard-coded list of groups, each listing entries with the configured base DN and filter.
+ // if the 'groups' option from above is set, it'll be shown as the first entry with the name 'Groups'
+ 'group_filters' => array(
+ 'departments' => array(
+ 'name' => 'Company Departments',
+ 'scope' => 'list',
+ 'base_dn' => 'ou=Groups,dc=mydomain,dc=com',
+ 'filter' => '(|(objectclass=groupofuniquenames)(objectclass=groupofurls))',
+ 'name_attr' => 'cn',
+ ),
+ 'customers' => array(
+ 'name' => 'Customers',
+ 'scope' => 'sub',
+ 'base_dn' => 'ou=Customers,dc=mydomain,dc=com',
+ 'filter' => '(objectClass=inetOrgPerson)',
+ 'name_attr' => 'sn',
+ ),
),
);
*/
diff --git a/installer/check.php b/installer/check.php
index fcf35025e..ee0c9f367 100644
--- a/installer/check.php
+++ b/installer/check.php
@@ -42,12 +42,13 @@ $ini_checks = array(
'suhosin.session.encrypt' => 0,
'magic_quotes_runtime' => 0,
'magic_quotes_sybase' => 0,
- 'date.timezone' => '-NOTEMPTY-',
);
$optional_checks = array(
// required for utils/modcss.inc, should we require this?
'allow_url_fopen' => 1,
+ 'date.timezone' => '-VALID-',
+ 'register_globals' => 0, // #1489157
);
$source_urls = array(
@@ -139,10 +140,11 @@ foreach ($RCI->supported_dbs as $database => $ext) {
if (extension_loaded($ext)) {
// MySQL driver requires PHP >= 5.3 (#1488875)
if ($ext == 'pdo_mysql' && version_compare(PHP_VERSION, '5.3.0', '<')) {
- $RCI->fail($database, 'PHP >= 5.3 required');
+ $RCI->fail($database, 'PHP >= 5.3 required', null, true);
}
else {
$RCI->pass($database);
+ $found_db_driver = true;
}
}
else {
@@ -152,6 +154,9 @@ foreach ($RCI->supported_dbs as $database => $ext) {
}
echo '<br />';
}
+if (empty($found_db_driver)) {
+ $RCI->failures++;
+}
?>
@@ -185,23 +190,15 @@ foreach ($ini_checks as $var => $val) {
if ($val === '-NOTEMPTY-') {
if (empty($status)) {
$RCI->fail($var, "empty value detected");
- } else if ($var == 'date.timezone') {
- try {
- $tz = new DateTimeZone($status);
- $RCI->pass($var);
- }
- catch (Exception $e) {
- $RCI->fail($var, "invalid value detected: $status");
- }
- } else {
+ }
+ else {
$RCI->pass($var);
}
- echo '<br />';
- continue;
}
- if ($status == $val) {
+ else if (filter_var($status, FILTER_VALIDATE_BOOLEAN) == $val) {
$RCI->pass($var);
- } else {
+ }
+ else {
$RCI->fail($var, "is '$status', should be '$val'");
}
echo '<br />';
@@ -223,9 +220,24 @@ foreach ($optional_checks as $var => $val) {
echo '<br />';
continue;
}
- if ($status == $val) {
+ if ($val === '-VALID-') {
+ if ($var == 'date.timezone') {
+ try {
+ $tz = new DateTimeZone($status);
+ $RCI->pass($var);
+ }
+ catch (Exception $e) {
+ $RCI->optfail($var, empty($status) ? "not set" : "invalid value detected: $status");
+ }
+ }
+ else {
+ $RCI->pass($var);
+ }
+ }
+ else if (filter_var($status, FILTER_VALIDATE_BOOLEAN) == $val) {
$RCI->pass($var);
- } else {
+ }
+ else {
$RCI->optfail($var, "is '$status', could be '$val'");
}
echo '<br />';
diff --git a/installer/rcube_install.php b/installer/rcube_install.php
index da636555b..600db34ab 100644
--- a/installer/rcube_install.php
+++ b/installer/rcube_install.php
@@ -432,6 +432,51 @@ class rcube_install
return $schema;
}
+ /**
+ * Try to detect some file's mimetypes to test the correct behavior of fileinfo
+ */
+ function check_mime_detection()
+ {
+ $files = array(
+ 'installer/images/roundcube_logo.png' => 'image/png',
+ 'program/resources/blank.tif' => 'image/tiff',
+ 'skins/larry/templates/login.html' => 'text/html',
+ );
+
+ $errors = array();
+ foreach ($files as $path => $expected) {
+ $mimetype = rcube_mime::file_content_type(INSTALL_PATH . $path, basename($path));
+ if ($mimetype != $expected) {
+ $errors[] = array($path, $mimetype, $expected);
+ }
+ }
+
+ return $errors;
+ }
+
+ /**
+ * Check the correct configuration of the 'mime_types' mapping option
+ */
+ function check_mime_extensions()
+ {
+ $types = array(
+ 'application/zip' => 'zip',
+ 'application/x-tar' => 'tar',
+ 'application/java-archive' => 'jar',
+ 'image/bmp' => 'bmp',
+ 'image/svg+xml' => 'svg',
+ );
+
+ $errors = array();
+ foreach ($types as $mimetype => $expected) {
+ $ext = rcube_mime::get_mime_extensions($mimetype);
+ if ($ext[0] != $expected) {
+ $errors[] = array($mimetype, $ext, $expected);
+ }
+ }
+
+ return $errors;
+ }
/**
* Getter for the last error message
@@ -517,10 +562,13 @@ class rcube_install
* @param string Test name
* @param string Error message
* @param string URL for details
+ * @param bool Do not count this failure
*/
- function fail($name, $message = '', $url = '')
+ function fail($name, $message = '', $url = '', $optional=false)
{
- $this->failures++;
+ if (!$optional) {
+ $this->failures++;
+ }
echo Q($name) . ':&nbsp; <span class="fail">NOT OK</span>';
$this->_showhint($message, $url);
diff --git a/installer/test.php b/installer/test.php
index c2e321455..f834308ad 100644
--- a/installer/test.php
+++ b/installer/test.php
@@ -207,6 +207,42 @@ if ($db_working) {
?>
+<h3>Test filetype detection</h3>
+
+<p>
+<?php
+
+if ($errors = $RCI->check_mime_detection()) {
+ $RCI->fail('Fileinfo/mime_content_type configuration');
+ if (!empty($RCI->config['mime_magic'])) {
+ echo '<p class="hint">Try setting the <tt>mime_magic</tt> config option to <tt>null</tt>.</p>';
+ }
+ else {
+ echo '<p class="hint">Check the <a href="http://www.php.net/manual/en/function.finfo-open.php">Fileinfo functions</a> of your PHP installation.<br/>';
+ echo 'The path to the magic.mime file can be set using the <tt>mime_magic</tt> config option in Roundcube.</p>';
+ }
+}
+else {
+ $RCI->pass('Fileinfo/mime_content_type configuration');
+}
+
+?>
+</p>
+<p>
+<?php
+
+if ($errors = $RCI->check_mime_extensions()) {
+ $RCI->fail('Mimetype to file extension mapping');
+ echo '<p class="hint">Please set a valid path to your webserver\'s mime.types file to the <tt>mime_types</tt> config option.<br/>';
+ echo 'If you can\'t find such a file, download it from <a href="http://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types">svn.apache.org</a>.</p>';
+}
+else {
+ $RCI->pass('Mimetype to file extension mapping');
+}
+
+?>
+
+
<h3>Test SMTP config</h3>
<p>
diff --git a/plugins/acl/acl.php b/plugins/acl/acl.php
index 28139e92c..a840bcd58 100644
--- a/plugins/acl/acl.php
+++ b/plugins/acl/acl.php
@@ -9,18 +9,18 @@
*
* Copyright (C) 2011-2012, Kolab Systems AG
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
*/
class acl extends rcube_plugin
@@ -148,6 +148,7 @@ class acl extends rcube_plugin
// Load localization and include scripts
$this->load_config();
+ $this->specials = $this->rc->config->get('acl_specials', $this->specials);
$this->add_texts('localization/', array('deleteconfirm', 'norights',
'nouser', 'deleting', 'saving'));
$this->include_script('acl.js');
diff --git a/plugins/acl/config.inc.php.dist b/plugins/acl/config.inc.php.dist
index f957a233a..d0e1a0932 100644
--- a/plugins/acl/config.inc.php.dist
+++ b/plugins/acl/config.inc.php.dist
@@ -16,4 +16,10 @@ $rcmail_config['acl_users_field'] = 'mail';
// The LDAP search filter will be &'d with search queries
$rcmail_config['acl_users_filter'] = '';
+// Include the following 'special' access control subjects in the ACL dialog;
+// Defaults to array('anyone', 'anonymous') (not when set to an empty array)
+// Example: array('anyone') to exclude 'anonymous'.
+// Set to an empty array to exclude all special aci subjects.
+$rcmail_config['acl_specials'] = array('anyone', 'anonymous');
+
?>
diff --git a/plugins/acl/localization/et_EE.inc b/plugins/acl/localization/et_EE.inc
index f89e7d6b7..ceec4cd0c 100644
--- a/plugins/acl/localization/et_EE.inc
+++ b/plugins/acl/localization/et_EE.inc
@@ -73,8 +73,8 @@ $labels['longacli'] = 'Messages can be written or copied to the folder';
$labels['longaclp'] = 'Messages can be posted to this folder';
$labels['longaclc'] = 'Folders can be created (or renamed) directly under this folder';
$labels['longaclk'] = 'Folders can be created (or renamed) directly under this folder';
-$labels['longacld'] = 'Messages Delete flag can be changed';
-$labels['longaclt'] = 'Messages Delete flag can be changed';
+$labels['longacld'] = 'Kirja kustutamis lippu saab muuta';
+$labels['longaclt'] = 'Kirja kustutamis lippu saab muuta';
$labels['longacle'] = 'Kirju saab eemaldada';
$labels['longaclx'] = 'Seda kausta ei saa kustutada ega ümber nimetada';
$labels['longacla'] = 'Selle kausta ligipääsuõigusi saab muuta';
diff --git a/plugins/acl/localization/gl_ES.inc b/plugins/acl/localization/gl_ES.inc
index bb8837190..2349975de 100644
--- a/plugins/acl/localization/gl_ES.inc
+++ b/plugins/acl/localization/gl_ES.inc
@@ -28,15 +28,15 @@ $labels['identifier'] = 'Identificador';
$labels['acll'] = 'Bloquear';
$labels['aclr'] = 'Ler mensaxes';
-$labels['acls'] = 'Keep Seen state';
-$labels['aclw'] = 'Write flags';
-$labels['acli'] = 'Insert (Copy into)';
-$labels['aclp'] = 'Post';
+$labels['acls'] = 'Manter o estado coma visto';
+$labels['aclw'] = 'Marcas de lectura';
+$labels['acli'] = 'Engadir (Copiar en)';
+$labels['aclp'] = 'Envío';
$labels['aclc'] = 'Crear subcartafoles';
$labels['aclk'] = 'Crear subcartafoles';
$labels['acld'] = 'Borrar mensaxes';
$labels['aclt'] = 'Borrar mensaxes';
-$labels['acle'] = 'Expunge';
+$labels['acle'] = 'Expurga';
$labels['aclx'] = 'Eliminar carpeta';
$labels['acla'] = 'Administrar';
@@ -51,12 +51,12 @@ $labels['shortaclr'] = 'Ler';
$labels['shortacls'] = 'Manter';
$labels['shortaclw'] = 'Escribir';
$labels['shortacli'] = 'Insertar';
-$labels['shortaclp'] = 'Post';
+$labels['shortaclp'] = 'Envío';
$labels['shortaclc'] = 'Crear';
$labels['shortaclk'] = 'Crear';
$labels['shortacld'] = 'Borrar';
$labels['shortaclt'] = 'Borrar';
-$labels['shortacle'] = 'Expunge';
+$labels['shortacle'] = 'Expurga';
$labels['shortaclx'] = 'Borrar cartafol';
$labels['shortacla'] = 'Administrar';
@@ -66,33 +66,33 @@ $labels['shortaclwrite'] = 'Escritura';
$labels['shortacldelete'] = 'Borrado';
$labels['longacll'] = 'O cartafol é visible e pode ser suscrito';
-$labels['longaclr'] = 'The folder can be opened for reading';
-$labels['longacls'] = 'Messages Seen flag can be changed';
-$labels['longaclw'] = 'Messages flags and keywords can be changed, except Seen and Deleted';
-$labels['longacli'] = 'Messages can be written or copied to the folder';
-$labels['longaclp'] = 'Messages can be posted to this folder';
-$labels['longaclc'] = 'Folders can be created (or renamed) directly under this folder';
-$labels['longaclk'] = 'Folders can be created (or renamed) directly under this folder';
-$labels['longacld'] = 'Messages Delete flag can be changed';
-$labels['longaclt'] = 'Messages Delete flag can be changed';
-$labels['longacle'] = 'Messages can be expunged';
-$labels['longaclx'] = 'The folder can be deleted or renamed';
-$labels['longacla'] = 'The folder access rights can be changed';
+$labels['longaclr'] = 'Pódese abrir o cartafol para lectura';
+$labels['longacls'] = 'Pódese mudar o marcador de Mensaxes Enviadas';
+$labels['longaclw'] = 'Pódense mudar marcadores e palabras chave agás Olladas e Borradas';
+$labels['longacli'] = 'Pódense escreber ou copiar as mensaxes a este cartafol';
+$labels['longaclp'] = 'Pódense enviar as mensaxes a este cartafol';
+$labels['longaclc'] = 'Pódense crear (ou renomear) os cartafois directamente baixo deste cartafol';
+$labels['longaclk'] = 'Pódense crear (ou renomear) os cartafois directamente baixo deste cartafol';
+$labels['longacld'] = 'Pódense mudar as mensaxes coa marca de Borrado';
+$labels['longaclt'] = 'Pódense mudar as mensaxes coa marca de Borrado';
+$labels['longacle'] = 'Pódense eliminar as mensaxes';
+$labels['longaclx'] = 'Pódese borrar ou renomear o cartafol';
+$labels['longacla'] = 'Pódense mudar os dereitos de acceso ao cartafol';
-$labels['longaclfull'] = 'Full control including folder administration';
-$labels['longaclread'] = 'The folder can be opened for reading';
-$labels['longaclwrite'] = 'Messages can be marked, written or copied to the folder';
-$labels['longacldelete'] = 'Messages can be deleted';
+$labels['longaclfull'] = 'Control total inclúe administración de cartafois';
+$labels['longaclread'] = 'Pódese abrir o cartafol para lectura';
+$labels['longaclwrite'] = 'Pódense marcar, escribir ou copiar as mensaxes no cartafol';
+$labels['longacldelete'] = 'Pódense borrar as mensaxes';
-$messages['deleting'] = 'Deleting access rights...';
-$messages['saving'] = 'Saving access rights...';
-$messages['updatesuccess'] = 'Successfully changed access rights';
-$messages['deletesuccess'] = 'Successfully deleted access rights';
-$messages['createsuccess'] = 'Successfully added access rights';
-$messages['updateerror'] = 'Ubable to update access rights';
-$messages['deleteerror'] = 'Unable to delete access rights';
-$messages['createerror'] = 'Unable to add access rights';
-$messages['deleteconfirm'] = 'Are you sure, you want to remove access rights of selected user(s)?';
+$messages['deleting'] = 'Borrando dereitos de acceso...';
+$messages['saving'] = 'Gardando dereitos de acceso...';
+$messages['updatesuccess'] = 'Mudados con éxito os dereitos de acceso';
+$messages['deletesuccess'] = 'Borrados con éxito os dereitos de acceso';
+$messages['createsuccess'] = 'Engadidos con éxito os dereitos de acceso';
+$messages['updateerror'] = 'Non se poden actualizar os dereitos de acceso';
+$messages['deleteerror'] = 'Non se poden borrar os dereitos de acceso';
+$messages['createerror'] = 'Non se poden engadir dereitos de acceso';
+$messages['deleteconfirm'] = 'De certo quere eliminar os dereitos de acceso do usuario(s) escollido?';
$messages['norights'] = 'Non se especificaron permisos!';
$messages['nouser'] = 'Non se especificou o nome de usuario!';
diff --git a/plugins/acl/localization/he_IL.inc b/plugins/acl/localization/he_IL.inc
index d7b027a40..9ca305d32 100644
--- a/plugins/acl/localization/he_IL.inc
+++ b/plugins/acl/localization/he_IL.inc
@@ -89,7 +89,7 @@ $messages['saving'] = 'זכויות גישה נשמרות...';
$messages['updatesuccess'] = 'זכויות גישה שונו בהצלחה';
$messages['deletesuccess'] = 'זכויות גישה נמחקו בהצלחה';
$messages['createsuccess'] = 'זכויות גישה נוספו בהצלחה';
-$messages['updateerror'] = '×œ× × ×™×ª×Ÿ לעדכן זכויות גישה';
+$messages['updateerror'] = '×œ× × ×™×ª×Ÿ לעדכן הרש×ות גישה';
$messages['deleteerror'] = '×œ× × ×™×ª×Ÿ למחוק זכויות גישה';
$messages['createerror'] = '×œ× × ×™×ª×Ÿ להוסיף זכויות גישה';
$messages['deleteconfirm'] = '×”×× ×•×“××™ שברצונך להסיר זכויות גישה של המשתמש(×™×) שנבחרו?';
diff --git a/plugins/acl/localization/pl_PL.inc b/plugins/acl/localization/pl_PL.inc
index 73c0fc4fb..69a5e0c05 100644
--- a/plugins/acl/localization/pl_PL.inc
+++ b/plugins/acl/localization/pl_PL.inc
@@ -89,7 +89,7 @@ $messages['saving'] = 'Zapisywanie praw dostępu...';
$messages['updatesuccess'] = 'Pomyślnie zmieniono prawa dostępu';
$messages['deletesuccess'] = 'Pomyślnie usunięto prawa dostępu';
$messages['createsuccess'] = 'Pomyślnie dodano prawa dostępu';
-$messages['updateerror'] = 'Nie udało się zmienić praw dostępu';
+$messages['updateerror'] = 'Nie udało się zaktualizować praw dostępu';
$messages['deleteerror'] = 'Nie udało się usunąć praw dostępu';
$messages['createerror'] = 'Nie udało się dodać praw dostępu';
$messages['deleteconfirm'] = 'Czy na pewno chcesz usunąć prawa wybranym użytkownikom?';
diff --git a/plugins/acl/localization/tr_TR.inc b/plugins/acl/localization/tr_TR.inc
index 1569b5926..f3d60324b 100644
--- a/plugins/acl/localization/tr_TR.inc
+++ b/plugins/acl/localization/tr_TR.inc
@@ -89,7 +89,7 @@ $messages['saving'] = 'Erişim hakları saklanıyor...';
$messages['updatesuccess'] = 'Erişim hakları başarıyla değiştirildi';
$messages['deletesuccess'] = 'Erişim hakları başarıyla silindi';
$messages['createsuccess'] = 'Erişim hakları başarıyla eklendi';
-$messages['updateerror'] = 'Erişim haklarını güncellenemedi';
+$messages['updateerror'] = 'Erişim hakları güncellenemedi';
$messages['deleteerror'] = 'Erişim haklarını silinemedi';
$messages['createerror'] = 'Erişim hakları eklenemedi';
$messages['deleteconfirm'] = 'Seçilen kullanıcılar için erişim haklarını silmek istediğinizden emin misiniz?';
diff --git a/plugins/acl/package.xml b/plugins/acl/package.xml
index 52e234f37..98460e82f 100644
--- a/plugins/acl/package.xml
+++ b/plugins/acl/package.xml
@@ -22,7 +22,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/archive/archive.js b/plugins/archive/archive.js
index eee41d336..3500b9fe4 100644
--- a/plugins/archive/archive.js
+++ b/plugins/archive/archive.js
@@ -7,18 +7,16 @@ function rcmail_archive(prop)
{
if (!rcmail.env.uid && (!rcmail.message_list || !rcmail.message_list.get_selection().length))
return;
-
+
if (rcmail.env.mailbox.indexOf(rcmail.env.archive_folder) != 0) {
if (!rcmail.env.archive_type) {
// simply move to archive folder (if no partition type is set)
- rcmail.command('moveto', rcmail.env.archive_folder);
+ rcmail.command('move', rcmail.env.archive_folder);
}
else {
// let the server sort the messages to the according subfolders
- rcmail.http_post(
- 'plugin.move2archive',
- { _uid: rcmail.message_list.get_selection().join(','), _mbox: rcmail.env.mailbox }
- );
+ var post_data = { _uid: rcmail.message_list.get_selection().join(','), _mbox: rcmail.env.mailbox };
+ rcmail.http_post('plugin.move2archive', post_data);
}
}
}
@@ -26,16 +24,15 @@ function rcmail_archive(prop)
// callback for app-onload event
if (window.rcmail) {
rcmail.addEventListener('init', function(evt) {
-
// register command (directly enable in message view mode)
rcmail.register_command('plugin.archive', rcmail_archive, (rcmail.env.uid && rcmail.env.mailbox != rcmail.env.archive_folder));
-
+
// add event-listener to message list
if (rcmail.message_list)
- rcmail.message_list.addEventListener('select', function(list){
+ rcmail.message_list.addEventListener('select', function(list) {
rcmail.enable_command('plugin.archive', (list.get_selection().length > 0 && rcmail.env.mailbox != rcmail.env.archive_folder));
});
-
+
// set css style for archive folder
var li;
if (rcmail.env.archive_folder && (li = rcmail.get_folder_li(rcmail.env.archive_folder, '', true)))
@@ -48,4 +45,3 @@ if (window.rcmail) {
});
})
}
-
diff --git a/plugins/archive/localization/lv_LV.inc b/plugins/archive/localization/lv_LV.inc
index ad2812fba..d4c892705 100644
--- a/plugins/archive/localization/lv_LV.inc
+++ b/plugins/archive/localization/lv_LV.inc
@@ -18,17 +18,17 @@
$labels = array();
$labels['buttontext'] = 'Arhīvs';
-$labels['buttontitle'] = 'Arhivēt vēstuli';
-$labels['archived'] = 'Vēstule sekmīgi arhivēta';
-$labels['archivedreload'] = 'Successfully archived. Reload the page to see the new archive folders.';
-$labels['archiveerror'] = 'Some messages could not be archived';
+$labels['buttontitle'] = 'Arhivēt šo vēstuli';
+$labels['archived'] = 'Vēstule veiksmīgi arhivēta';
+$labels['archivedreload'] = 'ArhÄ«vs veiksmÄ«gi izveidots. Lai redzÄ“tu jaunÄs arhÄ«va mapes, pÄrlÄdÄ“jiet lapu.';
+$labels['archiveerror'] = 'Dažas vēstules nebija iespējams arhivēt';
$labels['archivefolder'] = 'Arhīvs';
-$labels['settingstitle'] = 'Archive';
-$labels['archivetype'] = 'Divide archive by';
-$labels['archivetypeyear'] = 'Year (e.g. Archive/2012)';
-$labels['archivetypemonth'] = 'Month (e.g. Archive/2012/06)';
-$labels['archivetypefolder'] = 'Original folder';
-$labels['archivetypesender'] = 'Sender email';
-$labels['unkownsender'] = 'unknown';
+$labels['settingstitle'] = 'Arhīvs';
+$labels['archivetype'] = 'Sadalīt arhīvu pa';
+$labels['archivetypeyear'] = 'Gadiem (piem. Arhīvs/2012)';
+$labels['archivetypemonth'] = 'Mēnešiem (piem. Arhīvs/2012/06)';
+$labels['archivetypefolder'] = 'SÄkotnÄ“jÄ mape';
+$labels['archivetypesender'] = 'SÅ«tÄ«tÄja e-pasts';
+$labels['unkownsender'] = 'nezinÄms';
?>
diff --git a/plugins/attachment_reminder/attachment_reminder.php b/plugins/attachment_reminder/attachment_reminder.php
index a215ff57c..84cc5f3b3 100755
--- a/plugins/attachment_reminder/attachment_reminder.php
+++ b/plugins/attachment_reminder/attachment_reminder.php
@@ -22,7 +22,7 @@
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
*/
class attachment_reminder extends rcube_plugin
@@ -36,9 +36,11 @@ class attachment_reminder extends rcube_plugin
$rcmail = rcube::get_instance();
if ($rcmail->task == 'mail' && $rcmail->action == 'compose') {
- $this->include_script('attachment_reminder.js');
- $this->add_texts('localization/', array('keywords', 'forgotattachment'));
- $rcmail->output->add_label('addattachment', 'send');
+ if ($rcmail->config->get('attachment_reminder')) {
+ $this->include_script('attachment_reminder.js');
+ $this->add_texts('localization/', array('keywords', 'forgotattachment'));
+ $rcmail->output->add_label('addattachment', 'send');
+ }
}
if ($rcmail->task == 'settings') {
diff --git a/plugins/enigma/skins/classic/templates/keys.html b/plugins/enigma/skins/classic/templates/keys.html
index 4271eccb7..f581c457b 100644
--- a/plugins/enigma/skins/classic/templates/keys.html
+++ b/plugins/enigma/skins/classic/templates/keys.html
@@ -13,7 +13,7 @@
}
</style>
</head>
-<body class="iframe" onload="rcube_init_mail_ui()">
+<body class="iframe">
<div id="prefs-title" class="boxtitle"><roundcube:label name="enigma.enigmakeys" /></div>
<div id="prefs-details" class="boxcontent">
@@ -72,5 +72,9 @@
</ul>
</div>
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
</html>
diff --git a/plugins/example_addressbook/example_addressbook.php b/plugins/example_addressbook/example_addressbook.php
index a15461f44..31077adf7 100644
--- a/plugins/example_addressbook/example_addressbook.php
+++ b/plugins/example_addressbook/example_addressbook.php
@@ -5,6 +5,9 @@ require_once(dirname(__FILE__) . '/example_addressbook_backend.php');
/**
* Sample plugin to add a new address book
* with just a static list of contacts
+ *
+ * @license GNU GPLv3+
+ * @author Thomas Bruederli
*/
class example_addressbook extends rcube_plugin
{
diff --git a/plugins/filesystem_attachments/filesystem_attachments.php b/plugins/filesystem_attachments/filesystem_attachments.php
index d952e5a75..8d995ca0d 100644
--- a/plugins/filesystem_attachments/filesystem_attachments.php
+++ b/plugins/filesystem_attachments/filesystem_attachments.php
@@ -13,6 +13,7 @@
* require_once('plugins/filesystem_attachments/filesystem_attachments.php');
* class myCustom_attachments extends filesystem_attachments
*
+ * @license GNU GPLv3+
* @author Ziba Scott <ziba@umich.edu>
* @author Thomas Bruederli <roundcube@gmail.com>
*
diff --git a/plugins/filesystem_attachments/package.xml b/plugins/filesystem_attachments/package.xml
index 031a74297..49ec51934 100644
--- a/plugins/filesystem_attachments/package.xml
+++ b/plugins/filesystem_attachments/package.xml
@@ -34,7 +34,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/help/config.inc.php.dist b/plugins/help/config.inc.php.dist
index d440dbbcc..1dbc21753 100644
--- a/plugins/help/config.inc.php.dist
+++ b/plugins/help/config.inc.php.dist
@@ -1,5 +1,35 @@
<?php
// Help content iframe source
-// $rcmail_config['help_source'] = 'http://trac.roundcube.net/wiki';
-$rcmail_config['help_source'] = '';
+// %l will be replaced by the language code resolved using the 'help_language_map' option
+$rcmail_config['help_source'] = 'http://roundcube.net/doc/help/0.9/%l/';
+
+// Map task/action combinations to deep-links
+// Use '<task>/<action>' or only '<task>' strings as keys
+// The values will be appended to the 'help_source' URL
+$rcmail_config['help_index_map'] = array(
+ 'login' => 'login.html',
+ 'mail' => 'mail/index.html',
+ 'mail/compose' => 'mail/compose.html',
+ 'addressbook' => 'addressbook/index.html',
+ 'settings' => 'settings/index.html',
+ 'settings/preferences' => 'settings/preferences.html',
+ 'settings/folders' => 'settings/folders.html',
+ 'settings/identities' => 'settings/identities.html',
+);
+
+// Map to translate Roundcube language codes into help document languages
+// The '*' entry will be used as default
+$rcmail_config['help_language_map'] = array('*' => 'en_US');
+
+// Enter an absolute URL to a page displaying information about this webmail
+// Alternatively, create a HTML file under <this-plugin-dir>/content/about.html
+$rcmail_config['help_about_url'] = null;
+
+// Enter an absolute URL to a page displaying information about this webmail
+// Alternatively, put your license text to <this-plugin-dir>/content/license.html
+$rcmail_config['help_license_url'] = null;
+
+// Determine whether to open the help in a new window
+$rcmail_config['help_open_extwin'] = false;
+
diff --git a/plugins/help/content/about.html b/plugins/help/content/about.html
deleted file mode 100644
index 6e9632bec..000000000
--- a/plugins/help/content/about.html
+++ /dev/null
@@ -1,27 +0,0 @@
-<div id="helpabout" class="readtext">
-<h2 align="center">Copyright &copy; 2005-2012, The Roundcube Dev Team</h2>
-
-<p>
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License (with exceptions
-for skins &amp; plugins) as published by the Free Software Foundation,
-either version 3 of the License, or (at your option) any later version.
-</p>
-<p>
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-</p>
-<p>
-You should have received a copy of the GNU General Public License
-along with this program. If not, see <a href="http://www.gnu.org/licenses/">www.gnu.org/licenses</a>.
-</p>
-
-<p>
-For more details about licensing and the expections for skins and plugins
-see <a href="http://roundcube.net/license">roundcube.net/license</a>.
-</p>
-
-<p><br/>Website: <a href="http://roundcube.net">roundcube.net</a></p>
-</div>
diff --git a/plugins/help/content/license.html b/plugins/help/content/license.html
index 371dbffe1..9034d46f8 100644
--- a/plugins/help/content/license.html
+++ b/plugins/help/content/license.html
@@ -655,7 +655,7 @@ the &ldquo;copyright&rdquo; line and a pointer to where the full notice is found
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
+ along with this program. If not, see &lt;http://www.gnu.org/licenses/&gt;.
</pre>
<p>Also add information on how to contact you by electronic and paper mail.</p>
diff --git a/plugins/help/help.js b/plugins/help/help.js
new file mode 100644
index 000000000..59a93c537
--- /dev/null
+++ b/plugins/help/help.js
@@ -0,0 +1,25 @@
+/*
+ * Help plugin client script
+ * @version 1.4
+ */
+
+// hook into switch-task event to open the help window
+if (window.rcmail) {
+ rcmail.addEventListener('beforeswitch-task', function(prop) {
+ // catch clicks to help task button
+ if (prop == 'help') {
+ if (rcmail.task == 'help') // we're already there
+ return false;
+
+ var url = rcmail.url('help/index', { _rel: rcmail.task + (rcmail.env.action ? '/'+rcmail.env.action : '') });
+ if (rcmail.env.help_open_extwin) {
+ rcmail.open_window(url, 1020, false);
+ }
+ else {
+ rcmail.redirect(url, false);
+ }
+
+ return false;
+ }
+ });
+}
diff --git a/plugins/help/help.php b/plugins/help/help.php
index 69da6828e..37fd908a3 100644
--- a/plugins/help/help.php
+++ b/plugins/help/help.php
@@ -1,9 +1,10 @@
<?php
/**
- * Help Plugin
+ * Roundcube Help Plugin
*
* @author Aleksander 'A.L.E.C' Machniak
+ * @author Thomas Bruederli <thomas@roundcube.net>
* @license GNU GPLv3+
*
* Configuration (see config.inc.php.dist)
@@ -21,6 +22,7 @@ class help extends rcube_plugin
function init()
{
+ $this->load_config();
$this->add_texts('localization/', false);
// register task
@@ -31,6 +33,8 @@ class help extends rcube_plugin
$this->register_action('about', array($this, 'action'));
$this->register_action('license', array($this, 'action'));
+ $rcmail = rcmail::get_instance();
+
// add taskbar button
$this->add_button(array(
'command' => 'help',
@@ -40,6 +44,9 @@ class help extends rcube_plugin
'label' => 'help.help',
), 'taskbar');
+ $this->include_script('help.js');
+ $rcmail->output->set_env('help_open_extwin', $rcmail->config->get('help_open_extwin', false), true);
+
// add style for taskbar button (must be here) and Help UI
$skin_path = $this->local_skin_path();
if (is_file($this->home . "/$skin_path/help.css")) {
@@ -51,11 +58,10 @@ class help extends rcube_plugin
{
$rcmail = rcmail::get_instance();
- $this->load_config();
-
// register UI objects
$rcmail->output->add_handlers(array(
'helpcontent' => array($this, 'content'),
+ 'tablink' => array($this, 'tablink'),
));
if ($rcmail->action == 'about')
@@ -68,20 +74,52 @@ class help extends rcube_plugin
$rcmail->output->send('help.help');
}
+ function tablink($attrib)
+ {
+ $rcmail = rcmail::get_instance();
+ $attrib['name'] = 'helplink' . $attrib['action'];
+ $attrib['href'] = $rcmail->url(array('_action' => $attrib['action'], '_extwin' => !empty($_REQUEST['_extwin']) ? 1 : null));
+ return $rcmail->output->button($attrib);
+ }
+
function content($attrib)
{
$rcmail = rcmail::get_instance();
- if ($rcmail->action == 'about') {
- return @file_get_contents($this->home.'/content/about.html');
- }
- else if ($rcmail->action == 'license') {
- return @file_get_contents($this->home.'/content/license.html');
+ switch ($rcmail->action) {
+ case 'about':
+ if (is_readable($this->home . '/content/about.html')) {
+ return @file_get_contents($this->home . '/content/about.html');
+ }
+ $default = $rcmail->url(array('_task' => 'settings', '_action' => 'about', '_framed' => 1));
+ $src = $rcmail->config->get('help_about_url', $default);
+ break;
+
+ case 'license':
+ if (is_readable($this->home . '/content/license.html')) {
+ return @file_get_contents($this->home . '/content/license.html');
+ }
+ $src = $rcmail->config->get('help_license_url', 'http://www.gnu.org/licenses/gpl-3.0-standalone.html');
+ break;
+
+ default:
+ $src = $rcmail->config->get('help_source');
+
+ // resolve task/action for depp linking
+ $index_map = $rcmail->config->get('help_index_map', array());
+ $rel = $_REQUEST['_rel'];
+ list($task,$action) = explode('/', $rel);
+ if ($add = $index_map[$rel])
+ $src .= $add;
+ else if ($add = $index_map[$task])
+ $src .= $add;
+ break;
}
// default content: iframe
- if ($src = $rcmail->config->get('help_source'))
- $attrib['src'] = $src;
+ if (!empty($src)) {
+ $attrib['src'] = $this->resolve_language($src);
+ }
if (empty($attrib['id']))
$attrib['id'] = 'rcmailhelpcontent';
@@ -91,4 +129,13 @@ class help extends rcube_plugin
return $rcmail->output->frame($attrib);
}
+
+ private function resolve_language($path)
+ {
+ // resolve language placeholder
+ $rcmail = rcmail::get_instance();
+ $langmap = $rcmail->config->get('help_language_map', array('*' => 'en_US'));
+ $lang = !empty($langmap[$_SESSION['language']]) ? $langmap[$_SESSION['language']] : $langmap['*'];
+ return str_replace('%l', $lang, $path);
+ }
}
diff --git a/plugins/help/localization/de_DE.inc b/plugins/help/localization/de_DE.inc
index 70c50646e..250657da6 100644
--- a/plugins/help/localization/de_DE.inc
+++ b/plugins/help/localization/de_DE.inc
@@ -18,7 +18,7 @@
$labels = array();
$labels['help'] = 'Hilfe';
-$labels['about'] = '&Uuml;ber';
+$labels['about'] = 'Ãœber';
$labels['license'] = 'Lizenz';
?>
diff --git a/plugins/help/localization/gl_ES.inc b/plugins/help/localization/gl_ES.inc
index 432623751..e3e9e36ca 100644
--- a/plugins/help/localization/gl_ES.inc
+++ b/plugins/help/localization/gl_ES.inc
@@ -19,6 +19,6 @@
$labels = array();
$labels['help'] = 'Axuda';
$labels['about'] = 'Acerca de';
-$labels['license'] = 'Licencia';
+$labels['license'] = 'Licenza';
?>
diff --git a/plugins/help/package.xml b/plugins/help/package.xml
index 889efd17d..d39143ba1 100644
--- a/plugins/help/package.xml
+++ b/plugins/help/package.xml
@@ -5,7 +5,7 @@
http://pear.php.net/dtd/package-2.0.xsd">
<name>help</name>
<channel>pear.roundcube.net</channel>
- <summary>Help for Roundcube</summary>
+ <summary>Online Help for Roundcube</summary>
<description>Plugin adds a new item (Help) in taskbar.</description>
<lead>
<name>Aleksander Machniak</name>
@@ -13,10 +13,10 @@
<email>alec@alec.pl</email>
<active>yes</active>
</lead>
- <date>2012-11-11</date>
+ <date>2013-07-03</date>
<version>
- <release>1.3</release>
- <api>1.2</api>
+ <release>1.4</release>
+ <api>1.4</api>
</version>
<stability>
<release>stable</release>
@@ -31,7 +31,6 @@
<tasks:replace from="@package_version@" to="version" type="package-info"/>
</file>
<file name="config.inc.php.dist" role="data"></file>
- <file name="content/about.html" role="data"></file>
<file name="content/license.html" role="data"></file>
<file name="localization/bs_BA.inc" role="data"></file>
<file name="localization/ca_ES.inc" role="data"></file>
diff --git a/plugins/help/skins/classic/help.css b/plugins/help/skins/classic/help.css
index 8f67f111e..c45b8f0b0 100644
--- a/plugins/help/skins/classic/help.css
+++ b/plugins/help/skins/classic/help.css
@@ -5,9 +5,23 @@
background-image: url('help.gif');
}
+.extwin #tabsbar
+{
+ top: 21px;
+ left: 20px;
+ right: 100px;
+ border-bottom: 0;
+}
+
+.closelink {
+ position: absolute;
+ top: 20px;
+ right: 20px;
+}
+
.help-box
{
- overflow: auto;
+ overflow: auto;
background-color: #F2F2F2;
}
diff --git a/plugins/help/skins/classic/templates/help.html b/plugins/help/skins/classic/templates/help.html
index 2e430ecf3..3d5b22869 100644
--- a/plugins/help/skins/classic/templates/help.html
+++ b/plugins/help/skins/classic/templates/help.html
@@ -7,23 +7,28 @@
<script type="text/javascript">
function help_init_settings_tabs()
{
- var action, tab = '#helptabdefault';
+ var action, tab = '#helptabindex';
if (window.rcmail && (action = rcmail.env.action)) {
- tab = '#helptab' + (action ? action : 'default');
+ tab = '#helptab' + (action ? action : 'index');
}
$(tab).addClass('tablink-selected');
}
</script>
</head>
+<roundcube:if condition="env:extwin" />
+<body class="extwin">
+<roundcube:object name="message" id="message" />
+<roundcube:button name="close" type="link" label="close" class="closelink" onclick="self.close()" />
+<roundcube:else />
<body>
-
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
+<roundcube:endif />
<div id="tabsbar">
-<span id="helptabdefault" class="tablink"><roundcube:button name="helpdefault" href="?_task=help" type="link" label="help.help" title="help.help" /></span>
-<span id="helptababout" class="tablink"><roundcube:button name="helpabout" href="?_task=help&_action=about" type="link" label="help.about" title="help.about" class="tablink" /></span>
-<span id="helptablicense" class="tablink"><roundcube:button name="helplicense" href="?_task=help&_action=license" type="link" label="help.license" title="help.license" class="tablink" /></span>
+<span id="helptabindex" class="tablink"><roundcube:object name="tablink" action="index" type="link" label="help.help" title="help.help" /></span>
+<span id="helptababout" class="tablink"><roundcube:object name="tablink" action="about" type="link" label="help.about" title="help.about" class="tablink" /></span>
+<span id="helptablicense" class="tablink"><roundcube:object name="tablink" action="license" type="link" label="help.license" title="help.license" class="tablink" /></span>
<roundcube:container name="helptabs" id="helptabsbar" />
<script type="text/javascript"> if (window.rcmail) rcmail.add_onload(help_init_settings_tabs);</script>
</div>
diff --git a/plugins/help/skins/larry/help.css b/plugins/help/skins/larry/help.css
index c2e369af6..d9af6e15e 100644
--- a/plugins/help/skins/larry/help.css
+++ b/plugins/help/skins/larry/help.css
@@ -39,7 +39,6 @@
background: url(help.png) center -130px no-repeat;
}
-.iframebox.help_about,
.iframebox.help_license {
overflow: auto;
}
diff --git a/plugins/help/skins/larry/templates/help.html b/plugins/help/skins/larry/templates/help.html
index 39caaa62f..bfd3f1141 100644
--- a/plugins/help/skins/larry/templates/help.html
+++ b/plugins/help/skins/larry/templates/help.html
@@ -4,16 +4,16 @@
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
</head>
-<body>
+<roundcube:if condition="env:extwin" /><body class="extwin"><roundcube:else /><body><roundcube:endif />
<roundcube:include file="/includes/header.html" />
<div id="mainscreen">
<div id="helptoolbar" class="toolbar">
-<roundcube:button name="helpdefault" href="?_task=help" type="link" label="help.help" title="help.help" class="button help" />
-<roundcube:button name="helpabout" href="?_task=help&amp;_action=about" type="link" label="help.about" title="help.about" class="button about" />
-<roundcube:button name="helplicense" href="?_task=help&amp;_action=license" type="link" label="help.license" title="help.license" class="button license" />
+<roundcube:object name="tablink" action="index" type="link" label="help.help" title="help.help" class="button help" />
+<roundcube:object name="tablink" action="about" type="link" label="help.about" title="help.about" class="button about" />
+<roundcube:object name="tablink" action="license" type="link" label="help.license" title="help.license" class="button license" />
<roundcube:container name="helptabs" id="helptabsbar" />
</div>
diff --git a/plugins/jqueryui/jqueryui.php b/plugins/jqueryui/jqueryui.php
index db640d1aa..e9b3c215e 100644
--- a/plugins/jqueryui/jqueryui.php
+++ b/plugins/jqueryui/jqueryui.php
@@ -8,6 +8,7 @@
* @version 1.9.1
* @author Cor Bosman <roundcube@wa.ter.net>
* @author Thomas Bruederli <roundcube@gmail.com>
+ * @license GNU GPLv3+
*/
class jqueryui extends rcube_plugin
{
diff --git a/plugins/managesieve/Changelog b/plugins/managesieve/Changelog
index a5f325008..daee91a70 100644
--- a/plugins/managesieve/Changelog
+++ b/plugins/managesieve/Changelog
@@ -1,6 +1,9 @@
- Add vacation-seconds extension support (RFC 6131)
- Several script parser code improvements
- Support string list arguments in filter form (#1489018)
+- Support date, currendate and index tests - RFC5260 (#1488120)
+- Split plugin file into two files
+- Fix handling of &, <, > characters in scripts/filter names (#1489208)
* version 6.2 [2013-02-17]
-----------------------------------------------------------
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve.php b/plugins/managesieve/lib/Roundcube/rcube_sieve.php
index a04e3c2a4..3bd2978da 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve.php
@@ -6,18 +6,18 @@
* Copyright (C) 2008-2011, The Roundcube Dev Team
* Copyright (C) 2011, Kolab Systems AG
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
*/
// Managesieve Protocol: RFC5804
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
new file mode 100644
index 000000000..e92ba04d6
--- /dev/null
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_engine.php
@@ -0,0 +1,2122 @@
+<?php
+
+/**
+ * Managesieve (Sieve Filters) Engine
+ *
+ * Engine part of Managesieve plugin implementing UI and backend access.
+ *
+ * Copyright (C) 2008-2013, The Roundcube Dev Team
+ * Copyright (C) 2011-2013, Kolab Systems AG
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
+
+class rcube_sieve_engine
+{
+ private $rc;
+ private $sieve;
+ private $errors;
+ private $form;
+ private $tips = array();
+ private $script = array();
+ private $exts = array();
+ private $list;
+ private $active = array();
+ private $headers = array(
+ 'subject' => 'Subject',
+ 'from' => 'From',
+ 'to' => 'To',
+ );
+ private $addr_headers = array(
+ // Required
+ "from", "to", "cc", "bcc", "sender", "resent-from", "resent-to",
+ // Additional (RFC 822 / RFC 2822)
+ "reply-to", "resent-reply-to", "resent-sender", "resent-cc", "resent-bcc",
+ // Non-standard (RFC 2076, draft-palme-mailext-headers-08.txt)
+ "for-approval", "for-handling", "for-comment", "apparently-to", "errors-to",
+ "delivered-to", "return-receipt-to", "x-admin", "read-receipt-to",
+ "x-confirm-reading-to", "return-receipt-requested",
+ "registered-mail-reply-requested-by", "mail-followup-to", "mail-reply-to",
+ "abuse-reports-to", "x-complaints-to", "x-report-abuse-to",
+ // Undocumented
+ "x-beenthere",
+ );
+
+ const VERSION = '7.0';
+ const PROGNAME = 'Roundcube (Managesieve)';
+ const PORT = 4190;
+
+
+ /**
+ * Class constructor
+ */
+ function __construct($plugin)
+ {
+ $this->rc = rcmail::get_instance();
+ $this->plugin = $plugin;
+ }
+
+ /**
+ * Loads configuration, initializes plugin (including sieve connection)
+ */
+ function start()
+ {
+ // register UI objects
+ $this->rc->output->add_handlers(array(
+ 'filterslist' => array($this, 'filters_list'),
+ 'filtersetslist' => array($this, 'filtersets_list'),
+ 'filterframe' => array($this, 'filter_frame'),
+ 'filterform' => array($this, 'filter_form'),
+ 'filtersetform' => array($this, 'filterset_form'),
+ ));
+
+ // Get connection parameters
+ $host = $this->rc->config->get('managesieve_host', 'localhost');
+ $port = $this->rc->config->get('managesieve_port');
+ $tls = $this->rc->config->get('managesieve_usetls', false);
+
+ $host = rcube_utils::parse_host($host);
+ $host = rcube_utils::idn_to_ascii($host);
+
+ // remove tls:// prefix, set TLS flag
+ if (($host = preg_replace('|^tls://|i', '', $host, 1, $cnt)) && $cnt) {
+ $tls = true;
+ }
+
+ if (empty($port)) {
+ $port = getservbyname('sieve', 'tcp');
+ if (empty($port)) {
+ $port = self::PORT;
+ }
+ }
+
+ $plugin = $this->rc->plugins->exec_hook('managesieve_connect', array(
+ 'user' => $_SESSION['username'],
+ 'password' => $this->rc->decrypt($_SESSION['password']),
+ 'host' => $host,
+ 'port' => $port,
+ 'usetls' => $tls,
+ 'auth_type' => $this->rc->config->get('managesieve_auth_type'),
+ 'disabled' => $this->rc->config->get('managesieve_disabled_extensions'),
+ 'debug' => $this->rc->config->get('managesieve_debug', false),
+ 'auth_cid' => $this->rc->config->get('managesieve_auth_cid'),
+ 'auth_pw' => $this->rc->config->get('managesieve_auth_pw'),
+ ));
+
+ // try to connect to managesieve server and to fetch the script
+ $this->sieve = new rcube_sieve(
+ $plugin['user'],
+ $plugin['password'],
+ $plugin['host'],
+ $plugin['port'],
+ $plugin['auth_type'],
+ $plugin['usetls'],
+ $plugin['disabled'],
+ $plugin['debug'],
+ $plugin['auth_cid'],
+ $plugin['auth_pw']
+ );
+
+ if (!($error = $this->sieve->error())) {
+ // Get list of scripts
+ $list = $this->list_scripts();
+
+ if (!empty($_GET['_set']) || !empty($_POST['_set'])) {
+ $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
+ }
+ else if (!empty($_SESSION['managesieve_current'])) {
+ $script_name = $_SESSION['managesieve_current'];
+ }
+ else {
+ // get (first) active script
+ if (!empty($this->active[0])) {
+ $script_name = $this->active[0];
+ }
+ else if ($list) {
+ $script_name = $list[0];
+ }
+ // create a new (initial) script
+ else {
+ // if script not exists build default script contents
+ $script_file = $this->rc->config->get('managesieve_default');
+ $script_name = $this->rc->config->get('managesieve_script_name');
+
+ if (empty($script_name))
+ $script_name = 'roundcube';
+
+ if ($script_file && is_readable($script_file))
+ $content = file_get_contents($script_file);
+
+ // add script and set it active
+ if ($this->sieve->save_script($script_name, $content)) {
+ $this->activate_script($script_name);
+ $this->list[] = $script_name;
+ }
+ }
+ }
+
+ if ($script_name) {
+ $this->sieve->load($script_name);
+ }
+
+ $error = $this->sieve->error();
+ }
+
+ // finally set script objects
+ if ($error) {
+ switch ($error) {
+ case SIEVE_ERROR_CONNECTION:
+ case SIEVE_ERROR_LOGIN:
+ $this->rc->output->show_message('managesieve.filterconnerror', 'error');
+ break;
+ default:
+ $this->rc->output->show_message('managesieve.filterunknownerror', 'error');
+ break;
+ }
+
+ rcube::raise_error(array('code' => 403, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Unable to connect to managesieve on $host:$port"), true, false);
+
+ // to disable 'Add filter' button set env variable
+ $this->rc->output->set_env('filterconnerror', true);
+ $this->script = array();
+ }
+ else {
+ $this->exts = $this->sieve->get_extensions();
+ $this->script = $this->sieve->script->as_array();
+ $this->rc->output->set_env('currentset', $this->sieve->current);
+ $_SESSION['managesieve_current'] = $this->sieve->current;
+ }
+
+ return $error;
+ }
+
+ function actions()
+ {
+ $error = $this->start();
+
+ // Handle user requests
+ if ($action = rcube_utils::get_input_value('_act', rcube_utils::INPUT_GPC)) {
+ $fid = (int) rcube_utils::get_input_value('_fid', rcube_utils::INPUT_POST);
+
+ if ($action == 'delete' && !$error) {
+ if (isset($this->script[$fid])) {
+ if ($this->sieve->script->delete_rule($fid))
+ $result = $this->save_script();
+
+ if ($result === true) {
+ $this->rc->output->show_message('managesieve.filterdeleted', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'del', array('id' => $fid));
+ } else {
+ $this->rc->output->show_message('managesieve.filterdeleteerror', 'error');
+ }
+ }
+ }
+ else if ($action == 'move' && !$error) {
+ if (isset($this->script[$fid])) {
+ $to = (int) rcube_utils::get_input_value('_to', rcube_utils::INPUT_POST);
+ $rule = $this->script[$fid];
+
+ // remove rule
+ unset($this->script[$fid]);
+ $this->script = array_values($this->script);
+
+ // add at target position
+ if ($to >= count($this->script)) {
+ $this->script[] = $rule;
+ }
+ else {
+ $script = array();
+ foreach ($this->script as $idx => $r) {
+ if ($idx == $to)
+ $script[] = $rule;
+ $script[] = $r;
+ }
+ $this->script = $script;
+ }
+
+ $this->sieve->script->content = $this->script;
+ $result = $this->save_script();
+
+ if ($result === true) {
+ $result = $this->list_rules();
+
+ $this->rc->output->show_message('managesieve.moved', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'list',
+ array('list' => $result, 'clear' => true, 'set' => $to));
+ } else {
+ $this->rc->output->show_message('managesieve.moveerror', 'error');
+ }
+ }
+ }
+ else if ($action == 'act' && !$error) {
+ if (isset($this->script[$fid])) {
+ $rule = $this->script[$fid];
+ $disabled = $rule['disabled'] ? true : false;
+ $rule['disabled'] = !$disabled;
+ $result = $this->sieve->script->update_rule($fid, $rule);
+
+ if ($result !== false)
+ $result = $this->save_script();
+
+ if ($result === true) {
+ if ($rule['disabled'])
+ $this->rc->output->show_message('managesieve.deactivated', 'confirmation');
+ else
+ $this->rc->output->show_message('managesieve.activated', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'update',
+ array('id' => $fid, 'disabled' => $rule['disabled']));
+ } else {
+ if ($rule['disabled'])
+ $this->rc->output->show_message('managesieve.deactivateerror', 'error');
+ else
+ $this->rc->output->show_message('managesieve.activateerror', 'error');
+ }
+ }
+ }
+ else if ($action == 'setact' && !$error) {
+ $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
+ $result = $this->activate_script($script_name);
+ $kep14 = $this->rc->config->get('managesieve_kolab_master');
+
+ if ($result === true) {
+ $this->rc->output->set_env('active_sets', $this->active);
+ $this->rc->output->show_message('managesieve.setactivated', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'setact',
+ array('name' => $script_name, 'active' => true, 'all' => !$kep14));
+ } else {
+ $this->rc->output->show_message('managesieve.setactivateerror', 'error');
+ }
+ }
+ else if ($action == 'deact' && !$error) {
+ $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
+ $result = $this->deactivate_script($script_name);
+
+ if ($result === true) {
+ $this->rc->output->set_env('active_sets', $this->active);
+ $this->rc->output->show_message('managesieve.setdeactivated', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'setact',
+ array('name' => $script_name, 'active' => false));
+ } else {
+ $this->rc->output->show_message('managesieve.setdeactivateerror', 'error');
+ }
+ }
+ else if ($action == 'setdel' && !$error) {
+ $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
+ $result = $this->remove_script($script_name);
+
+ if ($result === true) {
+ $this->rc->output->show_message('managesieve.setdeleted', 'confirmation');
+ $this->rc->output->command('managesieve_updatelist', 'setdel',
+ array('name' => $script_name));
+ $this->rc->session->remove('managesieve_current');
+ } else {
+ $this->rc->output->show_message('managesieve.setdeleteerror', 'error');
+ }
+ }
+ else if ($action == 'setget') {
+ $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
+ $script = $this->sieve->get_script($script_name);
+
+ if (PEAR::isError($script))
+ exit;
+
+ $browser = new rcube_browser;
+
+ // send download headers
+ header("Content-Type: application/octet-stream");
+ header("Content-Length: ".strlen($script));
+
+ if ($browser->ie)
+ header("Content-Type: application/force-download");
+ if ($browser->ie && $browser->ver < 7)
+ $filename = rawurlencode(abbreviate_string($script_name, 55));
+ else if ($browser->ie)
+ $filename = rawurlencode($script_name);
+ else
+ $filename = addcslashes($script_name, '\\"');
+
+ header("Content-Disposition: attachment; filename=\"$filename.txt\"");
+ echo $script;
+ exit;
+ }
+ else if ($action == 'list') {
+ $result = $this->list_rules();
+
+ $this->rc->output->command('managesieve_updatelist', 'list', array('list' => $result));
+ }
+ else if ($action == 'ruleadd') {
+ $rid = rcube_utils::get_input_value('_rid', rcube_utils::INPUT_GPC);
+ $id = $this->genid();
+ $content = $this->rule_div($fid, $id, false);
+
+ $this->rc->output->command('managesieve_rulefill', $content, $id, $rid);
+ }
+ else if ($action == 'actionadd') {
+ $aid = rcube_utils::get_input_value('_aid', rcube_utils::INPUT_GPC);
+ $id = $this->genid();
+ $content = $this->action_div($fid, $id, false);
+
+ $this->rc->output->command('managesieve_actionfill', $content, $id, $aid);
+ }
+
+ $this->rc->output->send();
+ }
+ else if ($this->rc->task == 'mail') {
+ // Initialize the form
+ $rules = rcube_utils::get_input_value('r', rcube_utils::INPUT_GET);
+ if (!empty($rules)) {
+ $i = 0;
+ foreach ($rules as $rule) {
+ list($header, $value) = explode(':', $rule, 2);
+ $tests[$i] = array(
+ 'type' => 'contains',
+ 'test' => 'header',
+ 'arg1' => $header,
+ 'arg2' => $value,
+ );
+ $i++;
+ }
+
+ $this->form = array(
+ 'join' => count($tests) > 1 ? 'allof' : 'anyof',
+ 'name' => '',
+ 'tests' => $tests,
+ 'actions' => array(
+ 0 => array('type' => 'fileinto'),
+ 1 => array('type' => 'stop'),
+ ),
+ );
+ }
+ }
+
+ $this->send();
+ }
+
+ function save()
+ {
+ // Init plugin and handle managesieve connection
+ $error = $this->start();
+
+ // get request size limits (#1488648)
+ $max_post = max(array(
+ ini_get('max_input_vars'),
+ ini_get('suhosin.request.max_vars'),
+ ini_get('suhosin.post.max_vars'),
+ ));
+ $max_depth = max(array(
+ ini_get('suhosin.request.max_array_depth'),
+ ini_get('suhosin.post.max_array_depth'),
+ ));
+
+ // check request size limit
+ if ($max_post && count($_POST, COUNT_RECURSIVE) >= $max_post) {
+ rcube::raise_error(array(
+ 'code' => 500, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Request size limit exceeded (one of max_input_vars/suhosin.request.max_vars/suhosin.post.max_vars)"
+ ), true, false);
+ $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+ }
+ // check request depth limits
+ else if ($max_depth && count($_POST['_header']) > $max_depth) {
+ rcube::raise_error(array(
+ 'code' => 500, 'type' => 'php',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Request size limit exceeded (one of suhosin.request.max_array_depth/suhosin.post.max_array_depth)"
+ ), true, false);
+ $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+ }
+ // filters set add action
+ else if (!empty($_POST['_newset'])) {
+ $name = rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true);
+ $copy = rcube_utils::get_input_value('_copy', rcube_utils::INPUT_POST, true);
+ $from = rcube_utils::get_input_value('_from', rcube_utils::INPUT_POST);
+ $exceptions = $this->rc->config->get('managesieve_filename_exceptions');
+ $kolab = $this->rc->config->get('managesieve_kolab_master');
+ $name_uc = mb_strtolower($name);
+ $list = $this->list_scripts();
+
+ if (!$name) {
+ $this->errors['name'] = $this->plugin->gettext('cannotbeempty');
+ }
+ else if (mb_strlen($name) > 128) {
+ $this->errors['name'] = $this->plugin->gettext('nametoolong');
+ }
+ else if (!empty($exceptions) && in_array($name, (array)$exceptions)) {
+ $this->errors['name'] = $this->plugin->gettext('namereserved');
+ }
+ else if (!empty($kolab) && in_array($name_uc, array('MASTER', 'USER', 'MANAGEMENT'))) {
+ $this->errors['name'] = $this->plugin->gettext('namereserved');
+ }
+ else if (in_array($name, $list)) {
+ $this->errors['name'] = $this->plugin->gettext('setexist');
+ }
+ else if ($from == 'file') {
+ // from file
+ if (is_uploaded_file($_FILES['_file']['tmp_name'])) {
+ $file = file_get_contents($_FILES['_file']['tmp_name']);
+ $file = preg_replace('/\r/', '', $file);
+ // for security don't save script directly
+ // check syntax before, like this...
+ $this->sieve->load_script($file);
+ if (!$this->save_script($name)) {
+ $this->errors['file'] = $this->plugin->gettext('setcreateerror');
+ }
+ }
+ else { // upload failed
+ $err = $_FILES['_file']['error'];
+
+ if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
+ $msg = $this->rc->gettext(array('name' => 'filesizeerror',
+ 'vars' => array('size' =>
+ $this->rc->show_bytes(parse_bytes(ini_get('upload_max_filesize'))))));
+ }
+ else {
+ $this->errors['file'] = $this->plugin->gettext('fileuploaderror');
+ }
+ }
+ }
+ else if (!$this->sieve->copy($name, $from == 'set' ? $copy : '')) {
+ $error = 'managesieve.setcreateerror';
+ }
+
+ if (!$error && empty($this->errors)) {
+ // Find position of the new script on the list
+ $list[] = $name;
+ asort($list, SORT_LOCALE_STRING);
+ $list = array_values($list);
+ $index = array_search($name, $list);
+
+ $this->rc->output->show_message('managesieve.setcreated', 'confirmation');
+ $this->rc->output->command('parent.managesieve_updatelist', 'setadd',
+ array('name' => $name, 'index' => $index));
+ } else if ($msg) {
+ $this->rc->output->command('display_message', $msg, 'error');
+ } else if ($error) {
+ $this->rc->output->show_message($error, 'error');
+ }
+ }
+ // filter add/edit action
+ else if (isset($_POST['_name'])) {
+ $name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true));
+ $fid = trim(rcube_utils::get_input_value('_fid', rcube_utils::INPUT_POST));
+ $join = trim(rcube_utils::get_input_value('_join', rcube_utils::INPUT_POST));
+
+ // and arrays
+ $headers = rcube_utils::get_input_value('_header', rcube_utils::INPUT_POST);
+ $cust_headers = rcube_utils::get_input_value('_custom_header', rcube_utils::INPUT_POST);
+ $ops = rcube_utils::get_input_value('_rule_op', rcube_utils::INPUT_POST);
+ $sizeops = rcube_utils::get_input_value('_rule_size_op', rcube_utils::INPUT_POST);
+ $sizeitems = rcube_utils::get_input_value('_rule_size_item', rcube_utils::INPUT_POST);
+ $sizetargets = rcube_utils::get_input_value('_rule_size_target', rcube_utils::INPUT_POST);
+ $targets = rcube_utils::get_input_value('_rule_target', rcube_utils::INPUT_POST, true);
+ $mods = rcube_utils::get_input_value('_rule_mod', rcube_utils::INPUT_POST);
+ $mod_types = rcube_utils::get_input_value('_rule_mod_type', rcube_utils::INPUT_POST);
+ $body_trans = rcube_utils::get_input_value('_rule_trans', rcube_utils::INPUT_POST);
+ $body_types = rcube_utils::get_input_value('_rule_trans_type', rcube_utils::INPUT_POST, true);
+ $comparators = rcube_utils::get_input_value('_rule_comp', rcube_utils::INPUT_POST);
+ $indexes = rcube_utils::get_input_value('_rule_index', rcube_utils::INPUT_POST);
+ $lastindexes = rcube_utils::get_input_value('_rule_index_last', rcube_utils::INPUT_POST);
+ $dateheaders = rcube_utils::get_input_value('_rule_date_header', rcube_utils::INPUT_POST);
+ $dateparts = rcube_utils::get_input_value('_rule_date_part', rcube_utils::INPUT_POST);
+ $act_types = rcube_utils::get_input_value('_action_type', rcube_utils::INPUT_POST, true);
+ $mailboxes = rcube_utils::get_input_value('_action_mailbox', rcube_utils::INPUT_POST, true);
+ $act_targets = rcube_utils::get_input_value('_action_target', rcube_utils::INPUT_POST, true);
+ $area_targets = rcube_utils::get_input_value('_action_target_area', rcube_utils::INPUT_POST, true);
+ $reasons = rcube_utils::get_input_value('_action_reason', rcube_utils::INPUT_POST, true);
+ $addresses = rcube_utils::get_input_value('_action_addresses', rcube_utils::INPUT_POST, true);
+ $intervals = rcube_utils::get_input_value('_action_interval', rcube_utils::INPUT_POST);
+ $interval_types = rcube_utils::get_input_value('_action_interval_type', rcube_utils::INPUT_POST);
+ $subject = rcube_utils::get_input_value('_action_subject', rcube_utils::INPUT_POST, true);
+ $flags = rcube_utils::get_input_value('_action_flags', rcube_utils::INPUT_POST);
+ $varnames = rcube_utils::get_input_value('_action_varname', rcube_utils::INPUT_POST);
+ $varvalues = rcube_utils::get_input_value('_action_varvalue', rcube_utils::INPUT_POST);
+ $varmods = rcube_utils::get_input_value('_action_varmods', rcube_utils::INPUT_POST);
+ $notifyaddrs = rcube_utils::get_input_value('_action_notifyaddress', rcube_utils::INPUT_POST);
+ $notifybodies = rcube_utils::get_input_value('_action_notifybody', rcube_utils::INPUT_POST);
+ $notifymessages = rcube_utils::get_input_value('_action_notifymessage', rcube_utils::INPUT_POST);
+ $notifyfrom = rcube_utils::get_input_value('_action_notifyfrom', rcube_utils::INPUT_POST);
+ $notifyimp = rcube_utils::get_input_value('_action_notifyimportance', rcube_utils::INPUT_POST);
+
+ // we need a "hack" for radiobuttons
+ foreach ($sizeitems as $item)
+ $items[] = $item;
+
+ $this->form['disabled'] = $_POST['_disabled'] ? true : false;
+ $this->form['join'] = $join=='allof' ? true : false;
+ $this->form['name'] = $name;
+ $this->form['tests'] = array();
+ $this->form['actions'] = array();
+
+ if ($name == '')
+ $this->errors['name'] = $this->plugin->gettext('cannotbeempty');
+ else {
+ foreach($this->script as $idx => $rule)
+ if($rule['name'] == $name && $idx != $fid) {
+ $this->errors['name'] = $this->plugin->gettext('ruleexist');
+ break;
+ }
+ }
+
+ $i = 0;
+ // rules
+ if ($join == 'any') {
+ $this->form['tests'][0]['test'] = 'true';
+ }
+ else {
+ foreach ($headers as $idx => $header) {
+ // targets are indexed differently (assume form order)
+ $target = $this->strip_value(array_shift($targets), true);
+ $header = $this->strip_value($header);
+ $operator = $this->strip_value($ops[$idx]);
+ $comparator = $this->strip_value($comparators[$idx]);
+
+ if ($header == 'size') {
+ $sizeop = $this->strip_value($sizeops[$idx]);
+ $sizeitem = $this->strip_value($items[$idx]);
+ $sizetarget = $this->strip_value($sizetargets[$idx]);
+
+ $this->form['tests'][$i]['test'] = 'size';
+ $this->form['tests'][$i]['type'] = $sizeop;
+ $this->form['tests'][$i]['arg'] = $sizetarget;
+
+ if ($sizetarget == '')
+ $this->errors['tests'][$i]['sizetarget'] = $this->plugin->gettext('cannotbeempty');
+ else if (!preg_match('/^[0-9]+(K|M|G)?$/i', $sizetarget.$sizeitem, $m)) {
+ $this->errors['tests'][$i]['sizetarget'] = $this->plugin->gettext('forbiddenchars');
+ $this->form['tests'][$i]['item'] = $sizeitem;
+ }
+ else
+ $this->form['tests'][$i]['arg'] .= $m[1];
+ }
+ else if ($header == 'currentdate') {
+ $datepart = $this->strip_value($dateparts[$idx]);
+
+ if (preg_match('/^not/', $operator))
+ $this->form['tests'][$i]['not'] = true;
+ $type = preg_replace('/^not/', '', $operator);
+
+ if ($type == 'exists') {
+ $this->errors['tests'][$i]['op'] = true;
+ }
+
+ $this->form['tests'][$i]['test'] = 'currentdate';
+ $this->form['tests'][$i]['type'] = $type;
+ $this->form['tests'][$i]['part'] = $datepart;
+ $this->form['tests'][$i]['arg'] = $target;
+
+ if ($type != 'exists') {
+ if (!count($target)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
+ }
+ else if ($type != 'regex' && $type != 'matches') {
+ foreach ($target as $arg) {
+ if (!$this->validate_date_part($datepart, $arg)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('invaliddateformat');
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if ($header == 'date') {
+ $datepart = $this->strip_value($dateparts[$idx]);
+ $dateheader = $this->strip_value($dateheaders[$idx]);
+ $index = $this->strip_value($indexes[$idx]);
+ $indexlast = $this->strip_value($lastindexes[$idx]);
+
+ if (preg_match('/^not/', $operator))
+ $this->form['tests'][$i]['not'] = true;
+ $type = preg_replace('/^not/', '', $operator);
+
+ if ($type == 'exists') {
+ $this->errors['tests'][$i]['op'] = true;
+ }
+
+ if (!empty($index) && $mod != 'envelope') {
+ $this->form['tests'][$i]['index'] = intval($index);
+ $this->form['tests'][$i]['last'] = !empty($indexlast);
+ }
+
+ if (empty($dateheader)) {
+ $dateheader = 'Date';
+ }
+ else if (!preg_match('/^[\x21-\x39\x41-\x7E]+$/i', $dateheader)) {
+ $this->errors['tests'][$i]['dateheader'] = $this->plugin->gettext('forbiddenchars');
+ }
+
+ $this->form['tests'][$i]['test'] = 'date';
+ $this->form['tests'][$i]['type'] = $type;
+ $this->form['tests'][$i]['part'] = $datepart;
+ $this->form['tests'][$i]['arg'] = $target;
+ $this->form['tests'][$i]['header'] = $dateheader;
+
+ if ($type != 'exists') {
+ if (!count($target)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
+ }
+ else if ($type != 'regex' && $type != 'matches') {
+ foreach ($target as $arg) {
+ if (!$this->validate_date_part($datepart, $arg)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('invaliddateformat');
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if ($header == 'body') {
+ $trans = $this->strip_value($body_trans[$idx]);
+ $trans_type = $this->strip_value($body_types[$idx], true);
+
+ if (preg_match('/^not/', $operator))
+ $this->form['tests'][$i]['not'] = true;
+ $type = preg_replace('/^not/', '', $operator);
+
+ if ($type == 'exists') {
+ $this->errors['tests'][$i]['op'] = true;
+ }
+
+ $this->form['tests'][$i]['test'] = 'body';
+ $this->form['tests'][$i]['type'] = $type;
+ $this->form['tests'][$i]['arg'] = $target;
+
+ if (empty($target) && $type != 'exists') {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
+ }
+ else if (preg_match('/^(value|count)-/', $type)) {
+ foreach ($target as $target_value) {
+ if (!preg_match('/[0-9]+/', $target_value)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('forbiddenchars');
+ }
+ }
+ }
+
+ $this->form['tests'][$i]['part'] = $trans;
+ if ($trans == 'content') {
+ $this->form['tests'][$i]['content'] = $trans_type;
+ }
+ }
+ else {
+ $cust_header = $headers = $this->strip_value(array_shift($cust_headers));
+ $mod = $this->strip_value($mods[$idx]);
+ $mod_type = $this->strip_value($mod_types[$idx]);
+ $index = $this->strip_value($indexes[$idx]);
+ $indexlast = $this->strip_value($lastindexes[$idx]);
+
+ if (preg_match('/^not/', $operator))
+ $this->form['tests'][$i]['not'] = true;
+ $type = preg_replace('/^not/', '', $operator);
+
+ if (!empty($index) && $mod != 'envelope') {
+ $this->form['tests'][$i]['index'] = intval($index);
+ $this->form['tests'][$i]['last'] = !empty($indexlast);
+ }
+
+ if ($header == '...') {
+ if (!count($headers))
+ $this->errors['tests'][$i]['header'] = $this->plugin->gettext('cannotbeempty');
+ else {
+ foreach ($headers as $hr) {
+ // RFC2822: printable ASCII except colon
+ if (!preg_match('/^[\x21-\x39\x41-\x7E]+$/i', $hr)) {
+ $this->errors['tests'][$i]['header'] = $this->plugin->gettext('forbiddenchars');
+ }
+ }
+ }
+
+ if (empty($this->errors['tests'][$i]['header']))
+ $cust_header = (is_array($headers) && count($headers) == 1) ? $headers[0] : $headers;
+ }
+
+ if ($type == 'exists') {
+ $this->form['tests'][$i]['test'] = 'exists';
+ $this->form['tests'][$i]['arg'] = $header == '...' ? $cust_header : $header;
+ }
+ else {
+ $test = 'header';
+ $header = $header == '...' ? $cust_header : $header;
+
+ if ($mod == 'address' || $mod == 'envelope') {
+ $found = false;
+ if (empty($this->errors['tests'][$i]['header'])) {
+ foreach ((array)$header as $hdr) {
+ if (!in_array(strtolower(trim($hdr)), $this->addr_headers))
+ $found = true;
+ }
+ }
+ if (!$found)
+ $test = $mod;
+ }
+
+ $this->form['tests'][$i]['type'] = $type;
+ $this->form['tests'][$i]['test'] = $test;
+ $this->form['tests'][$i]['arg1'] = $header;
+ $this->form['tests'][$i]['arg2'] = $target;
+
+ if (empty($target)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
+ }
+ else if (preg_match('/^(value|count)-/', $type)) {
+ foreach ($target as $target_value) {
+ if (!preg_match('/[0-9]+/', $target_value)) {
+ $this->errors['tests'][$i]['target'] = $this->plugin->gettext('forbiddenchars');
+ }
+ }
+ }
+
+ if ($mod) {
+ $this->form['tests'][$i]['part'] = $mod_type;
+ }
+ }
+ }
+
+ if ($header != 'size' && $comparator) {
+ if (preg_match('/^(value|count)/', $this->form['tests'][$i]['type']))
+ $comparator = 'i;ascii-numeric';
+
+ $this->form['tests'][$i]['comparator'] = $comparator;
+ }
+
+ $i++;
+ }
+ }
+
+ $i = 0;
+ // actions
+ foreach($act_types as $idx => $type) {
+ $type = $this->strip_value($type);
+ $target = $this->strip_value($act_targets[$idx]);
+
+ switch ($type) {
+
+ case 'fileinto':
+ case 'fileinto_copy':
+ $mailbox = $this->strip_value($mailboxes[$idx], false, false);
+ $this->form['actions'][$i]['target'] = $this->mod_mailbox($mailbox, 'in');
+ if ($type == 'fileinto_copy') {
+ $type = 'fileinto';
+ $this->form['actions'][$i]['copy'] = true;
+ }
+ break;
+
+ case 'reject':
+ case 'ereject':
+ $target = $this->strip_value($area_targets[$idx]);
+ $this->form['actions'][$i]['target'] = str_replace("\r\n", "\n", $target);
+
+ // if ($target == '')
+// $this->errors['actions'][$i]['targetarea'] = $this->plugin->gettext('cannotbeempty');
+ break;
+
+ case 'redirect':
+ case 'redirect_copy':
+ $this->form['actions'][$i]['target'] = $target;
+
+ if ($this->form['actions'][$i]['target'] == '')
+ $this->errors['actions'][$i]['target'] = $this->plugin->gettext('cannotbeempty');
+ else if (!rcube_utils::check_email($this->form['actions'][$i]['target']))
+ $this->errors['actions'][$i]['target'] = $this->plugin->gettext('noemailwarning');
+
+ if ($type == 'redirect_copy') {
+ $type = 'redirect';
+ $this->form['actions'][$i]['copy'] = true;
+ }
+ break;
+
+ case 'addflag':
+ case 'setflag':
+ case 'removeflag':
+ $_target = array();
+ if (empty($flags[$idx])) {
+ $this->errors['actions'][$i]['target'] = $this->plugin->gettext('noflagset');
+ }
+ else {
+ foreach ($flags[$idx] as $flag) {
+ $_target[] = $this->strip_value($flag);
+ }
+ }
+ $this->form['actions'][$i]['target'] = $_target;
+ break;
+
+ case 'vacation':
+ $reason = $this->strip_value($reasons[$idx]);
+ $interval_type = $interval_types[$idx] == 'seconds' ? 'seconds' : 'days';
+ $this->form['actions'][$i]['reason'] = str_replace("\r\n", "\n", $reason);
+ $this->form['actions'][$i]['subject'] = $subject[$idx];
+ $this->form['actions'][$i]['addresses'] = array_shift($addresses);
+ $this->form['actions'][$i][$interval_type] = $intervals[$idx];
+// @TODO: vacation :mime, :from, :handle
+
+ foreach ((array)$this->form['actions'][$i]['addresses'] as $aidx => $address) {
+ if (!rcube_utils::check_email($address)) {
+ $this->errors['actions'][$i]['addresses'] = $this->plugin->gettext('noemailwarning');
+ break;
+ }
+ }
+
+ if ($this->form['actions'][$i]['reason'] == '')
+ $this->errors['actions'][$i]['reason'] = $this->plugin->gettext('cannotbeempty');
+ if ($this->form['actions'][$i][$interval_type] && !preg_match('/^[0-9]+$/', $this->form['actions'][$i][$interval_type]))
+ $this->errors['actions'][$i]['interval'] = $this->plugin->gettext('forbiddenchars');
+ break;
+
+ case 'set':
+ $this->form['actions'][$i]['name'] = $varnames[$idx];
+ $this->form['actions'][$i]['value'] = $varvalues[$idx];
+ foreach ((array)$varmods[$idx] as $v_m) {
+ $this->form['actions'][$i][$v_m] = true;
+ }
+
+ if (empty($varnames[$idx])) {
+ $this->errors['actions'][$i]['name'] = $this->plugin->gettext('cannotbeempty');
+ }
+ else if (!preg_match('/^[0-9a-z_]+$/i', $varnames[$idx])) {
+ $this->errors['actions'][$i]['name'] = $this->plugin->gettext('forbiddenchars');
+ }
+
+ if (!isset($varvalues[$idx]) || $varvalues[$idx] === '') {
+ $this->errors['actions'][$i]['value'] = $this->plugin->gettext('cannotbeempty');
+ }
+ break;
+
+ case 'notify':
+ if (empty($notifyaddrs[$idx])) {
+ $this->errors['actions'][$i]['address'] = $this->plugin->gettext('cannotbeempty');
+ }
+ else if (!rcube_utils::check_email($notifyaddrs[$idx])) {
+ $this->errors['actions'][$i]['address'] = $this->plugin->gettext('noemailwarning');
+ }
+ if (!empty($notifyfrom[$idx]) && !rcube_utils::check_email($notifyfrom[$idx])) {
+ $this->errors['actions'][$i]['from'] = $this->plugin->gettext('noemailwarning');
+ }
+ $this->form['actions'][$i]['address'] = $notifyaddrs[$idx];
+ $this->form['actions'][$i]['body'] = $notifybodies[$idx];
+ $this->form['actions'][$i]['message'] = $notifymessages[$idx];
+ $this->form['actions'][$i]['from'] = $notifyfrom[$idx];
+ $this->form['actions'][$i]['importance'] = $notifyimp[$idx];
+ break;
+ }
+
+ $this->form['actions'][$i]['type'] = $type;
+ $i++;
+ }
+
+ if (!$this->errors && !$error) {
+ // zapis skryptu
+ if (!isset($this->script[$fid])) {
+ $fid = $this->sieve->script->add_rule($this->form);
+ $new = true;
+ } else
+ $fid = $this->sieve->script->update_rule($fid, $this->form);
+
+ if ($fid !== false)
+ $save = $this->save_script();
+
+ if ($save && $fid !== false) {
+ $this->rc->output->show_message('managesieve.filtersaved', 'confirmation');
+ if ($this->rc->task != 'mail') {
+ $this->rc->output->command('parent.managesieve_updatelist',
+ isset($new) ? 'add' : 'update',
+ array(
+ 'name' => $this->form['name'],
+ 'id' => $fid,
+ 'disabled' => $this->form['disabled']
+ ));
+ }
+ else {
+ $this->rc->output->command('managesieve_dialog_close');
+ $this->rc->output->send('iframe');
+ }
+ }
+ else {
+ $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
+// $this->rc->output->send();
+ }
+ }
+ }
+
+ $this->send();
+ }
+
+ private function send()
+ {
+ // Handle form action
+ if (isset($_GET['_framed']) || isset($_POST['_framed'])) {
+ if (isset($_GET['_newset']) || isset($_POST['_newset'])) {
+ $this->rc->output->send('managesieve.setedit');
+ }
+ else {
+ $this->rc->output->send('managesieve.filteredit');
+ }
+ } else {
+ $this->rc->output->set_pagetitle($this->plugin->gettext('filters'));
+ $this->rc->output->send('managesieve.managesieve');
+ }
+ }
+
+ // return the filters list as HTML table
+ function filters_list($attrib)
+ {
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmfilterslist';
+
+ // define list of cols to be displayed
+ $a_show_cols = array('name');
+
+ $result = $this->list_rules();
+
+ // create XHTML table
+ $out = $this->rc->table_output($attrib, $result, $a_show_cols, 'id');
+
+ // set client env
+ $this->rc->output->add_gui_object('filterslist', $attrib['id']);
+ $this->rc->output->include_script('list.js');
+
+ // add some labels to client
+ $this->rc->output->add_label('managesieve.filterdeleteconfirm');
+
+ return $out;
+ }
+
+ // return the filters list as <SELECT>
+ function filtersets_list($attrib, $no_env = false)
+ {
+ // add id to message list table if not specified
+ if (!strlen($attrib['id']))
+ $attrib['id'] = 'rcmfiltersetslist';
+
+ $list = $this->list_scripts();
+
+ if ($list) {
+ asort($list, SORT_LOCALE_STRING);
+ }
+
+ if (!empty($attrib['type']) && $attrib['type'] == 'list') {
+ // define list of cols to be displayed
+ $a_show_cols = array('name');
+
+ if ($list) {
+ foreach ($list as $idx => $set) {
+ $scripts['S'.$idx] = $set;
+ $result[] = array(
+ 'name' => $set,
+ 'id' => 'S'.$idx,
+ 'class' => !in_array($set, $this->active) ? 'disabled' : '',
+ );
+ }
+ }
+
+ // create XHTML table
+ $out = $this->rc->table_output($attrib, $result, $a_show_cols, 'id');
+
+ $this->rc->output->set_env('filtersets', $scripts);
+ $this->rc->output->include_script('list.js');
+ }
+ else {
+ $select = new html_select(array('name' => '_set', 'id' => $attrib['id'],
+ 'onchange' => $this->rc->task != 'mail' ? 'rcmail.managesieve_set()' : ''));
+
+ if ($list) {
+ foreach ($list as $set)
+ $select->add($set, $set);
+ }
+
+ $out = $select->show($this->sieve->current);
+ }
+
+ // set client env
+ if (!$no_env) {
+ $this->rc->output->add_gui_object('filtersetslist', $attrib['id']);
+ $this->rc->output->add_label('managesieve.setdeleteconfirm');
+ }
+
+ return $out;
+ }
+
+ function filter_frame($attrib)
+ {
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmfilterframe';
+
+ $attrib['name'] = $attrib['id'];
+
+ $this->rc->output->set_env('contentframe', $attrib['name']);
+ $this->rc->output->set_env('blankpage', $attrib['src'] ?
+ $this->rc->output->abs_url($attrib['src']) : 'program/resources/blank.gif');
+
+ return $this->rc->output->frame($attrib);
+ }
+
+ function filterset_form($attrib)
+ {
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmfiltersetform';
+
+ $out = '<form name="filtersetform" action="./" method="post" enctype="multipart/form-data">'."\n";
+
+ $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $this->rc->task));
+ $hiddenfields->add(array('name' => '_action', 'value' => 'plugin.managesieve-save'));
+ $hiddenfields->add(array('name' => '_framed', 'value' => ($_POST['_framed'] || $_GET['_framed'] ? 1 : 0)));
+ $hiddenfields->add(array('name' => '_newset', 'value' => 1));
+
+ $out .= $hiddenfields->show();
+
+ $name = rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST);
+ $copy = rcube_utils::get_input_value('_copy', rcube_utils::INPUT_POST);
+ $selected = rcube_utils::get_input_value('_from', rcube_utils::INPUT_POST);
+
+ // filter set name input
+ $input_name = new html_inputfield(array('name' => '_name', 'id' => '_name', 'size' => 30,
+ 'class' => ($this->errors['name'] ? 'error' : '')));
+
+ $out .= sprintf('<label for="%s"><b>%s:</b></label> %s<br /><br />',
+ '_name', rcube::Q($this->plugin->gettext('filtersetname')), $input_name->show($name));
+
+ $out .="\n<fieldset class=\"itemlist\"><legend>" . $this->plugin->gettext('filters') . ":</legend>\n";
+ $out .= '<input type="radio" id="from_none" name="_from" value="none"'
+ .(!$selected || $selected=='none' ? ' checked="checked"' : '').'></input>';
+ $out .= sprintf('<label for="%s">%s</label> ', 'from_none', rcube::Q($this->plugin->gettext('none')));
+
+ // filters set list
+ $list = $this->list_scripts();
+ $select = new html_select(array('name' => '_copy', 'id' => '_copy'));
+
+ if (is_array($list)) {
+ asort($list, SORT_LOCALE_STRING);
+
+ if (!$copy)
+ $copy = $_SESSION['managesieve_current'];
+
+ foreach ($list as $set) {
+ $select->add($set, $set);
+ }
+
+ $out .= '<br /><input type="radio" id="from_set" name="_from" value="set"'
+ .($selected=='set' ? ' checked="checked"' : '').'></input>';
+ $out .= sprintf('<label for="%s">%s:</label> ', 'from_set', rcube::Q($this->plugin->gettext('fromset')));
+ $out .= $select->show($copy);
+ }
+
+ // script upload box
+ $upload = new html_inputfield(array('name' => '_file', 'id' => '_file', 'size' => 30,
+ 'type' => 'file', 'class' => ($this->errors['file'] ? 'error' : '')));
+
+ $out .= '<br /><input type="radio" id="from_file" name="_from" value="file"'
+ .($selected=='file' ? ' checked="checked"' : '').'></input>';
+ $out .= sprintf('<label for="%s">%s:</label> ', 'from_file', rcube::Q($this->plugin->gettext('fromfile')));
+ $out .= $upload->show();
+ $out .= '</fieldset>';
+
+ $this->rc->output->add_gui_object('sieveform', 'filtersetform');
+
+ if ($this->errors['name'])
+ $this->add_tip('_name', $this->errors['name'], true);
+ if ($this->errors['file'])
+ $this->add_tip('_file', $this->errors['file'], true);
+
+ $this->print_tips();
+
+ return $out;
+ }
+
+
+ function filter_form($attrib)
+ {
+ if (!$attrib['id'])
+ $attrib['id'] = 'rcmfilterform';
+
+ $fid = rcube_utils::get_input_value('_fid', rcube_utils::INPUT_GPC);
+ $scr = isset($this->form) ? $this->form : $this->script[$fid];
+
+ $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $this->rc->task));
+ $hiddenfields->add(array('name' => '_action', 'value' => 'plugin.managesieve-save'));
+ $hiddenfields->add(array('name' => '_framed', 'value' => ($_POST['_framed'] || $_GET['_framed'] ? 1 : 0)));
+ $hiddenfields->add(array('name' => '_fid', 'value' => $fid));
+
+ $out = '<form name="filterform" action="./" method="post">'."\n";
+ $out .= $hiddenfields->show();
+
+ // 'any' flag
+ if (sizeof($scr['tests']) == 1 && $scr['tests'][0]['test'] == 'true' && !$scr['tests'][0]['not'])
+ $any = true;
+
+ // filter name input
+ $field_id = '_name';
+ $input_name = new html_inputfield(array('name' => '_name', 'id' => $field_id, 'size' => 30,
+ 'class' => ($this->errors['name'] ? 'error' : '')));
+
+ if ($this->errors['name'])
+ $this->add_tip($field_id, $this->errors['name'], true);
+
+ if (isset($scr))
+ $input_name = $input_name->show($scr['name']);
+ else
+ $input_name = $input_name->show();
+
+ $out .= sprintf("\n<label for=\"%s\"><b>%s:</b></label> %s\n",
+ $field_id, rcube::Q($this->plugin->gettext('filtername')), $input_name);
+
+ // filter set selector
+ if ($this->rc->task == 'mail') {
+ $out .= sprintf("\n&nbsp;<label for=\"%s\"><b>%s:</b></label> %s\n",
+ $field_id, rcube::Q($this->plugin->gettext('filterset')),
+ $this->filtersets_list(array('id' => 'sievescriptname'), true));
+ }
+
+ $out .= '<br /><br /><fieldset><legend>' . rcube::Q($this->plugin->gettext('messagesrules')) . "</legend>\n";
+
+ // any, allof, anyof radio buttons
+ $field_id = '_allof';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'allof',
+ 'onclick' => 'rule_join_radio(\'allof\')', 'class' => 'radio'));
+
+ if (isset($scr) && !$any)
+ $input_join = $input_join->show($scr['join'] ? 'allof' : '');
+ else
+ $input_join = $input_join->show();
+
+ $out .= sprintf("%s<label for=\"%s\">%s</label>&nbsp;\n",
+ $input_join, $field_id, rcube::Q($this->plugin->gettext('filterallof')));
+
+ $field_id = '_anyof';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'anyof',
+ 'onclick' => 'rule_join_radio(\'anyof\')', 'class' => 'radio'));
+
+ if (isset($scr) && !$any)
+ $input_join = $input_join->show($scr['join'] ? '' : 'anyof');
+ else
+ $input_join = $input_join->show('anyof'); // default
+
+ $out .= sprintf("%s<label for=\"%s\">%s</label>\n",
+ $input_join, $field_id, rcube::Q($this->plugin->gettext('filteranyof')));
+
+ $field_id = '_any';
+ $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'any',
+ 'onclick' => 'rule_join_radio(\'any\')', 'class' => 'radio'));
+
+ $input_join = $input_join->show($any ? 'any' : '');
+
+ $out .= sprintf("%s<label for=\"%s\">%s</label>\n",
+ $input_join, $field_id, rcube::Q($this->plugin->gettext('filterany')));
+
+ $rows_num = isset($scr) ? sizeof($scr['tests']) : 1;
+
+ $out .= '<div id="rules"'.($any ? ' style="display: none"' : '').'>';
+ for ($x=0; $x<$rows_num; $x++)
+ $out .= $this->rule_div($fid, $x);
+ $out .= "</div>\n";
+
+ $out .= "</fieldset>\n";
+
+ // actions
+ $out .= '<fieldset><legend>' . rcube::Q($this->plugin->gettext('messagesactions')) . "</legend>\n";
+
+ $rows_num = isset($scr) ? sizeof($scr['actions']) : 1;
+
+ $out .= '<div id="actions">';
+ for ($x=0; $x<$rows_num; $x++)
+ $out .= $this->action_div($fid, $x);
+ $out .= "</div>\n";
+
+ $out .= "</fieldset>\n";
+
+ $this->print_tips();
+
+ if ($scr['disabled']) {
+ $this->rc->output->set_env('rule_disabled', true);
+ }
+ $this->rc->output->add_label(
+ 'managesieve.ruledeleteconfirm',
+ 'managesieve.actiondeleteconfirm'
+ );
+ $this->rc->output->add_gui_object('sieveform', 'filterform');
+
+ return $out;
+ }
+
+ function rule_div($fid, $id, $div=true)
+ {
+ $rule = isset($this->form) ? $this->form['tests'][$id] : $this->script[$fid]['tests'][$id];
+ $rows_num = isset($this->form) ? sizeof($this->form['tests']) : sizeof($this->script[$fid]['tests']);
+
+ // headers select
+ $select_header = new html_select(array('name' => "_header[]", 'id' => 'header'.$id,
+ 'onchange' => 'rule_header_select(' .$id .')'));
+
+ foreach ($this->headers as $name => $val)
+ $select_header->add(rcube::Q($this->plugin->gettext($name)), Q($val));
+ $select_header->add(rcube::Q($this->plugin->gettext('...')), '...');
+ if (in_array('body', $this->exts))
+ $select_header->add(rcube::Q($this->plugin->gettext('body')), 'body');
+ $select_header->add(rcube::Q($this->plugin->gettext('size')), 'size');
+ if (in_array('date', $this->exts)) {
+ $select_header->add(rcube::Q($this->plugin->gettext('datetest')), 'date');
+ $select_header->add(rcube::Q($this->plugin->gettext('currdate')), 'currentdate');
+ }
+
+ if (isset($rule['test'])) {
+ if (in_array($rule['test'], array('header', 'address', 'envelope'))
+ && !is_array($rule['arg1']) && in_array($rule['arg1'], $this->headers)
+ ) {
+ $test = $rule['arg1'];
+ }
+ else if ($rule['test'] == 'exists'
+ && !is_array($rule['arg']) && in_array($rule['arg'], $this->headers)
+ ) {
+ $test = $rule['arg'];
+ }
+ else if (in_array($rule['test'], array('size', 'body', 'date', 'currentdate'))) {
+ $test = $rule['test'];
+ }
+ else if ($rule['test'] != 'true') {
+ $test = '...';
+ }
+ }
+
+ $aout = $select_header->show($test);
+
+ // custom headers input
+ if (isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope'))) {
+ $custom = (array) $rule['arg1'];
+ if (count($custom) == 1 && isset($this->headers[strtolower($custom[0])])) {
+ unset($custom);
+ }
+ }
+ else if (isset($rule['test']) && $rule['test'] == 'exists') {
+ $custom = (array) $rule['arg'];
+ if (count($custom) == 1 && isset($this->headers[strtolower($custom[0])])) {
+ unset($custom);
+ }
+ }
+
+ $tout = $this->list_input($id, 'custom_header', $custom, isset($custom),
+ $this->error_class($id, 'test', 'header', 'custom_header'), 15) . "\n";
+
+ // matching type select (operator)
+ $select_op = new html_select(array('name' => "_rule_op[]", 'id' => 'rule_op'.$id,
+ 'style' => 'display:' .($rule['test']!='size' ? 'inline' : 'none'),
+ 'class' => 'operator_selector',
+ 'onchange' => 'rule_op_select(this, '.$id.')'));
+ $select_op->add(rcube::Q($this->plugin->gettext('filtercontains')), 'contains');
+ $select_op->add(rcube::Q($this->plugin->gettext('filternotcontains')), 'notcontains');
+ $select_op->add(rcube::Q($this->plugin->gettext('filteris')), 'is');
+ $select_op->add(rcube::Q($this->plugin->gettext('filterisnot')), 'notis');
+ $select_op->add(rcube::Q($this->plugin->gettext('filterexists')), 'exists');
+ $select_op->add(rcube::Q($this->plugin->gettext('filternotexists')), 'notexists');
+ $select_op->add(rcube::Q($this->plugin->gettext('filtermatches')), 'matches');
+ $select_op->add(rcube::Q($this->plugin->gettext('filternotmatches')), 'notmatches');
+ if (in_array('regex', $this->exts)) {
+ $select_op->add(rcube::Q($this->plugin->gettext('filterregex')), 'regex');
+ $select_op->add(rcube::Q($this->plugin->gettext('filternotregex')), 'notregex');
+ }
+ if (in_array('relational', $this->exts)) {
+ $select_op->add(rcube::Q($this->plugin->gettext('countisgreaterthan')), 'count-gt');
+ $select_op->add(rcube::Q($this->plugin->gettext('countisgreaterthanequal')), 'count-ge');
+ $select_op->add(rcube::Q($this->plugin->gettext('countislessthan')), 'count-lt');
+ $select_op->add(rcube::Q($this->plugin->gettext('countislessthanequal')), 'count-le');
+ $select_op->add(rcube::Q($this->plugin->gettext('countequals')), 'count-eq');
+ $select_op->add(rcube::Q($this->plugin->gettext('countnotequals')), 'count-ne');
+ $select_op->add(rcube::Q($this->plugin->gettext('valueisgreaterthan')), 'value-gt');
+ $select_op->add(rcube::Q($this->plugin->gettext('valueisgreaterthanequal')), 'value-ge');
+ $select_op->add(rcube::Q($this->plugin->gettext('valueislessthan')), 'value-lt');
+ $select_op->add(rcube::Q($this->plugin->gettext('valueislessthanequal')), 'value-le');
+ $select_op->add(rcube::Q($this->plugin->gettext('valueequals')), 'value-eq');
+ $select_op->add(rcube::Q($this->plugin->gettext('valuenotequals')), 'value-ne');
+ }
+
+ // (current)date part select
+ if (in_array('date', $this->exts) || in_array('currentdate', $this->exts)) {
+ $date_parts = array('date', 'iso8601', 'std11', 'julian', 'time',
+ 'year', 'month', 'day', 'hour', 'minute', 'second', 'weekday', 'zone');
+ $select_dp = new html_select(array('name' => "_rule_date_part[]", 'id' => 'rule_date_part'.$id,
+ 'style' => $rule['test'] == 'currentdate' || $rule['test'] == 'date' ? '' : 'display:none',
+ 'class' => 'datepart_selector',
+ ));
+
+ foreach ($date_parts as $part) {
+ $select_dp->add(rcube::Q($this->plugin->gettext($part)), $part);
+ }
+
+ $tout .= $select_dp->show($rule['test'] == 'currentdate' || $rule['test'] == 'date' ? $rule['part'] : '');
+ }
+
+ // target(s) input
+ if (in_array($rule['test'], array('header', 'address', 'envelope'))) {
+ $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
+ $target = $rule['arg2'];
+ }
+ else if (in_array($rule['test'], array('body', 'date', 'currentdate'))) {
+ $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
+ $target = $rule['arg'];
+ }
+ else if ($rule['test'] == 'size') {
+ $test = '';
+ $target = '';
+ if (preg_match('/^([0-9]+)(K|M|G)?$/', $rule['arg'], $matches)) {
+ $sizetarget = $matches[1];
+ $sizeitem = $matches[2];
+ }
+ else {
+ $sizetarget = $rule['arg'];
+ $sizeitem = $rule['item'];
+ }
+ }
+ else {
+ $test = ($rule['not'] ? 'not' : '').$rule['test'];
+ $target = '';
+ }
+
+ $tout .= $select_op->show($test);
+ $tout .= $this->list_input($id, 'rule_target', $target,
+ $rule['test'] != 'size' && $rule['test'] != 'exists',
+ $this->error_class($id, 'test', 'target', 'rule_target')) . "\n";
+
+ $select_size_op = new html_select(array('name' => "_rule_size_op[]", 'id' => 'rule_size_op'.$id));
+ $select_size_op->add(rcube::Q($this->plugin->gettext('filterover')), 'over');
+ $select_size_op->add(rcube::Q($this->plugin->gettext('filterunder')), 'under');
+
+ $tout .= '<div id="rule_size' .$id. '" style="display:' . ($rule['test']=='size' ? 'inline' : 'none') .'">';
+ $tout .= $select_size_op->show($rule['test']=='size' ? $rule['type'] : '');
+ $tout .= '<input type="text" name="_rule_size_target[]" id="rule_size_i'.$id.'" value="'.$sizetarget.'" size="10" '
+ . $this->error_class($id, 'test', 'sizetarget', 'rule_size_i') .' />
+ <label><input type="radio" name="_rule_size_item['.$id.']" value=""'
+ . (!$sizeitem ? ' checked="checked"' : '') .' class="radio" />'.$this->rc->gettext('B').'</label>
+ <label><input type="radio" name="_rule_size_item['.$id.']" value="K"'
+ . ($sizeitem=='K' ? ' checked="checked"' : '') .' class="radio" />'.$this->rc->gettext('KB').'</label>
+ <label><input type="radio" name="_rule_size_item['.$id.']" value="M"'
+ . ($sizeitem=='M' ? ' checked="checked"' : '') .' class="radio" />'.$this->rc->gettext('MB').'</label>
+ <label><input type="radio" name="_rule_size_item['.$id.']" value="G"'
+ . ($sizeitem=='G' ? ' checked="checked"' : '') .' class="radio" />'.$this->rc->gettext('GB').'</label>';
+ $tout .= '</div>';
+
+ // Advanced modifiers (address, envelope)
+ $select_mod = new html_select(array('name' => "_rule_mod[]", 'id' => 'rule_mod_op'.$id,
+ 'onchange' => 'rule_mod_select(' .$id .')'));
+ $select_mod->add(rcube::Q($this->plugin->gettext('none')), '');
+ $select_mod->add(rcube::Q($this->plugin->gettext('address')), 'address');
+ if (in_array('envelope', $this->exts))
+ $select_mod->add(rcube::Q($this->plugin->gettext('envelope')), 'envelope');
+
+ $select_type = new html_select(array('name' => "_rule_mod_type[]", 'id' => 'rule_mod_type'.$id));
+ $select_type->add(rcube::Q($this->plugin->gettext('allparts')), 'all');
+ $select_type->add(rcube::Q($this->plugin->gettext('domain')), 'domain');
+ $select_type->add(rcube::Q($this->plugin->gettext('localpart')), 'localpart');
+ if (in_array('subaddress', $this->exts)) {
+ $select_type->add(rcube::Q($this->plugin->gettext('user')), 'user');
+ $select_type->add(rcube::Q($this->plugin->gettext('detail')), 'detail');
+ }
+
+ $need_mod = $rule['test'] != 'size' && $rule['test'] != 'body';
+ $mout = '<div id="rule_mod' .$id. '" class="adv"' . (!$need_mod ? ' style="display:none"' : '') . '>';
+ $mout .= ' <span class="label">' . rcube::Q($this->plugin->gettext('modifier')) . ' </span>';
+ $mout .= $select_mod->show($rule['test']);
+ $mout .= ' <span id="rule_mod_type' . $id . '"';
+ $mout .= ' style="display:' . (in_array($rule['test'], array('address', 'envelope')) ? 'inline' : 'none') .'">';
+ $mout .= rcube::Q($this->plugin->gettext('modtype')) . ' ';
+ $mout .= $select_type->show($rule['part']);
+ $mout .= '</span>';
+ $mout .= '</div>';
+
+ // Advanced modifiers (body transformations)
+ $select_mod = new html_select(array('name' => "_rule_trans[]", 'id' => 'rule_trans_op'.$id,
+ 'onchange' => 'rule_trans_select(' .$id .')'));
+ $select_mod->add(rcube::Q($this->plugin->gettext('text')), 'text');
+ $select_mod->add(rcube::Q($this->plugin->gettext('undecoded')), 'raw');
+ $select_mod->add(rcube::Q($this->plugin->gettext('contenttype')), 'content');
+
+ $mout .= '<div id="rule_trans' .$id. '" class="adv"' . ($rule['test'] != 'body' ? ' style="display:none"' : '') . '>';
+ $mout .= '<span class="label">' . rcube::Q($this->plugin->gettext('modifier')) . '</span>';
+ $mout .= $select_mod->show($rule['part']);
+ $mout .= '<input type="text" name="_rule_trans_type[]" id="rule_trans_type'.$id
+ . '" value="'.(is_array($rule['content']) ? implode(',', $rule['content']) : $rule['content'])
+ .'" size="20"' . ($rule['part'] != 'content' ? ' style="display:none"' : '')
+ . $this->error_class($id, 'test', 'part', 'rule_trans_type') .' />';
+ $mout .= '</div>';
+
+ // Advanced modifiers (body transformations)
+ $select_comp = new html_select(array('name' => "_rule_comp[]", 'id' => 'rule_comp_op'.$id));
+ $select_comp->add(rcube::Q($this->plugin->gettext('default')), '');
+ $select_comp->add(rcube::Q($this->plugin->gettext('octet')), 'i;octet');
+ $select_comp->add(rcube::Q($this->plugin->gettext('asciicasemap')), 'i;ascii-casemap');
+ if (in_array('comparator-i;ascii-numeric', $this->exts)) {
+ $select_comp->add(rcube::Q($this->plugin->gettext('asciinumeric')), 'i;ascii-numeric');
+ }
+
+ // Comparators
+ $mout .= '<div id="rule_comp' .$id. '" class="adv"' . ($rule['test'] == 'size' ? ' style="display:none"' : '') . '>';
+ $mout .= '<span class="label">' . rcube::Q($this->plugin->gettext('comparator')) . '</span>';
+ $mout .= $select_comp->show($rule['comparator']);
+ $mout .= '</div>';
+
+ // Date header
+ if (in_array('date', $this->exts)) {
+ $mout .= '<div id="rule_date_header_div' .$id. '" class="adv"'. ($rule['test'] != 'date' ? ' style="display:none"' : '') .'>';
+ $mout .= '<span class="label">' . rcube::Q($this->plugin->gettext('dateheader')) . '</span>';
+ $mout .= '<input type="text" name="_rule_date_header[]" id="rule_date_header'.$id
+ . '" value="'. Q($rule['test'] == 'date' ? $rule['header'] : '')
+ . '" size="15"' . $this->error_class($id, 'test', 'dateheader', 'rule_date_header') .' />';
+ $mout .= '</div>';
+ }
+
+ // Index
+ if (in_array('index', $this->exts)) {
+ $need_index = in_array($rule['test'], array('header', ', address', 'date'));
+ $mout .= '<div id="rule_index_div' .$id. '" class="adv"'. (!$need_index ? ' style="display:none"' : '') .'>';
+ $mout .= '<span class="label">' . rcube::Q($this->plugin->gettext('index')) . '</span>';
+ $mout .= '<input type="text" name="_rule_index[]" id="rule_index'.$id
+ . '" value="'. ($rule['index'] ? intval($rule['index']) : '')
+ . '" size="3"' . $this->error_class($id, 'test', 'index', 'rule_index') .' />';
+ $mout .= '&nbsp;<input type="checkbox" name="_rule_index_last[]" id="rule_index_last'.$id
+ . '" value="1"' . (!empty($rule['last']) ? ' checked="checked"' : '') . ' />'
+ . '<label for="rule_index_last'.$id.'">'.rcube::Q($this->plugin->gettext('indexlast')).'</label>';
+ $mout .= '</div>';
+ }
+
+ // Build output table
+ $out = $div ? '<div class="rulerow" id="rulerow' .$id .'">'."\n" : '';
+ $out .= '<table><tr>';
+ $out .= '<td class="advbutton">';
+ $out .= '<a href="#" id="ruleadv' . $id .'" title="'. rcube::Q($this->plugin->gettext('advancedopts')). '"
+ onclick="rule_adv_switch(' . $id .', this)" class="show">&nbsp;&nbsp;</a>';
+ $out .= '</td>';
+ $out .= '<td class="rowactions">' . $aout . '</td>';
+ $out .= '<td class="rowtargets">' . $tout . "\n";
+ $out .= '<div id="rule_advanced' .$id. '" style="display:none">' . $mout . '</div>';
+ $out .= '</td>';
+
+ // add/del buttons
+ $out .= '<td class="rowbuttons">';
+ $out .= '<a href="#" id="ruleadd' . $id .'" title="'. rcube::Q($this->plugin->gettext('add')). '"
+ onclick="rcmail.managesieve_ruleadd(' . $id .')" class="button add"></a>';
+ $out .= '<a href="#" id="ruledel' . $id .'" title="'. rcube::Q($this->plugin->gettext('del')). '"
+ onclick="rcmail.managesieve_ruledel(' . $id .')" class="button del' . ($rows_num<2 ? ' disabled' : '') .'"></a>';
+ $out .= '</td>';
+ $out .= '</tr></table>';
+
+ $out .= $div ? "</div>\n" : '';
+
+ return $out;
+ }
+
+ function action_div($fid, $id, $div=true)
+ {
+ $action = isset($this->form) ? $this->form['actions'][$id] : $this->script[$fid]['actions'][$id];
+ $rows_num = isset($this->form) ? sizeof($this->form['actions']) : sizeof($this->script[$fid]['actions']);
+
+ $out = $div ? '<div class="actionrow" id="actionrow' .$id .'">'."\n" : '';
+
+ $out .= '<table><tr><td class="rowactions">';
+
+ // action select
+ $select_action = new html_select(array('name' => "_action_type[$id]", 'id' => 'action_type'.$id,
+ 'onchange' => 'action_type_select(' .$id .')'));
+ if (in_array('fileinto', $this->exts))
+ $select_action->add(rcube::Q($this->plugin->gettext('messagemoveto')), 'fileinto');
+ if (in_array('fileinto', $this->exts) && in_array('copy', $this->exts))
+ $select_action->add(rcube::Q($this->plugin->gettext('messagecopyto')), 'fileinto_copy');
+ $select_action->add(rcube::Q($this->plugin->gettext('messageredirect')), 'redirect');
+ if (in_array('copy', $this->exts))
+ $select_action->add(rcube::Q($this->plugin->gettext('messagesendcopy')), 'redirect_copy');
+ if (in_array('reject', $this->exts))
+ $select_action->add(rcube::Q($this->plugin->gettext('messagediscard')), 'reject');
+ else if (in_array('ereject', $this->exts))
+ $select_action->add(rcube::Q($this->plugin->gettext('messagediscard')), 'ereject');
+ if (in_array('vacation', $this->exts))
+ $select_action->add(rcube::Q($this->plugin->gettext('messagereply')), 'vacation');
+ $select_action->add(rcube::Q($this->plugin->gettext('messagedelete')), 'discard');
+ if (in_array('imapflags', $this->exts) || in_array('imap4flags', $this->exts)) {
+ $select_action->add(rcube::Q($this->plugin->gettext('setflags')), 'setflag');
+ $select_action->add(rcube::Q($this->plugin->gettext('addflags')), 'addflag');
+ $select_action->add(rcube::Q($this->plugin->gettext('removeflags')), 'removeflag');
+ }
+ if (in_array('variables', $this->exts)) {
+ $select_action->add(rcube::Q($this->plugin->gettext('setvariable')), 'set');
+ }
+ if (in_array('enotify', $this->exts) || in_array('notify', $this->exts)) {
+ $select_action->add(rcube::Q($this->plugin->gettext('notify')), 'notify');
+ }
+ $select_action->add(rcube::Q($this->plugin->gettext('rulestop')), 'stop');
+
+ $select_type = $action['type'];
+ if (in_array($action['type'], array('fileinto', 'redirect')) && $action['copy']) {
+ $select_type .= '_copy';
+ }
+
+ $out .= $select_action->show($select_type);
+ $out .= '</td>';
+
+ // actions target inputs
+ $out .= '<td class="rowtargets">';
+ // shared targets
+ $out .= '<input type="text" name="_action_target['.$id.']" id="action_target' .$id. '" '
+ .'value="' .($action['type']=='redirect' ? rcube::Q($action['target'], 'strict', false) : ''). '" size="35" '
+ .'style="display:' .($action['type']=='redirect' ? 'inline' : 'none') .'" '
+ . $this->error_class($id, 'action', 'target', 'action_target') .' />';
+ $out .= '<textarea name="_action_target_area['.$id.']" id="action_target_area' .$id. '" '
+ .'rows="3" cols="35" '. $this->error_class($id, 'action', 'targetarea', 'action_target_area')
+ .'style="display:' .(in_array($action['type'], array('reject', 'ereject')) ? 'inline' : 'none') .'">'
+ . (in_array($action['type'], array('reject', 'ereject')) ? rcube::Q($action['target'], 'strict', false) : '')
+ . "</textarea>\n";
+
+ // vacation
+ $vsec = in_array('vacation-seconds', $this->exts);
+ $out .= '<div id="action_vacation' .$id.'" style="display:' .($action['type']=='vacation' ? 'inline' : 'none') .'">';
+ $out .= '<span class="label">'. rcube::Q($this->plugin->gettext('vacationreason')) .'</span><br />'
+ .'<textarea name="_action_reason['.$id.']" id="action_reason' .$id. '" '
+ .'rows="3" cols="35" '. $this->error_class($id, 'action', 'reason', 'action_reason') . '>'
+ . Q($action['reason'], 'strict', false) . "</textarea>\n";
+ $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('vacationsubject')) . '</span><br />'
+ .'<input type="text" name="_action_subject['.$id.']" id="action_subject'.$id.'" '
+ .'value="' . (is_array($action['subject']) ? rcube::Q(implode(', ', $action['subject']), 'strict', false) : $action['subject']) . '" size="35" '
+ . $this->error_class($id, 'action', 'subject', 'action_subject') .' />';
+ $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('vacationaddr')) . '</span><br />'
+ . $this->list_input($id, 'action_addresses', $action['addresses'], true,
+ $this->error_class($id, 'action', 'addresses', 'action_addresses'), 30);
+ $out .= '<br /><span class="label">' . rcube::Q($this->plugin->gettext($vsec ? 'vacationinterval' : 'vacationdays')) . '</span><br />'
+ .'<input type="text" name="_action_interval['.$id.']" id="action_interval'.$id.'" '
+ .'value="' .rcube::Q(isset($action['seconds']) ? $action['seconds'] : $action['days'], 'strict', false) . '" size="2" '
+ . $this->error_class($id, 'action', 'interval', 'action_interval') .' />';
+ if ($vsec) {
+ $out .= '&nbsp;<label><input type="radio" name="_action_interval_type['.$id.']" value="days"'
+ . (!isset($action['seconds']) ? ' checked="checked"' : '') .' class="radio" />'.$this->plugin->gettext('days').'</label>'
+ . '&nbsp;<label><input type="radio" name="_action_interval_type['.$id.']" value="seconds"'
+ . (isset($action['seconds']) ? ' checked="checked"' : '') .' class="radio" />'.$this->plugin->gettext('seconds').'</label>';
+ }
+ $out .= '</div>';
+
+ // flags
+ $flags = array(
+ 'read' => '\\Seen',
+ 'answered' => '\\Answered',
+ 'flagged' => '\\Flagged',
+ 'deleted' => '\\Deleted',
+ 'draft' => '\\Draft',
+ );
+ $flags_target = (array)$action['target'];
+
+ $out .= '<div id="action_flags' .$id.'" style="display:'
+ . (preg_match('/^(set|add|remove)flag$/', $action['type']) ? 'inline' : 'none') . '"'
+ . $this->error_class($id, 'action', 'flags', 'action_flags') . '>';
+ foreach ($flags as $fidx => $flag) {
+ $out .= '<input type="checkbox" name="_action_flags[' .$id .'][]" value="' . $flag . '"'
+ . (in_array_nocase($flag, $flags_target) ? 'checked="checked"' : '') . ' />'
+ . rcube::Q($this->plugin->gettext('flag'.$fidx)) .'<br>';
+ }
+ $out .= '</div>';
+
+ // set variable
+ $set_modifiers = array(
+ 'lower',
+ 'upper',
+ 'lowerfirst',
+ 'upperfirst',
+ 'quotewildcard',
+ 'length'
+ );
+
+ $out .= '<div id="action_set' .$id.'" style="display:' .($action['type']=='set' ? 'inline' : 'none') .'">';
+ $out .= '<span class="label">' .rcube::Q($this->plugin->gettext('setvarname')) . '</span><br />'
+ .'<input type="text" name="_action_varname['.$id.']" id="action_varname'.$id.'" '
+ .'value="' . rcube::Q($action['name']) . '" size="35" '
+ . $this->error_class($id, 'action', 'name', 'action_varname') .' />';
+ $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('setvarvalue')) . '</span><br />'
+ .'<input type="text" name="_action_varvalue['.$id.']" id="action_varvalue'.$id.'" '
+ .'value="' . rcube::Q($action['value']) . '" size="35" '
+ . $this->error_class($id, 'action', 'value', 'action_varvalue') .' />';
+ $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('setvarmodifiers')) . '</span><br />';
+ foreach ($set_modifiers as $s_m) {
+ $s_m_id = 'action_varmods' . $id . $s_m;
+ $out .= sprintf('<input type="checkbox" name="_action_varmods[%s][]" value="%s" id="%s"%s />%s<br>',
+ $id, $s_m, $s_m_id,
+ (array_key_exists($s_m, (array)$action) && $action[$s_m] ? ' checked="checked"' : ''),
+ rcube::Q($this->plugin->gettext('var' . $s_m)));
+ }
+ $out .= '</div>';
+
+ // notify
+ // skip :options tag - not used by the mailto method
+ $out .= '<div id="action_notify' .$id.'" style="display:' .($action['type']=='notify' ? 'inline' : 'none') .'">';
+ $out .= '<span class="label">' .rcube::Q($this->plugin->gettext('notifyaddress')) . '</span><br />'
+ .'<input type="text" name="_action_notifyaddress['.$id.']" id="action_notifyaddress'.$id.'" '
+ .'value="' . rcube::Q($action['address']) . '" size="35" '
+ . $this->error_class($id, 'action', 'address', 'action_notifyaddress') .' />';
+ $out .= '<br /><span class="label">'. rcube::Q($this->plugin->gettext('notifybody')) .'</span><br />'
+ .'<textarea name="_action_notifybody['.$id.']" id="action_notifybody' .$id. '" '
+ .'rows="3" cols="35" '. $this->error_class($id, 'action', 'method', 'action_notifybody') . '>'
+ . rcube::Q($action['body'], 'strict', false) . "</textarea>\n";
+ $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('notifysubject')) . '</span><br />'
+ .'<input type="text" name="_action_notifymessage['.$id.']" id="action_notifymessage'.$id.'" '
+ .'value="' . rcube::Q($action['message']) . '" size="35" '
+ . $this->error_class($id, 'action', 'message', 'action_notifymessage') .' />';
+ $out .= '<br /><span class="label">' .rcube::Q($this->plugin->gettext('notifyfrom')) . '</span><br />'
+ .'<input type="text" name="_action_notifyfrom['.$id.']" id="action_notifyfrom'.$id.'" '
+ .'value="' . rcube::Q($action['from']) . '" size="35" '
+ . $this->error_class($id, 'action', 'from', 'action_notifyfrom') .' />';
+ $importance_options = array(
+ 3 => 'notifyimportancelow',
+ 2 => 'notifyimportancenormal',
+ 1 => 'notifyimportancehigh'
+ );
+ $select_importance = new html_select(array(
+ 'name' => '_action_notifyimportance[' . $id . ']',
+ 'id' => '_action_notifyimportance' . $id,
+ 'class' => $this->error_class($id, 'action', 'importance', 'action_notifyimportance')));
+ foreach ($importance_options as $io_v => $io_n) {
+ $select_importance->add(rcube::Q($this->plugin->gettext($io_n)), $io_v);
+ }
+ $out .= '<br /><span class="label">' . rcube::Q($this->plugin->gettext('notifyimportance')) . '</span><br />';
+ $out .= $select_importance->show($action['importance'] ? $action['importance'] : 2);
+ $out .= '</div>';
+
+ // mailbox select
+ if ($action['type'] == 'fileinto')
+ $mailbox = $this->mod_mailbox($action['target'], 'out');
+ else
+ $mailbox = '';
+
+ $select = $this->rc->folder_selector(array(
+ 'realnames' => false,
+ 'maxlength' => 100,
+ 'id' => 'action_mailbox' . $id,
+ 'name' => "_action_mailbox[$id]",
+ 'style' => 'display:'.(!isset($action) || $action['type']=='fileinto' ? 'inline' : 'none')
+ ));
+ $out .= $select->show($mailbox);
+ $out .= '</td>';
+
+ // add/del buttons
+ $out .= '<td class="rowbuttons">';
+ $out .= '<a href="#" id="actionadd' . $id .'" title="'. rcube::Q($this->plugin->gettext('add')). '"
+ onclick="rcmail.managesieve_actionadd(' . $id .')" class="button add"></a>';
+ $out .= '<a href="#" id="actiondel' . $id .'" title="'. rcube::Q($this->plugin->gettext('del')). '"
+ onclick="rcmail.managesieve_actiondel(' . $id .')" class="button del' . ($rows_num<2 ? ' disabled' : '') .'"></a>';
+ $out .= '</td>';
+
+ $out .= '</tr></table>';
+
+ $out .= $div ? "</div>\n" : '';
+
+ return $out;
+ }
+
+ private function genid()
+ {
+ return preg_replace('/[^0-9]/', '', microtime(true));
+ }
+
+ private function strip_value($str, $allow_html = false, $trim = true)
+ {
+ if (is_array($str)) {
+ foreach ($str as $idx => $val) {
+ $val = $this->strip_value($val, $allow_html, $trim);
+
+ if ($val === '') {
+ unset($str[$idx]);
+ }
+ }
+
+ return $str;
+ }
+
+ if (!$allow_html) {
+ $str = strip_tags($str);
+ }
+
+ return $trim ? trim($str) : $str;
+ }
+
+ private function error_class($id, $type, $target, $elem_prefix='')
+ {
+ // TODO: tooltips
+ if (($type == 'test' && ($str = $this->errors['tests'][$id][$target])) ||
+ ($type == 'action' && ($str = $this->errors['actions'][$id][$target]))
+ ) {
+ $this->add_tip($elem_prefix.$id, $str, true);
+ return ' class="error"';
+ }
+
+ return '';
+ }
+
+ private function add_tip($id, $str, $error=false)
+ {
+ if ($error)
+ $str = html::span('sieve error', $str);
+
+ $this->tips[] = array($id, $str);
+ }
+
+ private function print_tips()
+ {
+ if (empty($this->tips))
+ return;
+
+ $script = rcmail_output::JS_OBJECT_NAME.'.managesieve_tip_register('.json_encode($this->tips).');';
+ $this->rc->output->add_script($script, 'foot');
+ }
+
+ private function list_input($id, $name, $value, $enabled, $class, $size=null)
+ {
+ $value = (array) $value;
+ $value = array_map(array('rcube', 'Q'), $value);
+ $value = implode("\n", $value);
+
+ return '<textarea data-type="list" name="_' . $name . '['.$id.']" id="' . $name.$id . '"'
+ . ($enabled ? '' : ' disabled="disabled"')
+ . ($size ? ' data-size="'.$size.'"' : '')
+ . $class
+ . ' style="display:none">' . $value . '</textarea>';
+ }
+
+ /**
+ * Validate input for date part elements
+ */
+ private function validate_date_part($type, $value)
+ {
+ // we do simple validation of date/part format
+ switch ($type) {
+ case 'date': // yyyy-mm-dd
+ return preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $value);
+ case 'iso8601':
+ return preg_match('/^[0-9: .,ZWT+-]+$/', $value);
+ case 'std11':
+ return preg_match('/^((Sun|Mon|Tue|Wed|Thu|Fri|Sat),\s+)?[0-9]{1,2}\s+'
+ . '(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s+[0-9]{2,4}\s+'
+ . '[0-9]{2}:[0-9]{2}(:[0-9]{2})?\s+([+-]*[0-9]{4}|[A-Z]{1,3})$', $value);
+ case 'julian':
+ return preg_match('/^[0-9]+$/', $value);
+ case 'time': // hh:mm:ss
+ return preg_match('/^[0-9]{2}:[0-9]{2}:[0-9]{2}$/', $value);
+ case 'year':
+ return preg_match('/^[0-9]{4}$/', $value);
+ case 'month':
+ return preg_match('/^[0-9]{2}$/', $value) && $value > 0 && $value < 13;
+ case 'day':
+ return preg_match('/^[0-9]{2}$/', $value) && $value > 0 && $value < 32;
+ case 'hour':
+ return preg_match('/^[0-9]{2}$/', $value) && $value < 24;
+ case 'minute':
+ return preg_match('/^[0-9]{2}$/', $value) && $value < 60;
+ case 'second':
+ // According to RFC5260, seconds can be from 00 to 60
+ return preg_match('/^[0-9]{2}$/', $value) && $value < 61;
+ case 'weekday':
+ return preg_match('/^[0-9]$/', $value) && $value < 7;
+ case 'zone':
+ return preg_match('/^[+-][0-9]{4}$/', $value);
+ }
+ }
+
+ /**
+ * Converts mailbox name from/to UTF7-IMAP from/to internal Sieve encoding
+ * with delimiter replacement.
+ *
+ * @param string $mailbox Mailbox name
+ * @param string $mode Conversion direction ('in'|'out')
+ *
+ * @return string Mailbox name
+ */
+ private function mod_mailbox($mailbox, $mode = 'out')
+ {
+ $delimiter = $_SESSION['imap_delimiter'];
+ $replace_delimiter = $this->rc->config->get('managesieve_replace_delimiter');
+ $mbox_encoding = $this->rc->config->get('managesieve_mbox_encoding', 'UTF7-IMAP');
+
+ if ($mode == 'out') {
+ $mailbox = rcube_charset::convert($mailbox, $mbox_encoding, 'UTF7-IMAP');
+ if ($replace_delimiter && $replace_delimiter != $delimiter)
+ $mailbox = str_replace($replace_delimiter, $delimiter, $mailbox);
+ }
+ else {
+ $mailbox = rcube_charset::convert($mailbox, 'UTF7-IMAP', $mbox_encoding);
+ if ($replace_delimiter && $replace_delimiter != $delimiter)
+ $mailbox = str_replace($delimiter, $replace_delimiter, $mailbox);
+ }
+
+ return $mailbox;
+ }
+
+ /**
+ * List sieve scripts
+ *
+ * @return array Scripts list
+ */
+ public function list_scripts()
+ {
+ if ($this->list !== null) {
+ return $this->list;
+ }
+
+ $this->list = $this->sieve->get_scripts();
+
+ // Handle active script(s) and list of scripts according to Kolab's KEP:14
+ if ($this->rc->config->get('managesieve_kolab_master')) {
+
+ // Skip protected names
+ foreach ((array)$this->list as $idx => $name) {
+ $_name = strtoupper($name);
+ if ($_name == 'MASTER')
+ $master_script = $name;
+ else if ($_name == 'MANAGEMENT')
+ $management_script = $name;
+ else if($_name == 'USER')
+ $user_script = $name;
+ else
+ continue;
+
+ unset($this->list[$idx]);
+ }
+
+ // get active script(s), read USER script
+ if ($user_script) {
+ $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
+ $filename_regex = '/'.preg_quote($extension, '/').'$/';
+ $_SESSION['managesieve_user_script'] = $user_script;
+
+ $this->sieve->load($user_script);
+
+ foreach ($this->sieve->script->as_array() as $rules) {
+ foreach ($rules['actions'] as $action) {
+ if ($action['type'] == 'include' && empty($action['global'])) {
+ $name = preg_replace($filename_regex, '', $action['target']);
+ $this->active[] = $name;
+ }
+ }
+ }
+ }
+ // create USER script if it doesn't exist
+ else {
+ $content = "# USER Management Script\n"
+ ."#\n"
+ ."# This script includes the various active sieve scripts\n"
+ ."# it is AUTOMATICALLY GENERATED. DO NOT EDIT MANUALLY!\n"
+ ."#\n"
+ ."# For more information, see http://wiki.kolab.org/KEP:14#USER\n"
+ ."#\n";
+ if ($this->sieve->save_script('USER', $content)) {
+ $_SESSION['managesieve_user_script'] = 'USER';
+ if (empty($this->master_file))
+ $this->sieve->activate('USER');
+ }
+ }
+ }
+ else if (!empty($this->list)) {
+ // Get active script name
+ if ($active = $this->sieve->get_active()) {
+ $this->active = array($active);
+ }
+
+ // Hide scripts from config
+ $exceptions = $this->rc->config->get('managesieve_filename_exceptions');
+ if (!empty($exceptions)) {
+ $this->list = array_diff($this->list, (array)$exceptions);
+ }
+ }
+
+ return $this->list;
+ }
+
+ /**
+ * Removes sieve script
+ *
+ * @param string $name Script name
+ *
+ * @return bool True on success, False on failure
+ */
+ public function remove_script($name)
+ {
+ $result = $this->sieve->remove($name);
+
+ // Kolab's KEP:14
+ if ($result && $this->rc->config->get('managesieve_kolab_master')) {
+ $this->deactivate_script($name);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Activates sieve script
+ *
+ * @param string $name Script name
+ *
+ * @return bool True on success, False on failure
+ */
+ public function activate_script($name)
+ {
+ // Kolab's KEP:14
+ if ($this->rc->config->get('managesieve_kolab_master')) {
+ $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
+ $user_script = $_SESSION['managesieve_user_script'];
+
+ // if the script is not active...
+ if ($user_script && array_search($name, $this->active) === false) {
+ // ...rewrite USER file adding appropriate include command
+ if ($this->sieve->load($user_script)) {
+ $script = $this->sieve->script->as_array();
+ $list = array();
+ $regexp = '/' . preg_quote($extension, '/') . '$/';
+
+ // Create new include entry
+ $rule = array(
+ 'actions' => array(
+ 0 => array(
+ 'target' => $name.$extension,
+ 'type' => 'include',
+ 'personal' => true,
+ )));
+
+ // get all active scripts for sorting
+ foreach ($script as $rid => $rules) {
+ foreach ($rules['actions'] as $action) {
+ if ($action['type'] == 'include' && empty($action['global'])) {
+ $target = $extension ? preg_replace($regexp, '', $action['target']) : $action['target'];
+ $list[] = $target;
+ }
+ }
+ }
+ $list[] = $name;
+
+ // Sort and find current script position
+ asort($list, SORT_LOCALE_STRING);
+ $list = array_values($list);
+ $index = array_search($name, $list);
+
+ // add rule at the end of the script
+ if ($index === false || $index == count($list)-1) {
+ $this->sieve->script->add_rule($rule);
+ }
+ // add rule at index position
+ else {
+ $script2 = array();
+ foreach ($script as $rid => $rules) {
+ if ($rid == $index) {
+ $script2[] = $rule;
+ }
+ $script2[] = $rules;
+ }
+ $this->sieve->script->content = $script2;
+ }
+
+ $result = $this->sieve->save();
+ if ($result) {
+ $this->active[] = $name;
+ }
+ }
+ }
+ }
+ else {
+ $result = $this->sieve->activate($name);
+ if ($result)
+ $this->active = array($name);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Deactivates sieve script
+ *
+ * @param string $name Script name
+ *
+ * @return bool True on success, False on failure
+ */
+ public function deactivate_script($name)
+ {
+ // Kolab's KEP:14
+ if ($this->rc->config->get('managesieve_kolab_master')) {
+ $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
+ $user_script = $_SESSION['managesieve_user_script'];
+
+ // if the script is active...
+ if ($user_script && ($key = array_search($name, $this->active)) !== false) {
+ // ...rewrite USER file removing appropriate include command
+ if ($this->sieve->load($user_script)) {
+ $script = $this->sieve->script->as_array();
+ $name = $name.$extension;
+
+ foreach ($script as $rid => $rules) {
+ foreach ($rules['actions'] as $action) {
+ if ($action['type'] == 'include' && empty($action['global'])
+ && $action['target'] == $name
+ ) {
+ break 2;
+ }
+ }
+ }
+
+ // Entry found
+ if ($rid < count($script)) {
+ $this->sieve->script->delete_rule($rid);
+ $result = $this->sieve->save();
+ if ($result) {
+ unset($this->active[$key]);
+ }
+ }
+ }
+ }
+ }
+ else {
+ $result = $this->sieve->deactivate();
+ if ($result)
+ $this->active = array();
+ }
+
+ return $result;
+ }
+
+ /**
+ * Saves current script (adding some variables)
+ */
+ public function save_script($name = null)
+ {
+ // Kolab's KEP:14
+ if ($this->rc->config->get('managesieve_kolab_master')) {
+ $this->sieve->script->set_var('EDITOR', self::PROGNAME);
+ $this->sieve->script->set_var('EDITOR_VERSION', self::VERSION);
+ }
+
+ return $this->sieve->save($name);
+ }
+
+ /**
+ * Returns list of rules from the current script
+ *
+ * @return array List of rules
+ */
+ public function list_rules()
+ {
+ $result = array();
+ $i = 1;
+
+ foreach ($this->script as $idx => $filter) {
+ if ($filter['type'] != 'if') {
+ continue;
+ }
+ $fname = $filter['name'] ? $filter['name'] : "#$i";
+ $result[] = array(
+ 'id' => $idx,
+ 'name' => $fname,
+ 'class' => $filter['disabled'] ? 'disabled' : '',
+ );
+ $i++;
+ }
+
+ return $result;
+ }
+}
diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
index 78b4bc625..a614c3b15 100644
--- a/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
+++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_script.php
@@ -6,18 +6,18 @@
* Copyright (C) 2008-2011, The Roundcube Dev Team
* Copyright (C) 2011, Kolab Systems AG
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
*/
class rcube_sieve_script
diff --git a/plugins/managesieve/localization/en_US.inc b/plugins/managesieve/localization/en_US.inc
index 9fe943446..72bbf9d41 100644
--- a/plugins/managesieve/localization/en_US.inc
+++ b/plugins/managesieve/localization/en_US.inc
@@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'count is greater than or equal to';
$labels['countislessthan'] = 'count is less than';
$labels['countislessthanequal'] = 'count is less than or equal to';
$labels['countequals'] = 'count is equal to';
-$labels['countnotequals'] = 'count does not equal';
+$labels['countnotequals'] = 'count is not equal to';
$labels['valueisgreaterthan'] = 'value is greater than';
$labels['valueisgreaterthanequal'] = 'value is greater than or equal to';
$labels['valueislessthan'] = 'value is less than';
$labels['valueislessthanequal'] = 'value is less than or equal to';
$labels['valueequals'] = 'value is equal to';
-$labels['valuenotequals'] = 'value does not equal';
+$labels['valuenotequals'] = 'value is not equal to';
$labels['setflags'] = 'Set flags to the message';
$labels['addflags'] = 'Add flags to the message';
$labels['removeflags'] = 'Remove flags from the message';
@@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Create filter';
$labels['usedata'] = 'Use following data in the filter:';
$labels['nextstep'] = 'Next Step';
$labels['...'] = '...';
+$labels['currdate'] = 'Current date';
+$labels['datetest'] = 'Date';
+$labels['dateheader'] = 'header:';
+$labels['year'] = 'year';
+$labels['month'] = 'month';
+$labels['day'] = 'day';
+$labels['date'] = 'date (yyyy-mm-dd)';
+$labels['julian'] = 'date (julian)';
+$labels['hour'] = 'hour';
+$labels['minute'] = 'minute';
+$labels['second'] = 'second';
+$labels['time'] = 'time (hh:mm:ss)';
+$labels['iso8601'] = 'date (ISO8601)';
+$labels['std11'] = 'date (RFC2822)';
+$labels['zone'] = 'time-zone';
+$labels['weekday'] = 'weekday (0-6)';
$labels['advancedopts'] = 'Advanced options';
$labels['body'] = 'Body';
$labels['address'] = 'address';
@@ -140,6 +156,8 @@ $labels['default'] = 'default';
$labels['octet'] = 'strict (octet)';
$labels['asciicasemap'] = 'case insensitive (ascii-casemap)';
$labels['asciinumeric'] = 'numeric (ascii-numeric)';
+$labels['index'] = 'index:';
+$labels['indexlast'] = 'backwards';
$messages = array();
$messages['filterunknownerror'] = 'Unknown server error.';
@@ -173,5 +191,6 @@ $messages['nametoolong'] = 'Name too long.';
$messages['namereserved'] = 'Reserved name.';
$messages['setexist'] = 'Set already exists.';
$messages['nodata'] = 'At least one position must be selected!';
+$messages['invaliddateformat'] = 'Invalid date or date part format';
?>
diff --git a/plugins/managesieve/localization/es_ES.inc b/plugins/managesieve/localization/es_ES.inc
index 93ea89262..65ed461c4 100644
--- a/plugins/managesieve/localization/es_ES.inc
+++ b/plugins/managesieve/localization/es_ES.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Agregar';
$labels['del'] = 'Eliminar';
$labels['sender'] = 'Remitente';
$labels['recipient'] = 'Destinatario';
-$labels['vacationaddr'] = 'Lista de direcciones de correo de destinatarios adicionales:';
+$labels['vacationaddr'] = 'Mis direcciones de correo electrónico adicionales:';
$labels['vacationdays'] = 'Cada cuánto enviar mensajes (en días):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Cada cuánto enviar mensajes:';
+$labels['days'] = 'días';
+$labels['seconds'] = 'segundos';
$labels['vacationreason'] = 'Cuerpo del mensaje (razón de vacaciones):';
$labels['vacationsubject'] = 'Asunto del Mensaje:';
$labels['rulestop'] = 'Parar de evaluar reglas';
@@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'contiene más o igual que';
$labels['countislessthan'] = 'contiene menos que';
$labels['countislessthanequal'] = 'contiene menos o igual que';
$labels['countequals'] = 'contiene igual que';
-$labels['countnotequals'] = 'contiene distinto que';
+$labels['countnotequals'] = 'la cuenta no es igual a';
$labels['valueisgreaterthan'] = 'el valor es mayor que';
$labels['valueisgreaterthanequal'] = 'el valor es mayor o igual que';
$labels['valueislessthan'] = 'el valor es menor que';
$labels['valueislessthanequal'] = 'el valor es menor o igual que';
$labels['valueequals'] = 'el valor es igual que';
-$labels['valuenotequals'] = 'el valor es distinto que';
+$labels['valuenotequals'] = 'el valor no es igual a';
$labels['setflags'] = 'Etiquetar el mensaje';
$labels['addflags'] = 'Agregar etiquetas al mensaje';
$labels['removeflags'] = 'Eliminar etiquetas al mensaje';
@@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Crear Filtro';
$labels['usedata'] = 'Usar los siguientes datos en el filtro:';
$labels['nextstep'] = 'Siguiente paso';
$labels['...'] = '...';
+$labels['currdate'] = 'Fecha actual';
+$labels['datetest'] = 'Fecha';
+$labels['dateheader'] = 'cabecera:';
+$labels['year'] = 'año';
+$labels['month'] = 'mes';
+$labels['day'] = 'día';
+$labels['date'] = 'fecha (aaaa-mm-dd)';
+$labels['julian'] = 'fecha (juliano)';
+$labels['hour'] = 'hora';
+$labels['minute'] = 'minuto';
+$labels['second'] = 'segundo';
+$labels['time'] = 'hora (hh:mm:ss)';
+$labels['iso8601'] = 'fecha (ISO8601)';
+$labels['std11'] = 'fecha (RFC2822)';
+$labels['zone'] = 'zona horaria';
+$labels['weekday'] = 'día de la semana (0-6)';
$labels['advancedopts'] = 'Opciones avanzadas';
$labels['body'] = 'Cuerpo del mensaje';
$labels['address'] = 'dirección';
@@ -140,6 +156,8 @@ $labels['default'] = 'predeterminado';
$labels['octet'] = 'estricto (octeto)';
$labels['asciicasemap'] = 'no sensible a mayúsculas (ascii-casemap)';
$labels['asciinumeric'] = 'numerico (ascii-numeric)';
+$labels['index'] = 'índice:';
+$labels['indexlast'] = 'hacia atrás';
$messages = array();
$messages['filterunknownerror'] = 'Error desconocido de servidor.';
@@ -173,5 +191,6 @@ $messages['nametoolong'] = 'Imposible crear el conjunto de filtros. Nombre demas
$messages['namereserved'] = 'Nombre reservado.';
$messages['setexist'] = 'El conjunto ya existe.';
$messages['nodata'] = '¡Al menos una posición debe ser seleccionada!';
+$messages['invaliddateformat'] = 'Fecha o formato de parte de la fecha no válido';
?>
diff --git a/plugins/managesieve/localization/et_EE.inc b/plugins/managesieve/localization/et_EE.inc
index 7a10af41e..dff15dfb4 100644
--- a/plugins/managesieve/localization/et_EE.inc
+++ b/plugins/managesieve/localization/et_EE.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Lisa';
$labels['del'] = 'Kustuta';
$labels['sender'] = 'Saatja';
$labels['recipient'] = 'Saaja';
-$labels['vacationaddr'] = 'Lisanimekiri saaja e-posti aadressidest:';
+$labels['vacationaddr'] = 'Minu teised e-posti aadress(id):';
$labels['vacationdays'] = 'Kui tihti kirju saata (päevades):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Kui tihti kirju saata:';
+$labels['days'] = 'päeva';
+$labels['seconds'] = 'sekundit';
$labels['vacationreason'] = 'Kirja sisu (puhkuse põhjus):';
$labels['vacationsubject'] = 'Kirja teema:';
$labels['rulestop'] = 'Peata reeglite otsimine';
@@ -83,7 +83,7 @@ $labels['countisgreaterthanequal'] = 'koguarv on suurem kui või võrdne';
$labels['countislessthan'] = 'koguarv on väiksem';
$labels['countislessthanequal'] = 'koguarv on väiksem kui või võrdne';
$labels['countequals'] = 'koguarv on võrdne';
-$labels['countnotequals'] = 'koguarv ei ole võrdne';
+$labels['countnotequals'] = 'summa ei ole võrdne';
$labels['valueisgreaterthan'] = 'väärtus on suurem kui';
$labels['valueisgreaterthanequal'] = 'väärtus on suurem kui või võrdne';
$labels['valueislessthan'] = 'väärtus on väiksem kui';
@@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Loo filter';
$labels['usedata'] = 'Kasuta filtris järgmisi andmeid:';
$labels['nextstep'] = 'Järgmine samm';
$labels['...'] = '…';
+$labels['currdate'] = 'Praegune kuupäev';
+$labels['datetest'] = 'Kuupäev';
+$labels['dateheader'] = 'päis:';
+$labels['year'] = 'aasta';
+$labels['month'] = 'kuu';
+$labels['day'] = 'päev';
+$labels['date'] = 'kuupäev (aaaa-kk-pp)';
+$labels['julian'] = 'kuupäev (Juliuse)';
+$labels['hour'] = 'tund';
+$labels['minute'] = 'minut';
+$labels['second'] = 'sekund';
+$labels['time'] = 'aeg (tt:mm:ss)';
+$labels['iso8601'] = 'kuupäev (ISO8601)';
+$labels['std11'] = 'kuupäev (RCF2822)';
+$labels['zone'] = 'ajatsoon';
+$labels['weekday'] = 'nädalapäev (0-6)';
$labels['advancedopts'] = 'Lisaseadistused';
$labels['body'] = 'Põhitekst';
$labels['address'] = 'aadress';
@@ -140,6 +156,8 @@ $labels['default'] = 'vaikimisi';
$labels['octet'] = 'range (octet)';
$labels['asciicasemap'] = 'tõstutundetu (ascii-casemap)';
$labels['asciinumeric'] = 'numbriline (ascii-numeric)';
+$labels['index'] = 'indeks:';
+$labels['indexlast'] = 'tagasisuunas';
$messages = array();
$messages['filterunknownerror'] = 'Tundmatu serveri tõrge';
@@ -173,5 +191,6 @@ $messages['nametoolong'] = 'Nimi on liiga pikk.';
$messages['namereserved'] = 'Nimi on reserveeritud.';
$messages['setexist'] = 'Kogum on juba olemas.';
$messages['nodata'] = 'Valitud peab olema vähemalt üks asukoht!';
+$messages['invaliddateformat'] = 'Vigane kuupäev või kuupäeva formaat';
?>
diff --git a/plugins/managesieve/localization/fr_FR.inc b/plugins/managesieve/localization/fr_FR.inc
index 047c455ef..821f9caab 100644
--- a/plugins/managesieve/localization/fr_FR.inc
+++ b/plugins/managesieve/localization/fr_FR.inc
@@ -18,7 +18,7 @@
$labels['filters'] = 'Filtres';
-$labels['managefilters'] = 'Gestion des filtres sur les mails entrants';
+$labels['managefilters'] = 'Gérer les filtres sur les courriels entrants';
$labels['filtername'] = 'Nom du filtre';
$labels['newfilter'] = 'Nouveau filtre';
$labels['filteradd'] = 'Ajouter un filtre';
@@ -49,18 +49,18 @@ $labels['messagesendcopy'] = 'Envoyer une copie du message à';
$labels['messagereply'] = 'Répondre avec le message';
$labels['messagedelete'] = 'Supprimer le message';
$labels['messagediscard'] = 'Rejeter avec le message';
-$labels['messagesrules'] = 'Pour les mails entrants:';
+$labels['messagesrules'] = 'Pour les courriels entrants :';
$labels['messagesactions'] = '...exécuter les actions suivantes:';
$labels['add'] = 'Ajouter';
$labels['del'] = 'Supprimer';
$labels['sender'] = 'Expéditeur';
$labels['recipient'] = 'Destinataire';
-$labels['vacationaddr'] = 'Liste des destinataires:';
-$labels['vacationdays'] = 'Ne pas renvoyer un message avant (jours):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
-$labels['vacationreason'] = 'Corps du message (raison de l\'absence):';
+$labels['vacationaddr'] = 'Mon/Mes adresse(s) de courriel additionnelle(s):';
+$labels['vacationdays'] = 'Ne pas renvoyer un message avant (jours) :';
+$labels['vacationinterval'] = 'Comment envoyer les messages :';
+$labels['days'] = 'jours';
+$labels['seconds'] = 'secondes';
+$labels['vacationreason'] = 'Corps du message (raison de l\'absence) :';
$labels['vacationsubject'] = 'Sujet du message:';
$labels['rulestop'] = 'Arrêter d\'évaluer les prochaines règles';
$labels['enable'] = 'Activer/Désactiver';
@@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'total supérieur ou égal à';
$labels['countislessthan'] = 'total inférieur à';
$labels['countislessthanequal'] = 'total inférieur à';
$labels['countequals'] = 'total égal à';
-$labels['countnotequals'] = 'total différent de';
+$labels['countnotequals'] = 'le comptage n\'est pas égal à';
$labels['valueisgreaterthan'] = 'valeur supérieure à';
$labels['valueisgreaterthanequal'] = 'valeur supérieure ou égale à';
$labels['valueislessthan'] = 'valeur inférieure à';
$labels['valueislessthanequal'] = 'valeur inférieure ou égale à';
$labels['valueequals'] = 'valeur égale à';
-$labels['valuenotequals'] = 'valeur différente de';
+$labels['valuenotequals'] = 'la valeur n\'est pas égale à';
$labels['setflags'] = 'Mettre les marqueurs au message';
$labels['addflags'] = 'Ajouter les marqueurs au message';
$labels['removeflags'] = 'Supprimer les marqueurs du message';
@@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Créer un filtre';
$labels['usedata'] = 'Utiliser les informations suivantes dans le filtre';
$labels['nextstep'] = 'Étape suivante';
$labels['...'] = '...';
+$labels['currdate'] = 'Date actuelle';
+$labels['datetest'] = 'Date';
+$labels['dateheader'] = 'header:';
+$labels['year'] = 'année';
+$labels['month'] = 'mois';
+$labels['day'] = 'jour';
+$labels['date'] = 'date (yyyy-mm-dd)';
+$labels['julian'] = 'date (julien)';
+$labels['hour'] = 'heure';
+$labels['minute'] = 'minute';
+$labels['second'] = 'seconde';
+$labels['time'] = 'heure (hh:mm:ss)';
+$labels['iso8601'] = 'date (ISO8601)';
+$labels['std11'] = 'date (RFC2822)';
+$labels['zone'] = 'fuseau horaire';
+$labels['weekday'] = 'jour de la semaine (0-6)';
$labels['advancedopts'] = 'Options avancées';
$labels['body'] = 'Corps du message';
$labels['address'] = 'adresse';
@@ -140,6 +156,8 @@ $labels['default'] = 'par défaut';
$labels['octet'] = 'strict (octet)';
$labels['asciicasemap'] = 'insensible à la casse (ascii-casemap)';
$labels['asciinumeric'] = 'numérique (ascii-numeric)';
+$labels['index'] = 'index:';
+$labels['indexlast'] = 'retour arrière';
$messages = array();
$messages['filterunknownerror'] = 'Erreur du serveur inconnue';
@@ -165,13 +183,14 @@ $messages['setcreateerror'] = 'Impossible de créer le groupe de filtres. Le ser
$messages['setcreated'] = 'Le groupe de filtres a bien été créé.';
$messages['activateerror'] = 'Impossible d\'activer le(s) filtre(s) sélectionné(s). Une erreur serveur s\'est produite.';
$messages['deactivateerror'] = 'Impossible de désactiver le(s) filtre(s) sélectionné(s). Une erreur serveur s\'est produite.';
-$messages['deactivated'] = 'Filtre(s) activé(s) avec succès';
-$messages['activated'] = 'Filtre(s) désactivé(s) avec succès';
+$messages['deactivated'] = 'Filtre(s) désactivé(s) avec succès.';
+$messages['activated'] = 'Filtre(s) activé(s) avec succès.';
$messages['moved'] = 'Filtre déplacé avec succès.';
$messages['moveerror'] = 'Déplacement du filtre sélectionné impossible. Le serveur a renvoyé une erreur.';
$messages['nametoolong'] = 'Nom trop long.';
$messages['namereserved'] = 'Nom réservé.';
$messages['setexist'] = 'Ce groupe existe déjà.';
$messages['nodata'] = 'Au moins un élément doit être selectionné !';
+$messages['invaliddateformat'] = 'Date non valide ou format d\'une partie de la date';
?>
diff --git a/plugins/managesieve/localization/lv_LV.inc b/plugins/managesieve/localization/lv_LV.inc
index 0a008f8b8..02b4eeffa 100644
--- a/plugins/managesieve/localization/lv_LV.inc
+++ b/plugins/managesieve/localization/lv_LV.inc
@@ -30,7 +30,7 @@ $labels['filteranyof'] = 'jÄatbilst jebkuram no sekojoÅ¡ajiem nosacÄ«jumiem';
$labels['filterany'] = 'visÄm vÄ“stulÄ“m';
$labels['filtercontains'] = 'satur';
$labels['filternotcontains'] = 'nesatur';
-$labels['filteris'] = 'vienÄds ar';
+$labels['filteris'] = 'ir vienÄds ar';
$labels['filterisnot'] = 'nav vienÄds ar';
$labels['filterexists'] = 'eksistē';
$labels['filternotexists'] = 'neeksistē';
@@ -46,20 +46,20 @@ $labels['messagemoveto'] = 'PÄrvietot vÄ“stuli uz';
$labels['messageredirect'] = 'PÄradresÄ“t vÄ“stuli uz';
$labels['messagecopyto'] = 'Kopēt vēstuli uz';
$labels['messagesendcopy'] = 'PÄrsÅ«tÄ«t vÄ“stules kopiju uz';
-$labels['messagereply'] = 'Atbildēt ar';
+$labels['messagereply'] = 'Atbildēt ar vēstuli';
$labels['messagedelete'] = 'Dzēst vēstuli';
$labels['messagediscard'] = 'Dzēst vēstuli un atbildēt';
$labels['messagesrules'] = 'IenÄkoÅ¡ajÄm vÄ“stulÄ“m:';
-$labels['messagesactions'] = 'IzpildÄ«t sekojoÅ¡Äs darbÄ«bas:';
+$labels['messagesactions'] = '...izpildÄ«t sekojoÅ¡Äs darbÄ«bas:';
$labels['add'] = 'Pievienot';
$labels['del'] = 'Dzēst';
$labels['sender'] = 'SÅ«tÄ«tÄjs';
$labels['recipient'] = 'Saņēmējs';
-$labels['vacationaddr'] = 'Ievadiet vienu vai vairÄkus e-pastu(s):';
+$labels['vacationaddr'] = 'Mana(s) papildus e-pasta adrese(s):';
$labels['vacationdays'] = 'Cik dienu laikÄ vienam un tam paÅ¡am sÅ«tÄ«tÄjam neatbildÄ“t atkÄrtoti (piem., 7):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Cik bieži sūtīt vēstules:';
+$labels['days'] = 'dienas';
+$labels['seconds'] = 'sekundes';
$labels['vacationreason'] = 'AtvaļinÄjuma paziņojuma teksts:';
$labels['vacationsubject'] = 'Vēstules tēma:';
$labels['rulestop'] = 'ApturÄ“t nosacÄ«jumu pÄrbaudi';
@@ -78,16 +78,16 @@ $labels['none'] = 'nav';
$labels['fromset'] = 'no kopas';
$labels['fromfile'] = 'no faila';
$labels['filterdisabled'] = 'Filtrs atslēgts';
-$labels['countisgreaterthan'] = 'skaits ir lielÄks nekÄ';
-$labels['countisgreaterthanequal'] = 'skaits ir vienÄds vai lielÄks nekÄ';
-$labels['countislessthan'] = 'skaits ir mazÄks nekÄ';
-$labels['countislessthanequal'] = 'skaits ir vienÄds vai mazÄks nekÄ';
+$labels['countisgreaterthan'] = 'skaits ir lielÄks kÄ';
+$labels['countisgreaterthanequal'] = 'skaits ir vienÄds vai lielÄks kÄ';
+$labels['countislessthan'] = 'skaits ir mazÄks kÄ';
+$labels['countislessthanequal'] = 'skaits ir vienÄds vai mazÄks kÄ';
$labels['countequals'] = 'skaits ir vienÄds ar';
$labels['countnotequals'] = 'skaits nav vienÄds ar';
-$labels['valueisgreaterthan'] = 'vÄ“rtÄ«ba ir lielÄka nekÄ';
-$labels['valueisgreaterthanequal'] = 'vÄ“rtÄ«ba ir vienÄda vai lielÄka nekÄ';
-$labels['valueislessthan'] = 'vÄ“rtÄ«ba ir mazÄka nekÄ';
-$labels['valueislessthanequal'] = 'vÄ“rtÄ«ba ir vienÄda vai mazÄka nekÄ';
+$labels['valueisgreaterthan'] = 'vÄ“rtÄ«ba ir lielÄka kÄ';
+$labels['valueisgreaterthanequal'] = 'vÄ“rtÄ«ba ir vienÄda vai lielÄka kÄ';
+$labels['valueislessthan'] = 'vÄ“rtÄ«ba ir mazÄka kÄ';
+$labels['valueislessthanequal'] = 'vÄ“rtÄ«ba ir vienÄda vai mazÄka kÄ';
$labels['valueequals'] = 'vÄ“rtÄ«ba ir vienÄda ar';
$labels['valuenotequals'] = 'vÄ“rtÄ«ba nav vienÄda ar';
$labels['setflags'] = 'Marķēt vēstuli';
@@ -96,82 +96,101 @@ $labels['removeflags'] = 'Noņemt vēstulei marķierus';
$labels['flagread'] = 'Lasītas';
$labels['flagdeleted'] = 'Dzēstas';
$labels['flaganswered'] = 'Atbildētas';
-$labels['flagflagged'] = 'IezÄ«mÄ“tÄs';
+$labels['flagflagged'] = 'MarÄ·Ä“tas';
$labels['flagdraft'] = 'Melnraksts';
-$labels['setvariable'] = 'Set variable';
-$labels['setvarname'] = 'Variable name:';
-$labels['setvarvalue'] = 'Variable value:';
-$labels['setvarmodifiers'] = 'Modifiers:';
-$labels['varlower'] = 'lower-case';
-$labels['varupper'] = 'upper-case';
-$labels['varlowerfirst'] = 'first character lower-case';
-$labels['varupperfirst'] = 'first character upper-case';
-$labels['varquotewildcard'] = 'quote special characters';
-$labels['varlength'] = 'length';
-$labels['notify'] = 'Send notification';
-$labels['notifyaddress'] = 'To e-mail address:';
-$labels['notifybody'] = 'Notification body:';
-$labels['notifysubject'] = 'Notification subject:';
-$labels['notifyfrom'] = 'Notification sender:';
-$labels['notifyimportance'] = 'Importance:';
-$labels['notifyimportancelow'] = 'low';
-$labels['notifyimportancenormal'] = 'normal';
-$labels['notifyimportancehigh'] = 'high';
+$labels['setvariable'] = 'Iestatīt mainīgo';
+$labels['setvarname'] = 'MainÄ«gÄ nosaukums:';
+$labels['setvarvalue'] = 'MainÄ«gÄ vÄ“rtÄ«ba:';
+$labels['setvarmodifiers'] = 'Modifikatori:';
+$labels['varlower'] = 'mazie burti';
+$labels['varupper'] = 'lielie burti';
+$labels['varlowerfirst'] = 'pirmais burts kÄ mazais burts';
+$labels['varupperfirst'] = 'pirmais burts kÄ lielais burts';
+$labels['varquotewildcard'] = '"citÄ“t" speciÄlÄs rakstzÄ«mes';
+$labels['varlength'] = 'garums';
+$labels['notify'] = 'Sūtīt paziņojumus';
+$labels['notifyaddress'] = 'Uz e-pasta adresi:';
+$labels['notifybody'] = 'Paziņojuma teksts:';
+$labels['notifysubject'] = 'Paziņojuma tēma:';
+$labels['notifyfrom'] = 'Paziņojuma sÅ«tÄ«tÄjs:';
+$labels['notifyimportance'] = 'Svarīgums:';
+$labels['notifyimportancelow'] = 'zems';
+$labels['notifyimportancenormal'] = 'parasts';
+$labels['notifyimportancehigh'] = 'augsts';
$labels['filtercreate'] = 'Izveidot filtru';
$labels['usedata'] = 'FiltrÄ izmantot sekojoÅ¡us datus';
$labels['nextstep'] = 'NÄkamais solis';
$labels['...'] = '...';
-$labels['advancedopts'] = 'PaplaÅ¡inÄti iestatÄ«jumi';
+$labels['currdate'] = 'Pašreizējais datums';
+$labels['datetest'] = 'Datums';
+$labels['dateheader'] = 'galvene:';
+$labels['year'] = 'gads';
+$labels['month'] = 'mēnesis';
+$labels['day'] = 'diena';
+$labels['date'] = 'datums (gggg-mm-dd)';
+$labels['julian'] = 'datums (JÅ«lija kalendÄrs)';
+$labels['hour'] = 'stunda';
+$labels['minute'] = 'minūte';
+$labels['second'] = 'sekunde';
+$labels['time'] = 'laiks (hh:mm:ss)';
+$labels['iso8601'] = 'datums (ISO8601)';
+$labels['std11'] = 'datums (RFC2822)';
+$labels['zone'] = 'laikajosla';
+$labels['weekday'] = 'nedēļas diena (0-6)';
+$labels['advancedopts'] = 'PaplaÅ¡inÄtie iestatÄ«jumi';
$labels['body'] = 'Pamatteksts';
$labels['address'] = 'adresÄts';
$labels['envelope'] = 'aploksne';
$labels['modifier'] = 'modifikators:';
$labels['text'] = 'teksts';
-$labels['undecoded'] = 'neatkodēts (jēldati)';
+$labels['undecoded'] = 'neatkodÄ“ts (neapstrÄdÄti dati)';
$labels['contenttype'] = 'satura tips';
$labels['modtype'] = 'tips:';
$labels['allparts'] = 'viss';
$labels['domain'] = 'domēns';
-$labels['localpart'] = 'vietÄ“jÄ daļa';
+$labels['localpart'] = 'lokÄlÄ daļa';
$labels['user'] = 'lietotÄjs';
$labels['detail'] = 'detaļas';
-$labels['comparator'] = 'komparators';
-$labels['default'] = 'noklusējums';
-$labels['octet'] = 'strikti (oktets)';
+$labels['comparator'] = 'salÄ«dzinÄtÄjs';
+$labels['default'] = 'noklusÄ“tÄ vÄ“rtÄ«ba';
+$labels['octet'] = 'precīzs (oktets)';
$labels['asciicasemap'] = 'reģistrnejutīgs (ascii tabula)';
$labels['asciinumeric'] = 'skaitļu (ascii skaitļu)';
+$labels['index'] = 'indekss:';
+$labels['indexlast'] = '"backwards"';
$messages = array();
-$messages['filterunknownerror'] = 'NezinÄma servera kļūda';
-$messages['filterconnerror'] = 'NeizdevÄs pieslÄ“gties ManageSieve serverim';
-$messages['filterdeleteerror'] = 'NeizdevÄs dzÄ“st filtru. Servera iekÅ¡Ä“jÄ kļūda';
-$messages['filterdeleted'] = 'Filtrs veiksmīgi izdzēsts';
-$messages['filtersaved'] = 'Filtrs veiksmÄ«gi saglabÄts';
-$messages['filtersaveerror'] = 'NeizdevÄs saglabÄt filtru. Servera iekÅ¡Ä“jÄ kļūda';
-$messages['filterdeleteconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to filtru?';
-$messages['ruledeleteconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to nosacÄ«jumu?';
-$messages['actiondeleteconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to darbÄ«bu?';
-$messages['forbiddenchars'] = 'Lauks satur aizliegtus simbolus';
-$messages['cannotbeempty'] = 'Lauks nedrīkst būt tukšs';
-$messages['ruleexist'] = 'Filter with specified name already exists.';
-$messages['setactivateerror'] = 'NeizdevÄs aktivizÄ“t atzÄ«mÄ“to filtru kopu. Servera iekÅ¡Ä“jÄ kļūda';
-$messages['setdeactivateerror'] = 'NeizdevÄs deaktivizÄ“t atzÄ«mÄ“to filtru kopu. Servera iekÅ¡Ä“jÄ kļūda';
-$messages['setdeleteerror'] = 'NeizdevÄs izdzÄ“st atzÄ«mÄ“to filtru kopu. Servera iekÅ¡Ä“jÄ kļūda';
-$messages['setactivated'] = 'Filtru kopa veiksmīgi aktivizēta';
-$messages['setdeactivated'] = 'Filtru kopa veiksmīgi deaktivizēta';
-$messages['setdeleted'] = 'Filtru kopa veiksmīgi izdzēsta';
-$messages['setdeleteconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to filtru kopu?';
-$messages['setcreateerror'] = 'NeizdevÄs izveidot filtru kopu. Servera iekÅ¡Ä“jÄ kļūda';
-$messages['setcreated'] = 'Filtru kopa veiksmīgi izveidota';
-$messages['activateerror'] = 'Unable to enable selected filter(s). Server error occured.';
-$messages['deactivateerror'] = 'Unable to disable selected filter(s). Server error occured.';
-$messages['deactivated'] = 'Filter(s) disabled successfully.';
-$messages['activated'] = 'Filter(s) enabled successfully.';
-$messages['moved'] = 'Filter moved successfully.';
-$messages['moveerror'] = 'Unable to move selected filter. Server error occured.';
-$messages['nametoolong'] = 'NeizdevÄs izveidot filtru kopu. PÄrÄk garÅ¡ kopas nosaukums';
-$messages['namereserved'] = 'Reserved name.';
-$messages['setexist'] = 'Set already exists.';
-$messages['nodata'] = 'At least one position must be selected!';
+$messages['filterunknownerror'] = 'NezinÄma servera kļūda.';
+$messages['filterconnerror'] = 'NeizdevÄs pieslÄ“gties ManageSieve serverim.';
+$messages['filterdeleteerror'] = 'NeizdevÄs izdzÄ“st filtru - servera kļūda.';
+$messages['filterdeleted'] = 'Filtrs veiksmīgi izdzēsts.';
+$messages['filtersaved'] = 'Filtrs veiksmÄ«gi saglabÄts.';
+$messages['filtersaveerror'] = 'NeizdevÄs saglabÄt filtru - servera kļūda.';
+$messages['filterdeleteconfirm'] = 'Vai JÅ«s tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to filtru?';
+$messages['ruledeleteconfirm'] = 'Vai JÅ«s tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to nosacÄ«jumu?';
+$messages['actiondeleteconfirm'] = 'Vai JÅ«s tieÅ¡Äm vÄ“laties dzÄ“st atzÄ«mÄ“to darbÄ«bu?';
+$messages['forbiddenchars'] = 'Lauks satur aizliegtus simbolus.';
+$messages['cannotbeempty'] = 'Lauks nedrīkst būt tukšs.';
+$messages['ruleexist'] = 'Filtrs ar tÄdu nosaukumu jau pastÄv.';
+$messages['setactivateerror'] = 'NeizdevÄs aktivizÄ“t atzÄ«mÄ“to filtru kopu - servera kļūda.';
+$messages['setdeactivateerror'] = 'NeizdevÄs deaktivizÄ“t atzÄ«mÄ“to filtru kopu - servera kļūda.';
+$messages['setdeleteerror'] = 'NeizdevÄs izdzÄ“st atzÄ«mÄ“to filtru kopu - servera kļūda.';
+$messages['setactivated'] = 'Filtru kopa veiksmīgi aktivizēta.';
+$messages['setdeactivated'] = 'Filtru kopa veiksmīgi deaktivizēta.';
+$messages['setdeleted'] = 'Filtru kopa veiksmīgi izdzēsta.';
+$messages['setdeleteconfirm'] = 'Vai tieÅ¡Äm JÅ«s vÄ“laties dzÄ“st atzÄ«mÄ“to filtru kopu?';
+$messages['setcreateerror'] = 'NeizdevÄs izveidot filtru kopu - servera kļūda.';
+$messages['setcreated'] = 'Filtru kopa veiksmīgi izveidota.';
+$messages['activateerror'] = 'Nav iespējams ieslēgt izvēlēto(s) filtru(s) - servera kļūda.';
+$messages['deactivateerror'] = 'Nav iespējams atslēgt izvēlēto(s) filtru(s) - servera kļūda.';
+$messages['deactivated'] = 'Filtrs(i) veiksmīgi atslēgts(i).';
+$messages['activated'] = 'Filtrs(i) veiksmīgi ieslēgts(i).';
+$messages['moved'] = 'Filtrs veiksmÄ«gi pÄrvietots.';
+$messages['moveerror'] = 'Nav iespÄ“jams pÄrvietot izvÄ“lÄ“to filtru - servera kļūda.';
+$messages['nametoolong'] = 'NeizdevÄs izveidot filtru kopu. PÄrÄk garÅ¡ kopas nosaukums.';
+$messages['namereserved'] = 'Rezervētais nosaukums.';
+$messages['setexist'] = 'Kopa jau eksistē.';
+$messages['nodata'] = 'Ir jÄbÅ«t atzÄ«mÄ“tai vismaz vienai pozÄ«cijai!';
+$messages['invaliddateformat'] = 'NederÄ«gs datums vai datuma formÄts';
?>
diff --git a/plugins/managesieve/localization/pl_PL.inc b/plugins/managesieve/localization/pl_PL.inc
index 287633727..799f0fb54 100644
--- a/plugins/managesieve/localization/pl_PL.inc
+++ b/plugins/managesieve/localization/pl_PL.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Dodaj';
$labels['del'] = 'Usuń';
$labels['sender'] = 'Nadawca';
$labels['recipient'] = 'Odbiorca';
-$labels['vacationaddr'] = 'Lista dodatkowych adresów odbiorców:';
+$labels['vacationaddr'] = 'Dodatkowy/e adres(y) e-mail:';
$labels['vacationdays'] = 'Częstotliwość wysyłania wiadomości (w dniach):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Jak często wysyłać wiadomości:';
+$labels['days'] = 'dni';
+$labels['seconds'] = 'sekundy';
$labels['vacationreason'] = 'Treść (przyczyna nieobecności):';
$labels['vacationsubject'] = 'Temat wiadomości:';
$labels['rulestop'] = 'Przerwij przetwarzanie reguł';
@@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'ilość jest równa lub większa od';
$labels['countislessthan'] = 'ilość jest mniejsza od';
$labels['countislessthanequal'] = 'ilość jest równa lub mniejsza od';
$labels['countequals'] = 'ilość jest równa';
-$labels['countnotequals'] = 'ilość jest różna od';
+$labels['countnotequals'] = 'ilość nie jest równa';
$labels['valueisgreaterthan'] = 'wartość jest większa od';
$labels['valueisgreaterthanequal'] = 'wartość jest równa lub większa od';
$labels['valueislessthan'] = 'wartość jest mniejsza od';
$labels['valueislessthanequal'] = 'wartość jest równa lub mniejsza od';
$labels['valueequals'] = 'wartość jest równa';
-$labels['valuenotequals'] = 'wartość jest różna od';
+$labels['valuenotequals'] = 'wartość nie jest równa';
$labels['setflags'] = 'Ustaw flagi wiadomości';
$labels['addflags'] = 'Dodaj flagi do wiadomości';
$labels['removeflags'] = 'Usuń flagi wiadomości';
@@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Utwórz filtr';
$labels['usedata'] = 'Użyj następujących danych do utworzenia filtra:';
$labels['nextstep'] = 'Następny krok';
$labels['...'] = '...';
+$labels['currdate'] = 'Bieżąca data';
+$labels['datetest'] = 'Data';
+$labels['dateheader'] = 'nagłówek:';
+$labels['year'] = 'rok';
+$labels['month'] = 'miesiÄ…c';
+$labels['day'] = 'dzień';
+$labels['date'] = 'data (rrrr-mm-dd)';
+$labels['julian'] = 'data (kalendarz juliański)';
+$labels['hour'] = 'godzina';
+$labels['minute'] = 'minuta';
+$labels['second'] = 'sekunda';
+$labels['time'] = 'czas (gg:mm:ss)';
+$labels['iso8601'] = 'data (ISO8601)';
+$labels['std11'] = 'data (RFC2822)';
+$labels['zone'] = 'Strefa czasowa';
+$labels['weekday'] = 'dzień tygodnia (0-6)';
$labels['advancedopts'] = 'Zaawansowane opcje';
$labels['body'] = 'Treść';
$labels['address'] = 'adres';
@@ -140,6 +156,8 @@ $labels['default'] = 'domyślny';
$labels['octet'] = 'dokładny (octet)';
$labels['asciicasemap'] = 'nierozróżniający wielkości liter (ascii-casemap)';
$labels['asciinumeric'] = 'numeryczny (ascii-numeric)';
+$labels['index'] = 'indeks:';
+$labels['indexlast'] = 'wstecz';
$messages = array();
$messages['filterunknownerror'] = 'Nieznany błąd serwera.';
@@ -173,5 +191,6 @@ $messages['nametoolong'] = 'Zbyt długa nazwa.';
$messages['namereserved'] = 'Nazwa zarezerwowana.';
$messages['setexist'] = 'Zbiór już istnieje.';
$messages['nodata'] = 'Należy wybrać co najmniej jedną pozycję!';
+$messages['invaliddateformat'] = 'Nieprawidłowy format daty lub fragmentu daty';
?>
diff --git a/plugins/managesieve/localization/pt_BR.inc b/plugins/managesieve/localization/pt_BR.inc
index 92c1e6ae6..cd96c49ca 100644
--- a/plugins/managesieve/localization/pt_BR.inc
+++ b/plugins/managesieve/localization/pt_BR.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Adicionar';
$labels['del'] = 'Excluir';
$labels['sender'] = 'Remetente';
$labels['recipient'] = 'Destinatário';
-$labels['vacationaddr'] = 'Lista adicional de e-mails destinatários:';
+$labels['vacationaddr'] = 'Meus endereços de e-mail adicionais:';
$labels['vacationdays'] = 'Enviar mensagens com que frequência (em dias):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Como geralmente enviam mensagens:';
+$labels['days'] = 'dias';
+$labels['seconds'] = 'segundos';
$labels['vacationreason'] = 'Corpo da mensagem (motivo de férias):';
$labels['vacationsubject'] = 'Título da mensagem:';
$labels['rulestop'] = 'Parar de avaliar regras';
@@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Criar filtro';
$labels['usedata'] = 'Usar os seguintes dados no filtro:';
$labels['nextstep'] = 'Próximo Passo';
$labels['...'] = '...';
+$labels['currdate'] = 'Data atual';
+$labels['datetest'] = 'Data';
+$labels['dateheader'] = 'cabeçalho:';
+$labels['year'] = 'ano';
+$labels['month'] = 'mês';
+$labels['day'] = 'dia';
+$labels['date'] = 'data (aaaa-mm-dd)';
+$labels['julian'] = 'data (calendário juliano)';
+$labels['hour'] = 'hora';
+$labels['minute'] = 'minuto';
+$labels['second'] = 'segundo';
+$labels['time'] = 'hora (hh:mm:ss)';
+$labels['iso8601'] = 'data (ISO8601)';
+$labels['std11'] = 'data (RFC2822)';
+$labels['zone'] = 'fuso horário';
+$labels['weekday'] = 'dia da semana (0-6)';
$labels['advancedopts'] = 'Opções avançadas';
$labels['body'] = 'Corpo';
$labels['address'] = 'endereço';
@@ -140,6 +156,8 @@ $labels['default'] = 'padrão';
$labels['octet'] = 'estrito (octeto)';
$labels['asciicasemap'] = 'caso insensível (mapa de caracteres ascii)';
$labels['asciinumeric'] = 'numérico (ascii-numeric)';
+$labels['index'] = 'índice:';
+$labels['indexlast'] = 'retroceder';
$messages = array();
$messages['filterunknownerror'] = 'Erro desconhecido de servidor';
@@ -173,5 +191,6 @@ $messages['nametoolong'] = 'Nome muito longo.';
$messages['namereserved'] = 'Nome reservado.';
$messages['setexist'] = 'Conjunto já existe.';
$messages['nodata'] = 'Pelo menos uma posição precisa ser selecionada!';
+$messages['invaliddateformat'] = 'Data inválida';
?>
diff --git a/plugins/managesieve/localization/ru_RU.inc b/plugins/managesieve/localization/ru_RU.inc
index 6aab60da6..f922bcf22 100644
--- a/plugins/managesieve/localization/ru_RU.inc
+++ b/plugins/managesieve/localization/ru_RU.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Добавить';
$labels['del'] = 'Удалить';
$labels['sender'] = 'Отправитель';
$labels['recipient'] = 'Получатель';
-$labels['vacationaddr'] = 'СпиÑок моих дополнительных адреÑов:';
+$labels['vacationaddr'] = 'Мои дополнительные адреÑа:';
$labels['vacationdays'] = 'Как чаÑто отправлÑÑ‚ÑŒ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (в днÑÑ…):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'Как чаÑто отправлÑÑ‚ÑŒ ÑообщениÑ:';
+$labels['days'] = 'дней';
+$labels['seconds'] = 'Ñекунд';
$labels['vacationreason'] = 'ТекÑÑ‚ ÑÐ¾Ð¾Ð±Ñ‰ÐµÐ½Ð¸Ñ (причина отÑутÑтвиÑ):';
$labels['vacationsubject'] = 'Тема ÑообщениÑ:';
$labels['rulestop'] = 'Закончить выполнение';
@@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Создать фильтр';
$labels['usedata'] = 'ИÑпользовать Ñледующие данные в фильтре:';
$labels['nextstep'] = 'Далее';
$labels['...'] = '...';
+$labels['currdate'] = 'Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð´Ð°Ñ‚Ð°';
+$labels['datetest'] = 'Дата';
+$labels['dateheader'] = 'заголовок:';
+$labels['year'] = 'год';
+$labels['month'] = 'меÑÑц';
+$labels['day'] = 'день';
+$labels['date'] = 'дата (гггг-мм-дд)';
+$labels['julian'] = 'дата (юлианÑкаÑ)';
+$labels['hour'] = 'чаÑ';
+$labels['minute'] = 'минута';
+$labels['second'] = 'Ñекунда';
+$labels['time'] = 'Ð²Ñ€ÐµÐ¼Ñ (чч:мм:ÑÑ)';
+$labels['iso8601'] = 'дата (ISO8601)';
+$labels['std11'] = 'дата (RFC2822)';
+$labels['zone'] = 'чаÑовой поÑÑ';
+$labels['weekday'] = 'день недели (0-6)';
$labels['advancedopts'] = 'Дополнительные параметры';
$labels['body'] = 'Тело пиÑьма';
$labels['address'] = 'адреÑ';
@@ -140,6 +156,8 @@ $labels['default'] = 'по умолчанию';
$labels['octet'] = 'Строгий (octet)';
$labels['asciicasemap'] = 'РегиÑтронезавиÑимый (ascii-casemap)';
$labels['asciinumeric'] = 'ЧиÑловой (ascii-numeric)';
+$labels['index'] = 'индекÑ:';
+$labels['indexlast'] = 'наоборот';
$messages = array();
$messages['filterunknownerror'] = 'ÐеизвеÑÑ‚Ð½Ð°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ° Ñервера';
@@ -173,5 +191,6 @@ $messages['nametoolong'] = 'Ðевозможно Ñоздать набор фиÐ
$messages['namereserved'] = 'Зарезервированное имÑ.';
$messages['setexist'] = 'Ðабор уже ÑущеÑтвует.';
$messages['nodata'] = 'Ðужно выбрать Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ одну позицию!';
+$messages['invaliddateformat'] = 'ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð´Ð°Ñ‚Ð° или формат чаÑти даты';
?>
diff --git a/plugins/managesieve/localization/sl_SI.inc b/plugins/managesieve/localization/sl_SI.inc
index 0a30a3a87..aa82078f1 100644
--- a/plugins/managesieve/localization/sl_SI.inc
+++ b/plugins/managesieve/localization/sl_SI.inc
@@ -55,11 +55,11 @@ $labels['add'] = 'Dodaj';
$labels['del'] = 'Izbriši';
$labels['sender'] = 'Pošiljatelj';
$labels['recipient'] = 'Prejemnik';
-$labels['vacationaddr'] = 'Dodaten seznam naslovov prejemnikov:';
+$labels['vacationaddr'] = 'Moji dodatni e-naslovi';
$labels['vacationdays'] = 'Kako pogosto naj bodo sporoÄila poslana (v dnevih):';
-$labels['vacationinterval'] = 'How often send messages:';
-$labels['days'] = 'days';
-$labels['seconds'] = 'seconds';
+$labels['vacationinterval'] = 'SporoÄila poÅ¡lji na:';
+$labels['days'] = 'dni';
+$labels['seconds'] = 'sekund';
$labels['vacationreason'] = 'Vsebina sporoÄila (vzrok za odsotnost):';
$labels['vacationsubject'] = 'Zadeva sporoÄila';
$labels['rulestop'] = 'Prekini z izvajanjem pravil';
@@ -83,13 +83,13 @@ $labels['countisgreaterthanequal'] = 'seÅ¡tevek je veÄji ali enak';
$labels['countislessthan'] = 'seštevek je manjši od';
$labels['countislessthanequal'] = 'seštevel je manjši ali enak';
$labels['countequals'] = 'seštevek je enak';
-$labels['countnotequals'] = 'seštevek ni enak';
+$labels['countnotequals'] = 'vsota ne ustreza';
$labels['valueisgreaterthan'] = 'vrednost je veÄja od';
$labels['valueisgreaterthanequal'] = 'vrednost je veÄja ali enaka';
$labels['valueislessthan'] = 'vrednost je manjša od';
$labels['valueislessthanequal'] = 'vrednost je manjša ali enaka';
$labels['valueequals'] = 'vrednost je enaka';
-$labels['valuenotequals'] = 'vrednost je neenaka';
+$labels['valuenotequals'] = 'vrednost ni enaka';
$labels['setflags'] = 'OznaÄi sporoÄilo';
$labels['addflags'] = 'OznaÄi sporoÄilo';
$labels['removeflags'] = 'Odstrani zaznamke s sporoÄil';
@@ -121,6 +121,22 @@ $labels['filtercreate'] = 'Ustvari filter';
$labels['usedata'] = 'Pri stvarjanju filtra uporabi naslednje podatke';
$labels['nextstep'] = 'Naslednji korak';
$labels['...'] = '...';
+$labels['currdate'] = 'Današnji datum';
+$labels['datetest'] = 'Datum';
+$labels['dateheader'] = 'glava:';
+$labels['year'] = 'leto';
+$labels['month'] = 'mesec';
+$labels['day'] = 'dan';
+$labels['date'] = 'datum(yyyy-mm-dd)';
+$labels['julian'] = 'datum (julijanski)';
+$labels['hour'] = 'ura';
+$labels['minute'] = 'minuta';
+$labels['second'] = 'sekunda';
+$labels['time'] = 'Äas';
+$labels['iso8601'] = 'datum (ISO8601)';
+$labels['std11'] = 'datum (RFC2822)';
+$labels['zone'] = 'Äasovni pas';
+$labels['weekday'] = 'dan v tednu (0-6)';
$labels['advancedopts'] = 'Dodatne možnosti';
$labels['body'] = 'Vsebina';
$labels['address'] = 'naslov';
@@ -140,6 +156,8 @@ $labels['default'] = 'privzeto';
$labels['octet'] = 'strict (octet)';
$labels['asciicasemap'] = 'ni obÄutljiv na velike/male Ärke (ascii-casemap)';
$labels['asciinumeric'] = 'numeriÄno (ascii-numeric)';
+$labels['index'] = 'indeks:';
+$labels['indexlast'] = 'obraten vrstni red';
$messages = array();
$messages['filterunknownerror'] = 'Prišlo je do neznane napake.';
@@ -173,5 +191,6 @@ $messages['nametoolong'] = 'Ime je predolgo.';
$messages['namereserved'] = 'Rezervirano ime.';
$messages['setexist'] = 'Nastavitev filtra že obstaja.';
$messages['nodata'] = 'Izbrana mora biti vsaj ena nastavitev!';
+$messages['invaliddateformat'] = 'Neveljaven datum ali oblika zapisa datuma';
?>
diff --git a/plugins/managesieve/managesieve.js b/plugins/managesieve/managesieve.js
index a1f31bb25..5201284fa 100644
--- a/plugins/managesieve/managesieve.js
+++ b/plugins/managesieve/managesieve.js
@@ -263,7 +263,7 @@ rcube_webmail.prototype.managesieve_updatelist = function(action, o)
var i, row = $('#rcmrow'+this.managesieve_rowid(o.id));
if (o.name)
- $('td', row).html(o.name);
+ $('td', row).text(o.name);
if (o.disabled)
row.addClass('disabled');
else
@@ -278,7 +278,7 @@ rcube_webmail.prototype.managesieve_updatelist = function(action, o)
var list = this.filters_list,
row = $('<tr><td class="name"></td></tr>');
- $('td', row).html(o.name);
+ $('td', row).text(o.name);
row.attr('id', 'rcmrow'+o.id);
if (o.disabled)
row.addClass('disabled');
@@ -302,7 +302,7 @@ rcube_webmail.prototype.managesieve_updatelist = function(action, o)
tr = document.createElement('TR');
td = document.createElement('TD');
- td.innerHTML = el.name;
+ $(td).text(el.name);
td.className = 'name';
tr.id = 'rcmrow' + el.id;
if (el['class'])
@@ -351,7 +351,7 @@ rcube_webmail.prototype.managesieve_updatelist = function(action, o)
list = this.filtersets_list,
row = $('<tr class="disabled"><td class="name"></td></tr>');
- $('td', row).html(o.name);
+ $('td', row).text(o.name);
row.attr('id', 'rcmrow'+id);
this.env.filtersets[id] = o.name;
@@ -578,35 +578,42 @@ function rule_header_select(id)
header = document.getElementById('custom_header' + id + '_list'),
mod = document.getElementById('rule_mod' + id),
trans = document.getElementById('rule_trans' + id),
- comp = document.getElementById('rule_comp' + id);
+ comp = document.getElementById('rule_comp' + id),
+ datepart = document.getElementById('rule_date_part' + id),
+ dateheader = document.getElementById('rule_date_header_div' + id),
+ h = obj.value;
- if (obj.value == 'size') {
+ if (h == 'size') {
size.style.display = 'inline';
- op.style.display = 'none';
- header.style.display = 'none';
- mod.style.display = 'none';
- trans.style.display = 'none';
- comp.style.display = 'none';
+ $.each([op, header, mod, trans, comp], function() { this.style.display = 'none'; });
}
else {
- header.style.display = obj.value != '...' ? 'none' : 'inline-block';
+ header.style.display = h != '...' ? 'none' : 'inline-block';
size.style.display = 'none';
op.style.display = 'inline';
comp.style.display = '';
- mod.style.display = obj.value == 'body' ? 'none' : 'block';
- trans.style.display = obj.value == 'body' ? 'block' : 'none';
+ mod.style.display = h == 'body' || h == 'currentdate' || h == 'date' ? 'none' : 'block';
+ trans.style.display = h == 'body' ? 'block' : 'none';
}
- rule_op_select(op, id, obj.value);
- obj.style.width = obj.value == '...' ? '40px' : '';
+ if (datepart)
+ datepart.style.display = h == 'currentdate' || h == 'date' ? 'inline' : 'none';
+ if (dateheader)
+ dateheader.style.display = h == 'date' ? '' : 'none';
+
+ rule_op_select(op, id, h);
+ rule_mod_select(id, h);
+ obj.style.width = h == '...' ? '40px' : '';
};
function rule_op_select(obj, id, header)
{
- var target = document.getElementById('rule_target' + id + '_list'),
- style = obj.value == 'exists' || obj.value == 'notexists' || header == 'size' ? 'none' : 'inline-block';
+ var target = document.getElementById('rule_target' + id + '_list');
+
+ if (!header)
+ header = document.getElementById('header' + id).value;
- target.style.display = style;
+ target.style.display = obj.value == 'exists' || obj.value == 'notexists' || header == 'size' ? 'none' : 'inline-block';
};
function rule_trans_select(id)
@@ -617,12 +624,19 @@ function rule_trans_select(id)
target.style.display = obj.value != 'content' ? 'none' : 'inline';
};
-function rule_mod_select(id)
+function rule_mod_select(id, header)
{
var obj = document.getElementById('rule_mod_op' + id),
- target = document.getElementById('rule_mod_type' + id);
+ target = document.getElementById('rule_mod_type' + id),
+ index = document.getElementById('rule_index_div' + id);
+
+ if (!header)
+ header = document.getElementById('header' + id).value;
target.style.display = obj.value != 'address' && obj.value != 'envelope' ? 'none' : 'inline';
+
+ if (index)
+ index.style.display = header != 'body' && header != 'currentdate' && header != 'size' && obj.value != 'envelope' ? '' : 'none';
};
function rule_join_radio(value)
@@ -646,8 +660,9 @@ function rule_adv_switch(id, elem)
function action_type_select(id)
{
+console.log(id);
var obj = document.getElementById('action_type' + id),
- enabled = {},
+ v = obj.value, enabled = {},
elems = {
mailbox: document.getElementById('action_mailbox' + id),
target: document.getElementById('action_target' + id),
@@ -658,25 +673,25 @@ function action_type_select(id)
notify: document.getElementById('action_notify' + id)
};
- if (obj.value == 'fileinto' || obj.value == 'fileinto_copy') {
+ if (v == 'fileinto' || v == 'fileinto_copy') {
enabled.mailbox = 1;
}
- else if (obj.value == 'redirect' || obj.value == 'redirect_copy') {
+ else if (v == 'redirect' || v == 'redirect_copy') {
enabled.target = 1;
}
- else if (obj.value.match(/^reject|ereject$/)) {
+ else if (v.match(/^reject|ereject$/)) {
enabled.target_area = 1;
}
- else if (obj.value.match(/^(add|set|remove)flag$/)) {
+ else if (v.match(/^(add|set|remove)flag$/)) {
enabled.flags = 1;
}
- else if (obj.value == 'vacation') {
+ else if (v == 'vacation') {
enabled.vacation = 1;
}
- else if (obj.value == 'set') {
+ else if (v == 'set') {
enabled.set = 1;
}
- else if (obj.value == 'notify') {
+ else if (v == 'notify') {
enabled.notify = 1;
}
diff --git a/plugins/managesieve/managesieve.php b/plugins/managesieve/managesieve.php
index 63ca97a70..6970193c2 100644
--- a/plugins/managesieve/managesieve.php
+++ b/plugins/managesieve/managesieve.php
@@ -12,60 +12,28 @@
*
* Configuration (see config.inc.php.dist)
*
- * Copyright (C) 2008-2012, The Roundcube Dev Team
- * Copyright (C) 2011-2012, Kolab Systems AG
+ * Copyright (C) 2008-2013, The Roundcube Dev Team
+ * Copyright (C) 2011-2013, Kolab Systems AG
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
*/
class managesieve extends rcube_plugin
{
public $task = 'mail|settings';
-
private $rc;
- private $sieve;
- private $errors;
- private $form;
- private $tips = array();
- private $script = array();
- private $exts = array();
- private $list;
- private $active = array();
- private $headers = array(
- 'subject' => 'Subject',
- 'from' => 'From',
- 'to' => 'To',
- );
- private $addr_headers = array(
- // Required
- "from", "to", "cc", "bcc", "sender", "resent-from", "resent-to",
- // Additional (RFC 822 / RFC 2822)
- "reply-to", "resent-reply-to", "resent-sender", "resent-cc", "resent-bcc",
- // Non-standard (RFC 2076, draft-palme-mailext-headers-08.txt)
- "for-approval", "for-handling", "for-comment", "apparently-to", "errors-to",
- "delivered-to", "return-receipt-to", "x-admin", "read-receipt-to",
- "x-confirm-reading-to", "return-receipt-requested",
- "registered-mail-reply-requested-by", "mail-followup-to", "mail-reply-to",
- "abuse-reports-to", "x-complaints-to", "x-report-abuse-to",
- // Undocumented
- "x-beenthere",
- );
-
- const VERSION = '6.2';
- const PROGNAME = 'Roundcube (Managesieve)';
- const PORT = 4190;
-
+ private $engine;
function init()
{
@@ -92,10 +60,11 @@ class managesieve extends rcube_plugin
/**
* Initializes plugin's UI (localization, js script)
*/
- private function init_ui()
+ function init_ui()
{
- if ($this->ui_initialized)
+ if ($this->ui_initialized) {
return;
+ }
// load localization
$this->add_texts('localization/', array('filters','managefilters'));
@@ -185,352 +154,18 @@ class managesieve extends rcube_plugin
}
/**
- * Loads configuration, initializes plugin (including sieve connection)
+ * Plugin action handler
*/
- function managesieve_start()
- {
- $this->load_config();
-
- // register UI objects
- $this->rc->output->add_handlers(array(
- 'filterslist' => array($this, 'filters_list'),
- 'filtersetslist' => array($this, 'filtersets_list'),
- 'filterframe' => array($this, 'filter_frame'),
- 'filterform' => array($this, 'filter_form'),
- 'filtersetform' => array($this, 'filterset_form'),
- ));
-
- // Add include path for internal classes
- $include_path = $this->home . '/lib' . PATH_SEPARATOR;
- $include_path .= ini_get('include_path');
- set_include_path($include_path);
-
- // Get connection parameters
- $host = $this->rc->config->get('managesieve_host', 'localhost');
- $port = $this->rc->config->get('managesieve_port');
- $tls = $this->rc->config->get('managesieve_usetls', false);
-
- $host = rcube_utils::parse_host($host);
- $host = rcube_utils::idn_to_ascii($host);
-
- // remove tls:// prefix, set TLS flag
- if (($host = preg_replace('|^tls://|i', '', $host, 1, $cnt)) && $cnt) {
- $tls = true;
- }
-
- if (empty($port)) {
- $port = getservbyname('sieve', 'tcp');
- if (empty($port)) {
- $port = self::PORT;
- }
- }
-
- $plugin = $this->rc->plugins->exec_hook('managesieve_connect', array(
- 'user' => $_SESSION['username'],
- 'password' => $this->rc->decrypt($_SESSION['password']),
- 'host' => $host,
- 'port' => $port,
- 'usetls' => $tls,
- 'auth_type' => $this->rc->config->get('managesieve_auth_type'),
- 'disabled' => $this->rc->config->get('managesieve_disabled_extensions'),
- 'debug' => $this->rc->config->get('managesieve_debug', false),
- 'auth_cid' => $this->rc->config->get('managesieve_auth_cid'),
- 'auth_pw' => $this->rc->config->get('managesieve_auth_pw'),
- ));
-
- // try to connect to managesieve server and to fetch the script
- $this->sieve = new rcube_sieve(
- $plugin['user'],
- $plugin['password'],
- $plugin['host'],
- $plugin['port'],
- $plugin['auth_type'],
- $plugin['usetls'],
- $plugin['disabled'],
- $plugin['debug'],
- $plugin['auth_cid'],
- $plugin['auth_pw']
- );
-
- if (!($error = $this->sieve->error())) {
- // Get list of scripts
- $list = $this->list_scripts();
-
- if (!empty($_GET['_set']) || !empty($_POST['_set'])) {
- $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
- }
- else if (!empty($_SESSION['managesieve_current'])) {
- $script_name = $_SESSION['managesieve_current'];
- }
- else {
- // get (first) active script
- if (!empty($this->active[0])) {
- $script_name = $this->active[0];
- }
- else if ($list) {
- $script_name = $list[0];
- }
- // create a new (initial) script
- else {
- // if script not exists build default script contents
- $script_file = $this->rc->config->get('managesieve_default');
- $script_name = $this->rc->config->get('managesieve_script_name');
-
- if (empty($script_name))
- $script_name = 'roundcube';
-
- if ($script_file && is_readable($script_file))
- $content = file_get_contents($script_file);
-
- // add script and set it active
- if ($this->sieve->save_script($script_name, $content)) {
- $this->activate_script($script_name);
- $this->list[] = $script_name;
- }
- }
- }
-
- if ($script_name) {
- $this->sieve->load($script_name);
- }
-
- $error = $this->sieve->error();
- }
-
- // finally set script objects
- if ($error) {
- switch ($error) {
- case SIEVE_ERROR_CONNECTION:
- case SIEVE_ERROR_LOGIN:
- $this->rc->output->show_message('managesieve.filterconnerror', 'error');
- break;
- default:
- $this->rc->output->show_message('managesieve.filterunknownerror', 'error');
- break;
- }
-
- rcube::raise_error(array('code' => 403, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Unable to connect to managesieve on $host:$port"), true, false);
-
- // to disable 'Add filter' button set env variable
- $this->rc->output->set_env('filterconnerror', true);
- $this->script = array();
- }
- else {
- $this->exts = $this->sieve->get_extensions();
- $this->script = $this->sieve->script->as_array();
- $this->rc->output->set_env('currentset', $this->sieve->current);
- $_SESSION['managesieve_current'] = $this->sieve->current;
- }
-
- return $error;
- }
-
function managesieve_actions()
{
$this->init_ui();
-
- $error = $this->managesieve_start();
-
- // Handle user requests
- if ($action = rcube_utils::get_input_value('_act', rcube_utils::INPUT_GPC)) {
- $fid = (int) rcube_utils::get_input_value('_fid', rcube_utils::INPUT_POST);
-
- if ($action == 'delete' && !$error) {
- if (isset($this->script[$fid])) {
- if ($this->sieve->script->delete_rule($fid))
- $result = $this->save_script();
-
- if ($result === true) {
- $this->rc->output->show_message('managesieve.filterdeleted', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'del', array('id' => $fid));
- } else {
- $this->rc->output->show_message('managesieve.filterdeleteerror', 'error');
- }
- }
- }
- else if ($action == 'move' && !$error) {
- if (isset($this->script[$fid])) {
- $to = (int) rcube_utils::get_input_value('_to', rcube_utils::INPUT_POST);
- $rule = $this->script[$fid];
-
- // remove rule
- unset($this->script[$fid]);
- $this->script = array_values($this->script);
-
- // add at target position
- if ($to >= count($this->script)) {
- $this->script[] = $rule;
- }
- else {
- $script = array();
- foreach ($this->script as $idx => $r) {
- if ($idx == $to)
- $script[] = $rule;
- $script[] = $r;
- }
- $this->script = $script;
- }
-
- $this->sieve->script->content = $this->script;
- $result = $this->save_script();
-
- if ($result === true) {
- $result = $this->list_rules();
-
- $this->rc->output->show_message('managesieve.moved', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'list',
- array('list' => $result, 'clear' => true, 'set' => $to));
- } else {
- $this->rc->output->show_message('managesieve.moveerror', 'error');
- }
- }
- }
- else if ($action == 'act' && !$error) {
- if (isset($this->script[$fid])) {
- $rule = $this->script[$fid];
- $disabled = $rule['disabled'] ? true : false;
- $rule['disabled'] = !$disabled;
- $result = $this->sieve->script->update_rule($fid, $rule);
-
- if ($result !== false)
- $result = $this->save_script();
-
- if ($result === true) {
- if ($rule['disabled'])
- $this->rc->output->show_message('managesieve.deactivated', 'confirmation');
- else
- $this->rc->output->show_message('managesieve.activated', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'update',
- array('id' => $fid, 'disabled' => $rule['disabled']));
- } else {
- if ($rule['disabled'])
- $this->rc->output->show_message('managesieve.deactivateerror', 'error');
- else
- $this->rc->output->show_message('managesieve.activateerror', 'error');
- }
- }
- }
- else if ($action == 'setact' && !$error) {
- $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
- $result = $this->activate_script($script_name);
- $kep14 = $this->rc->config->get('managesieve_kolab_master');
-
- if ($result === true) {
- $this->rc->output->set_env('active_sets', $this->active);
- $this->rc->output->show_message('managesieve.setactivated', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'setact',
- array('name' => $script_name, 'active' => true, 'all' => !$kep14));
- } else {
- $this->rc->output->show_message('managesieve.setactivateerror', 'error');
- }
- }
- else if ($action == 'deact' && !$error) {
- $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
- $result = $this->deactivate_script($script_name);
-
- if ($result === true) {
- $this->rc->output->set_env('active_sets', $this->active);
- $this->rc->output->show_message('managesieve.setdeactivated', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'setact',
- array('name' => $script_name, 'active' => false));
- } else {
- $this->rc->output->show_message('managesieve.setdeactivateerror', 'error');
- }
- }
- else if ($action == 'setdel' && !$error) {
- $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
- $result = $this->remove_script($script_name);
-
- if ($result === true) {
- $this->rc->output->show_message('managesieve.setdeleted', 'confirmation');
- $this->rc->output->command('managesieve_updatelist', 'setdel',
- array('name' => $script_name));
- $this->rc->session->remove('managesieve_current');
- } else {
- $this->rc->output->show_message('managesieve.setdeleteerror', 'error');
- }
- }
- else if ($action == 'setget') {
- $script_name = rcube_utils::get_input_value('_set', rcube_utils::INPUT_GPC, true);
- $script = $this->sieve->get_script($script_name);
-
- if (PEAR::isError($script))
- exit;
-
- $browser = new rcube_browser;
-
- // send download headers
- header("Content-Type: application/octet-stream");
- header("Content-Length: ".strlen($script));
-
- if ($browser->ie)
- header("Content-Type: application/force-download");
- if ($browser->ie && $browser->ver < 7)
- $filename = rawurlencode(abbreviate_string($script_name, 55));
- else if ($browser->ie)
- $filename = rawurlencode($script_name);
- else
- $filename = addcslashes($script_name, '\\"');
-
- header("Content-Disposition: attachment; filename=\"$filename.txt\"");
- echo $script;
- exit;
- }
- else if ($action == 'list') {
- $result = $this->list_rules();
-
- $this->rc->output->command('managesieve_updatelist', 'list', array('list' => $result));
- }
- else if ($action == 'ruleadd') {
- $rid = rcube_utils::get_input_value('_rid', rcube_utils::INPUT_GPC);
- $id = $this->genid();
- $content = $this->rule_div($fid, $id, false);
-
- $this->rc->output->command('managesieve_rulefill', $content, $id, $rid);
- }
- else if ($action == 'actionadd') {
- $aid = rcube_utils::get_input_value('_aid', rcube_utils::INPUT_GPC);
- $id = $this->genid();
- $content = $this->action_div($fid, $id, false);
-
- $this->rc->output->command('managesieve_actionfill', $content, $id, $aid);
- }
-
- $this->rc->output->send();
- }
- else if ($this->rc->task == 'mail') {
- // Initialize the form
- $rules = rcube_utils::get_input_value('r', rcube_utils::INPUT_GET);
- if (!empty($rules)) {
- $i = 0;
- foreach ($rules as $rule) {
- list($header, $value) = explode(':', $rule, 2);
- $tests[$i] = array(
- 'type' => 'contains',
- 'test' => 'header',
- 'arg1' => $header,
- 'arg2' => $value,
- );
- $i++;
- }
-
- $this->form = array(
- 'join' => count($tests) > 1 ? 'allof' : 'anyof',
- 'name' => '',
- 'tests' => $tests,
- 'actions' => array(
- 0 => array('type' => 'fileinto'),
- 1 => array('type' => 'stop'),
- ),
- );
- }
- }
-
- $this->managesieve_send();
+ $engine = $this->get_engine();
+ $engine->actions();
}
+ /**
+ * Forms save action handler
+ */
function managesieve_save()
{
// load localization
@@ -541,1551 +176,26 @@ class managesieve extends rcube_plugin
$this->include_script('managesieve.js');
}
- // Init plugin and handle managesieve connection
- $error = $this->managesieve_start();
-
- // get request size limits (#1488648)
- $max_post = max(array(
- ini_get('max_input_vars'),
- ini_get('suhosin.request.max_vars'),
- ini_get('suhosin.post.max_vars'),
- ));
- $max_depth = max(array(
- ini_get('suhosin.request.max_array_depth'),
- ini_get('suhosin.post.max_array_depth'),
- ));
-
- // check request size limit
- if ($max_post && count($_POST, COUNT_RECURSIVE) >= $max_post) {
- rcube::raise_error(array(
- 'code' => 500, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Request size limit exceeded (one of max_input_vars/suhosin.request.max_vars/suhosin.post.max_vars)"
- ), true, false);
- $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
- }
- // check request depth limits
- else if ($max_depth && count($_POST['_header']) > $max_depth) {
- rcube::raise_error(array(
- 'code' => 500, 'type' => 'php',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Request size limit exceeded (one of suhosin.request.max_array_depth/suhosin.post.max_array_depth)"
- ), true, false);
- $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
- }
- // filters set add action
- else if (!empty($_POST['_newset'])) {
- $name = rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true);
- $copy = rcube_utils::get_input_value('_copy', rcube_utils::INPUT_POST, true);
- $from = rcube_utils::get_input_value('_from', rcube_utils::INPUT_POST);
- $exceptions = $this->rc->config->get('managesieve_filename_exceptions');
- $kolab = $this->rc->config->get('managesieve_kolab_master');
- $name_uc = mb_strtolower($name);
- $list = $this->list_scripts();
-
- if (!$name) {
- $this->errors['name'] = $this->gettext('cannotbeempty');
- }
- else if (mb_strlen($name) > 128) {
- $this->errors['name'] = $this->gettext('nametoolong');
- }
- else if (!empty($exceptions) && in_array($name, (array)$exceptions)) {
- $this->errors['name'] = $this->gettext('namereserved');
- }
- else if (!empty($kolab) && in_array($name_uc, array('MASTER', 'USER', 'MANAGEMENT'))) {
- $this->errors['name'] = $this->gettext('namereserved');
- }
- else if (in_array($name, $list)) {
- $this->errors['name'] = $this->gettext('setexist');
- }
- else if ($from == 'file') {
- // from file
- if (is_uploaded_file($_FILES['_file']['tmp_name'])) {
- $file = file_get_contents($_FILES['_file']['tmp_name']);
- $file = preg_replace('/\r/', '', $file);
- // for security don't save script directly
- // check syntax before, like this...
- $this->sieve->load_script($file);
- if (!$this->save_script($name)) {
- $this->errors['file'] = $this->gettext('setcreateerror');
- }
- }
- else { // upload failed
- $err = $_FILES['_file']['error'];
-
- if ($err == UPLOAD_ERR_INI_SIZE || $err == UPLOAD_ERR_FORM_SIZE) {
- $msg = $this->rc->gettext(array('name' => 'filesizeerror',
- 'vars' => array('size' =>
- $this->rc->show_bytes(parse_bytes(ini_get('upload_max_filesize'))))));
- }
- else {
- $this->errors['file'] = $this->gettext('fileuploaderror');
- }
- }
- }
- else if (!$this->sieve->copy($name, $from == 'set' ? $copy : '')) {
- $error = 'managesieve.setcreateerror';
- }
-
- if (!$error && empty($this->errors)) {
- // Find position of the new script on the list
- $list[] = $name;
- asort($list, SORT_LOCALE_STRING);
- $list = array_values($list);
- $index = array_search($name, $list);
-
- $this->rc->output->show_message('managesieve.setcreated', 'confirmation');
- $this->rc->output->command('parent.managesieve_updatelist', 'setadd',
- array('name' => $name, 'index' => $index));
- } else if ($msg) {
- $this->rc->output->command('display_message', $msg, 'error');
- } else if ($error) {
- $this->rc->output->show_message($error, 'error');
- }
- }
- // filter add/edit action
- else if (isset($_POST['_name'])) {
- $name = trim(rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST, true));
- $fid = trim(rcube_utils::get_input_value('_fid', rcube_utils::INPUT_POST));
- $join = trim(rcube_utils::get_input_value('_join', rcube_utils::INPUT_POST));
-
- // and arrays
- $headers = rcube_utils::get_input_value('_header', rcube_utils::INPUT_POST);
- $cust_headers = rcube_utils::get_input_value('_custom_header', rcube_utils::INPUT_POST);
- $ops = rcube_utils::get_input_value('_rule_op', rcube_utils::INPUT_POST);
- $sizeops = rcube_utils::get_input_value('_rule_size_op', rcube_utils::INPUT_POST);
- $sizeitems = rcube_utils::get_input_value('_rule_size_item', rcube_utils::INPUT_POST);
- $sizetargets = rcube_utils::get_input_value('_rule_size_target', rcube_utils::INPUT_POST);
- $targets = rcube_utils::get_input_value('_rule_target', rcube_utils::INPUT_POST, true);
- $mods = rcube_utils::get_input_value('_rule_mod', rcube_utils::INPUT_POST);
- $mod_types = rcube_utils::get_input_value('_rule_mod_type', rcube_utils::INPUT_POST);
- $body_trans = rcube_utils::get_input_value('_rule_trans', rcube_utils::INPUT_POST);
- $body_types = rcube_utils::get_input_value('_rule_trans_type', rcube_utils::INPUT_POST, true);
- $comparators = rcube_utils::get_input_value('_rule_comp', rcube_utils::INPUT_POST);
- $act_types = rcube_utils::get_input_value('_action_type', rcube_utils::INPUT_POST, true);
- $mailboxes = rcube_utils::get_input_value('_action_mailbox', rcube_utils::INPUT_POST, true);
- $act_targets = rcube_utils::get_input_value('_action_target', rcube_utils::INPUT_POST, true);
- $area_targets = rcube_utils::get_input_value('_action_target_area', rcube_utils::INPUT_POST, true);
- $reasons = rcube_utils::get_input_value('_action_reason', rcube_utils::INPUT_POST, true);
- $addresses = rcube_utils::get_input_value('_action_addresses', rcube_utils::INPUT_POST, true);
- $intervals = rcube_utils::get_input_value('_action_interval', rcube_utils::INPUT_POST);
- $interval_types = rcube_utils::get_input_value('_action_interval_type', rcube_utils::INPUT_POST);
- $subject = rcube_utils::get_input_value('_action_subject', rcube_utils::INPUT_POST, true);
- $flags = rcube_utils::get_input_value('_action_flags', rcube_utils::INPUT_POST);
- $varnames = rcube_utils::get_input_value('_action_varname', rcube_utils::INPUT_POST);
- $varvalues = rcube_utils::get_input_value('_action_varvalue', rcube_utils::INPUT_POST);
- $varmods = rcube_utils::get_input_value('_action_varmods', rcube_utils::INPUT_POST);
- $notifyaddrs = rcube_utils::get_input_value('_action_notifyaddress', rcube_utils::INPUT_POST);
- $notifybodies = rcube_utils::get_input_value('_action_notifybody', rcube_utils::INPUT_POST);
- $notifymessages = rcube_utils::get_input_value('_action_notifymessage', rcube_utils::INPUT_POST);
- $notifyfrom = rcube_utils::get_input_value('_action_notifyfrom', rcube_utils::INPUT_POST);
- $notifyimp = rcube_utils::get_input_value('_action_notifyimportance', rcube_utils::INPUT_POST);
-
- // we need a "hack" for radiobuttons
- foreach ($sizeitems as $item)
- $items[] = $item;
-
- $this->form['disabled'] = $_POST['_disabled'] ? true : false;
- $this->form['join'] = $join=='allof' ? true : false;
- $this->form['name'] = $name;
- $this->form['tests'] = array();
- $this->form['actions'] = array();
-
- if ($name == '')
- $this->errors['name'] = $this->gettext('cannotbeempty');
- else {
- foreach($this->script as $idx => $rule)
- if($rule['name'] == $name && $idx != $fid) {
- $this->errors['name'] = $this->gettext('ruleexist');
- break;
- }
- }
-
- $i = 0;
- // rules
- if ($join == 'any') {
- $this->form['tests'][0]['test'] = 'true';
- }
- else {
- foreach ($headers as $idx => $header) {
- // targets are indexed differently (assume form order)
- $target = $this->strip_value(array_shift($targets), true);
- $header = $this->strip_value($header);
- $operator = $this->strip_value($ops[$idx]);
- $comparator = $this->strip_value($comparators[$idx]);
-
- if ($header == 'size') {
- $sizeop = $this->strip_value($sizeops[$idx]);
- $sizeitem = $this->strip_value($items[$idx]);
- $sizetarget = $this->strip_value($sizetargets[$idx]);
-
- $this->form['tests'][$i]['test'] = 'size';
- $this->form['tests'][$i]['type'] = $sizeop;
- $this->form['tests'][$i]['arg'] = $sizetarget;
-
- if ($sizetarget == '')
- $this->errors['tests'][$i]['sizetarget'] = $this->gettext('cannotbeempty');
- else if (!preg_match('/^[0-9]+(K|M|G)?$/i', $sizetarget.$sizeitem, $m)) {
- $this->errors['tests'][$i]['sizetarget'] = $this->gettext('forbiddenchars');
- $this->form['tests'][$i]['item'] = $sizeitem;
- }
- else
- $this->form['tests'][$i]['arg'] .= $m[1];
- }
- else if ($header == 'body') {
- $trans = $this->strip_value($body_trans[$idx]);
- $trans_type = $this->strip_value($body_types[$idx], true);
-
- if (preg_match('/^not/', $operator))
- $this->form['tests'][$i]['not'] = true;
- $type = preg_replace('/^not/', '', $operator);
-
- if ($type == 'exists') {
- $this->errors['tests'][$i]['op'] = true;
- }
-
- $this->form['tests'][$i]['test'] = 'body';
- $this->form['tests'][$i]['type'] = $type;
- $this->form['tests'][$i]['arg'] = $target;
-
- if (empty($target) && $type != 'exists') {
- $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty');
- }
- else if (preg_match('/^(value|count)-/', $type)) {
- foreach ($target as $target_value) {
- if (!preg_match('/[0-9]+/', $target_value)) {
- $this->errors['tests'][$i]['target'] = $this->gettext('forbiddenchars');
- }
- }
- }
-
- $this->form['tests'][$i]['part'] = $trans;
- if ($trans == 'content') {
- $this->form['tests'][$i]['content'] = $trans_type;
- }
- }
- else {
- $cust_header = $headers = $this->strip_value(array_shift($cust_headers));
- $mod = $this->strip_value($mods[$idx]);
- $mod_type = $this->strip_value($mod_types[$idx]);
-
- if (preg_match('/^not/', $operator))
- $this->form['tests'][$i]['not'] = true;
- $type = preg_replace('/^not/', '', $operator);
-
- if ($header == '...') {
- if (!count($headers))
- $this->errors['tests'][$i]['header'] = $this->gettext('cannotbeempty');
- else {
- foreach ($headers as $hr) {
- // RFC2822: printable ASCII except colon
- if (!preg_match('/^[\x21-\x39\x41-\x7E]+$/i', $hr)) {
- $this->errors['tests'][$i]['header'] = $this->gettext('forbiddenchars');
- }
- }
- }
-
- if (empty($this->errors['tests'][$i]['header']))
- $cust_header = (is_array($headers) && count($headers) == 1) ? $headers[0] : $headers;
- }
-
- if ($type == 'exists') {
- $this->form['tests'][$i]['test'] = 'exists';
- $this->form['tests'][$i]['arg'] = $header == '...' ? $cust_header : $header;
- }
- else {
- $test = 'header';
- $header = $header == '...' ? $cust_header : $header;
-
- if ($mod == 'address' || $mod == 'envelope') {
- $found = false;
- if (empty($this->errors['tests'][$i]['header'])) {
- foreach ((array)$header as $hdr) {
- if (!in_array(strtolower(trim($hdr)), $this->addr_headers))
- $found = true;
- }
- }
- if (!$found)
- $test = $mod;
- }
-
- $this->form['tests'][$i]['type'] = $type;
- $this->form['tests'][$i]['test'] = $test;
- $this->form['tests'][$i]['arg1'] = $header;
- $this->form['tests'][$i]['arg2'] = $target;
-
- if (empty($target)) {
- $this->errors['tests'][$i]['target'] = $this->gettext('cannotbeempty');
- }
- else if (preg_match('/^(value|count)-/', $type)) {
- foreach ($target as $target_value) {
- if (!preg_match('/[0-9]+/', $target_value)) {
- $this->errors['tests'][$i]['target'] = $this->gettext('forbiddenchars');
- }
- }
- }
-
- if ($mod) {
- $this->form['tests'][$i]['part'] = $mod_type;
- }
- }
- }
-
- if ($header != 'size' && $comparator) {
- if (preg_match('/^(value|count)/', $this->form['tests'][$i]['type']))
- $comparator = 'i;ascii-numeric';
-
- $this->form['tests'][$i]['comparator'] = $comparator;
- }
-
- $i++;
- }
- }
-
- $i = 0;
- // actions
- foreach($act_types as $idx => $type) {
- $type = $this->strip_value($type);
- $target = $this->strip_value($act_targets[$idx]);
-
- switch ($type) {
-
- case 'fileinto':
- case 'fileinto_copy':
- $mailbox = $this->strip_value($mailboxes[$idx], false, false);
- $this->form['actions'][$i]['target'] = $this->mod_mailbox($mailbox, 'in');
- if ($type == 'fileinto_copy') {
- $type = 'fileinto';
- $this->form['actions'][$i]['copy'] = true;
- }
- break;
-
- case 'reject':
- case 'ereject':
- $target = $this->strip_value($area_targets[$idx]);
- $this->form['actions'][$i]['target'] = str_replace("\r\n", "\n", $target);
-
- // if ($target == '')
-// $this->errors['actions'][$i]['targetarea'] = $this->gettext('cannotbeempty');
- break;
-
- case 'redirect':
- case 'redirect_copy':
- $this->form['actions'][$i]['target'] = $target;
-
- if ($this->form['actions'][$i]['target'] == '')
- $this->errors['actions'][$i]['target'] = $this->gettext('cannotbeempty');
- else if (!rcube_utils::check_email($this->form['actions'][$i]['target']))
- $this->errors['actions'][$i]['target'] = $this->gettext('noemailwarning');
-
- if ($type == 'redirect_copy') {
- $type = 'redirect';
- $this->form['actions'][$i]['copy'] = true;
- }
- break;
-
- case 'addflag':
- case 'setflag':
- case 'removeflag':
- $_target = array();
- if (empty($flags[$idx])) {
- $this->errors['actions'][$i]['target'] = $this->gettext('noflagset');
- }
- else {
- foreach ($flags[$idx] as $flag) {
- $_target[] = $this->strip_value($flag);
- }
- }
- $this->form['actions'][$i]['target'] = $_target;
- break;
-
- case 'vacation':
- $reason = $this->strip_value($reasons[$idx]);
- $interval_type = $interval_types[$idx] == 'seconds' ? 'seconds' : 'days';
- $this->form['actions'][$i]['reason'] = str_replace("\r\n", "\n", $reason);
- $this->form['actions'][$i]['subject'] = $subject[$idx];
- $this->form['actions'][$i]['addresses'] = array_shift($addresses);
- $this->form['actions'][$i][$interval_type] = $intervals[$idx];
-// @TODO: vacation :mime, :from, :handle
-
- foreach ((array)$this->form['actions'][$i]['addresses'] as $aidx => $address) {
- if (!rcube_utils::check_email($address)) {
- $this->errors['actions'][$i]['addresses'] = $this->gettext('noemailwarning');
- break;
- }
- }
-
- if ($this->form['actions'][$i]['reason'] == '')
- $this->errors['actions'][$i]['reason'] = $this->gettext('cannotbeempty');
- if ($this->form['actions'][$i][$interval_type] && !preg_match('/^[0-9]+$/', $this->form['actions'][$i][$interval_type]))
- $this->errors['actions'][$i]['interval'] = $this->gettext('forbiddenchars');
- break;
-
- case 'set':
- $this->form['actions'][$i]['name'] = $varnames[$idx];
- $this->form['actions'][$i]['value'] = $varvalues[$idx];
- foreach ((array)$varmods[$idx] as $v_m) {
- $this->form['actions'][$i][$v_m] = true;
- }
-
- if (empty($varnames[$idx])) {
- $this->errors['actions'][$i]['name'] = $this->gettext('cannotbeempty');
- }
- else if (!preg_match('/^[0-9a-z_]+$/i', $varnames[$idx])) {
- $this->errors['actions'][$i]['name'] = $this->gettext('forbiddenchars');
- }
-
- if (!isset($varvalues[$idx]) || $varvalues[$idx] === '') {
- $this->errors['actions'][$i]['value'] = $this->gettext('cannotbeempty');
- }
- break;
-
- case 'notify':
- if (empty($notifyaddrs[$idx])) {
- $this->errors['actions'][$i]['address'] = $this->gettext('cannotbeempty');
- }
- else if (!rcube_utils::check_email($notifyaddrs[$idx])) {
- $this->errors['actions'][$i]['address'] = $this->gettext('noemailwarning');
- }
- if (!empty($notifyfrom[$idx]) && !rcube_utils::check_email($notifyfrom[$idx])) {
- $this->errors['actions'][$i]['from'] = $this->gettext('noemailwarning');
- }
- $this->form['actions'][$i]['address'] = $notifyaddrs[$idx];
- $this->form['actions'][$i]['body'] = $notifybodies[$idx];
- $this->form['actions'][$i]['message'] = $notifymessages[$idx];
- $this->form['actions'][$i]['from'] = $notifyfrom[$idx];
- $this->form['actions'][$i]['importance'] = $notifyimp[$idx];
- break;
- }
-
- $this->form['actions'][$i]['type'] = $type;
- $i++;
- }
-
- if (!$this->errors && !$error) {
- // zapis skryptu
- if (!isset($this->script[$fid])) {
- $fid = $this->sieve->script->add_rule($this->form);
- $new = true;
- } else
- $fid = $this->sieve->script->update_rule($fid, $this->form);
-
- if ($fid !== false)
- $save = $this->save_script();
-
- if ($save && $fid !== false) {
- $this->rc->output->show_message('managesieve.filtersaved', 'confirmation');
- if ($this->rc->task != 'mail') {
- $this->rc->output->command('parent.managesieve_updatelist',
- isset($new) ? 'add' : 'update',
- array(
- 'name' => rcube::Q($this->form['name']),
- 'id' => $fid,
- 'disabled' => $this->form['disabled']
- ));
- }
- else {
- $this->rc->output->command('managesieve_dialog_close');
- $this->rc->output->send('iframe');
- }
- }
- else {
- $this->rc->output->show_message('managesieve.filtersaveerror', 'error');
-// $this->rc->output->send();
- }
- }
- }
-
- $this->managesieve_send();
- }
-
- private function managesieve_send()
- {
- // Handle form action
- if (isset($_GET['_framed']) || isset($_POST['_framed'])) {
- if (isset($_GET['_newset']) || isset($_POST['_newset'])) {
- $this->rc->output->send('managesieve.setedit');
- }
- else {
- $this->rc->output->send('managesieve.filteredit');
- }
- } else {
- $this->rc->output->set_pagetitle($this->gettext('filters'));
- $this->rc->output->send('managesieve.managesieve');
- }
- }
-
- // return the filters list as HTML table
- function filters_list($attrib)
- {
- // add id to message list table if not specified
- if (!strlen($attrib['id']))
- $attrib['id'] = 'rcmfilterslist';
-
- // define list of cols to be displayed
- $a_show_cols = array('name');
-
- $result = $this->list_rules();
-
- // create XHTML table
- $out = $this->rc->table_output($attrib, $result, $a_show_cols, 'id');
-
- // set client env
- $this->rc->output->add_gui_object('filterslist', $attrib['id']);
- $this->rc->output->include_script('list.js');
-
- // add some labels to client
- $this->rc->output->add_label('managesieve.filterdeleteconfirm');
-
- return $out;
- }
-
- // return the filters list as <SELECT>
- function filtersets_list($attrib, $no_env = false)
- {
- // add id to message list table if not specified
- if (!strlen($attrib['id']))
- $attrib['id'] = 'rcmfiltersetslist';
-
- $list = $this->list_scripts();
-
- if ($list) {
- asort($list, SORT_LOCALE_STRING);
- }
-
- if (!empty($attrib['type']) && $attrib['type'] == 'list') {
- // define list of cols to be displayed
- $a_show_cols = array('name');
-
- if ($list) {
- foreach ($list as $idx => $set) {
- $scripts['S'.$idx] = $set;
- $result[] = array(
- 'name' => rcube::Q($set),
- 'id' => 'S'.$idx,
- 'class' => !in_array($set, $this->active) ? 'disabled' : '',
- );
- }
- }
-
- // create XHTML table
- $out = $this->rc->table_output($attrib, $result, $a_show_cols, 'id');
-
- $this->rc->output->set_env('filtersets', $scripts);
- $this->rc->output->include_script('list.js');
- }
- else {
- $select = new html_select(array('name' => '_set', 'id' => $attrib['id'],
- 'onchange' => $this->rc->task != 'mail' ? 'rcmail.managesieve_set()' : ''));
-
- if ($list) {
- foreach ($list as $set)
- $select->add($set, $set);
- }
-
- $out = $select->show($this->sieve->current);
- }
-
- // set client env
- if (!$no_env) {
- $this->rc->output->add_gui_object('filtersetslist', $attrib['id']);
- $this->rc->output->add_label('managesieve.setdeleteconfirm');
- }
-
- return $out;
- }
-
- function filter_frame($attrib)
- {
- if (!$attrib['id'])
- $attrib['id'] = 'rcmfilterframe';
-
- $attrib['name'] = $attrib['id'];
-
- $this->rc->output->set_env('contentframe', $attrib['name']);
- $this->rc->output->set_env('blankpage', $attrib['src'] ?
- $this->rc->output->abs_url($attrib['src']) : 'program/resources/blank.gif');
-
- return $this->rc->output->frame($attrib);
- }
-
- function filterset_form($attrib)
- {
- if (!$attrib['id'])
- $attrib['id'] = 'rcmfiltersetform';
-
- $out = '<form name="filtersetform" action="./" method="post" enctype="multipart/form-data">'."\n";
-
- $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $this->rc->task));
- $hiddenfields->add(array('name' => '_action', 'value' => 'plugin.managesieve-save'));
- $hiddenfields->add(array('name' => '_framed', 'value' => ($_POST['_framed'] || $_GET['_framed'] ? 1 : 0)));
- $hiddenfields->add(array('name' => '_newset', 'value' => 1));
-
- $out .= $hiddenfields->show();
-
- $name = rcube_utils::get_input_value('_name', rcube_utils::INPUT_POST);
- $copy = rcube_utils::get_input_value('_copy', rcube_utils::INPUT_POST);
- $selected = rcube_utils::get_input_value('_from', rcube_utils::INPUT_POST);
-
- // filter set name input
- $input_name = new html_inputfield(array('name' => '_name', 'id' => '_name', 'size' => 30,
- 'class' => ($this->errors['name'] ? 'error' : '')));
-
- $out .= sprintf('<label for="%s"><b>%s:</b></label> %s<br /><br />',
- '_name', rcube::Q($this->gettext('filtersetname')), $input_name->show($name));
-
- $out .="\n<fieldset class=\"itemlist\"><legend>" . $this->gettext('filters') . ":</legend>\n";
- $out .= '<input type="radio" id="from_none" name="_from" value="none"'
- .(!$selected || $selected=='none' ? ' checked="checked"' : '').'></input>';
- $out .= sprintf('<label for="%s">%s</label> ', 'from_none', rcube::Q($this->gettext('none')));
-
- // filters set list
- $list = $this->list_scripts();
- $select = new html_select(array('name' => '_copy', 'id' => '_copy'));
-
- if (is_array($list)) {
- asort($list, SORT_LOCALE_STRING);
-
- if (!$copy)
- $copy = $_SESSION['managesieve_current'];
-
- foreach ($list as $set) {
- $select->add($set, $set);
- }
-
- $out .= '<br /><input type="radio" id="from_set" name="_from" value="set"'
- .($selected=='set' ? ' checked="checked"' : '').'></input>';
- $out .= sprintf('<label for="%s">%s:</label> ', 'from_set', rcube::Q($this->gettext('fromset')));
- $out .= $select->show($copy);
- }
-
- // script upload box
- $upload = new html_inputfield(array('name' => '_file', 'id' => '_file', 'size' => 30,
- 'type' => 'file', 'class' => ($this->errors['file'] ? 'error' : '')));
-
- $out .= '<br /><input type="radio" id="from_file" name="_from" value="file"'
- .($selected=='file' ? ' checked="checked"' : '').'></input>';
- $out .= sprintf('<label for="%s">%s:</label> ', 'from_file', rcube::Q($this->gettext('fromfile')));
- $out .= $upload->show();
- $out .= '</fieldset>';
-
- $this->rc->output->add_gui_object('sieveform', 'filtersetform');
-
- if ($this->errors['name'])
- $this->add_tip('_name', $this->errors['name'], true);
- if ($this->errors['file'])
- $this->add_tip('_file', $this->errors['file'], true);
-
- $this->print_tips();
-
- return $out;
- }
-
-
- function filter_form($attrib)
- {
- if (!$attrib['id'])
- $attrib['id'] = 'rcmfilterform';
-
- $fid = rcube_utils::get_input_value('_fid', rcube_utils::INPUT_GPC);
- $scr = isset($this->form) ? $this->form : $this->script[$fid];
-
- $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $this->rc->task));
- $hiddenfields->add(array('name' => '_action', 'value' => 'plugin.managesieve-save'));
- $hiddenfields->add(array('name' => '_framed', 'value' => ($_POST['_framed'] || $_GET['_framed'] ? 1 : 0)));
- $hiddenfields->add(array('name' => '_fid', 'value' => $fid));
-
- $out = '<form name="filterform" action="./" method="post">'."\n";
- $out .= $hiddenfields->show();
-
- // 'any' flag
- if (sizeof($scr['tests']) == 1 && $scr['tests'][0]['test'] == 'true' && !$scr['tests'][0]['not'])
- $any = true;
-
- // filter name input
- $field_id = '_name';
- $input_name = new html_inputfield(array('name' => '_name', 'id' => $field_id, 'size' => 30,
- 'class' => ($this->errors['name'] ? 'error' : '')));
-
- if ($this->errors['name'])
- $this->add_tip($field_id, $this->errors['name'], true);
-
- if (isset($scr))
- $input_name = $input_name->show($scr['name']);
- else
- $input_name = $input_name->show();
-
- $out .= sprintf("\n<label for=\"%s\"><b>%s:</b></label> %s\n",
- $field_id, rcube::Q($this->gettext('filtername')), $input_name);
-
- // filter set selector
- if ($this->rc->task == 'mail') {
- $out .= sprintf("\n&nbsp;<label for=\"%s\"><b>%s:</b></label> %s\n",
- $field_id, rcube::Q($this->gettext('filterset')),
- $this->filtersets_list(array('id' => 'sievescriptname'), true));
- }
-
- $out .= '<br /><br /><fieldset><legend>' . rcube::Q($this->gettext('messagesrules')) . "</legend>\n";
-
- // any, allof, anyof radio buttons
- $field_id = '_allof';
- $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'allof',
- 'onclick' => 'rule_join_radio(\'allof\')', 'class' => 'radio'));
-
- if (isset($scr) && !$any)
- $input_join = $input_join->show($scr['join'] ? 'allof' : '');
- else
- $input_join = $input_join->show();
-
- $out .= sprintf("%s<label for=\"%s\">%s</label>&nbsp;\n",
- $input_join, $field_id, rcube::Q($this->gettext('filterallof')));
-
- $field_id = '_anyof';
- $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'anyof',
- 'onclick' => 'rule_join_radio(\'anyof\')', 'class' => 'radio'));
-
- if (isset($scr) && !$any)
- $input_join = $input_join->show($scr['join'] ? '' : 'anyof');
- else
- $input_join = $input_join->show('anyof'); // default
-
- $out .= sprintf("%s<label for=\"%s\">%s</label>\n",
- $input_join, $field_id, rcube::Q($this->gettext('filteranyof')));
-
- $field_id = '_any';
- $input_join = new html_radiobutton(array('name' => '_join', 'id' => $field_id, 'value' => 'any',
- 'onclick' => 'rule_join_radio(\'any\')', 'class' => 'radio'));
-
- $input_join = $input_join->show($any ? 'any' : '');
-
- $out .= sprintf("%s<label for=\"%s\">%s</label>\n",
- $input_join, $field_id, rcube::Q($this->gettext('filterany')));
-
- $rows_num = isset($scr) ? sizeof($scr['tests']) : 1;
-
- $out .= '<div id="rules"'.($any ? ' style="display: none"' : '').'>';
- for ($x=0; $x<$rows_num; $x++)
- $out .= $this->rule_div($fid, $x);
- $out .= "</div>\n";
-
- $out .= "</fieldset>\n";
-
- // actions
- $out .= '<fieldset><legend>' . rcube::Q($this->gettext('messagesactions')) . "</legend>\n";
-
- $rows_num = isset($scr) ? sizeof($scr['actions']) : 1;
-
- $out .= '<div id="actions">';
- for ($x=0; $x<$rows_num; $x++)
- $out .= $this->action_div($fid, $x);
- $out .= "</div>\n";
-
- $out .= "</fieldset>\n";
-
- $this->print_tips();
-
- if ($scr['disabled']) {
- $this->rc->output->set_env('rule_disabled', true);
- }
- $this->rc->output->add_label(
- 'managesieve.ruledeleteconfirm',
- 'managesieve.actiondeleteconfirm'
- );
- $this->rc->output->add_gui_object('sieveform', 'filterform');
-
- return $out;
- }
-
- function rule_div($fid, $id, $div=true)
- {
- $rule = isset($this->form) ? $this->form['tests'][$id] : $this->script[$fid]['tests'][$id];
- $rows_num = isset($this->form) ? sizeof($this->form['tests']) : sizeof($this->script[$fid]['tests']);
-
- // headers select
- $select_header = new html_select(array('name' => "_header[]", 'id' => 'header'.$id,
- 'onchange' => 'rule_header_select(' .$id .')'));
- foreach($this->headers as $name => $val)
- $select_header->add(rcube::Q($this->gettext($name)), Q($val));
- if (in_array('body', $this->exts))
- $select_header->add(rcube::Q($this->gettext('body')), 'body');
- $select_header->add(rcube::Q($this->gettext('size')), 'size');
- $select_header->add(rcube::Q($this->gettext('...')), '...');
-
- // TODO: list arguments
- $aout = '';
-
- if ((isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope')))
- && !is_array($rule['arg1']) && in_array($rule['arg1'], $this->headers)
- ) {
- $aout .= $select_header->show($rule['arg1']);
- }
- else if ((isset($rule['test']) && $rule['test'] == 'exists')
- && !is_array($rule['arg']) && in_array($rule['arg'], $this->headers)
- ) {
- $aout .= $select_header->show($rule['arg']);
- }
- else if (isset($rule['test']) && $rule['test'] == 'size')
- $aout .= $select_header->show('size');
- else if (isset($rule['test']) && $rule['test'] == 'body')
- $aout .= $select_header->show('body');
- else if (isset($rule['test']) && $rule['test'] != 'true')
- $aout .= $select_header->show('...');
- else
- $aout .= $select_header->show();
-
- if (isset($rule['test']) && in_array($rule['test'], array('header', 'address', 'envelope'))) {
- $custom = (array) $rule['arg1'];
- if (count($custom) == 1 && isset($this->headers[strtolower($custom[0])])) {
- unset($custom);
- }
- }
- else if (isset($rule['test']) && $rule['test'] == 'exists') {
- $custom = (array) $rule['arg'];
- if (count($custom) == 1 && isset($this->headers[strtolower($custom[0])])) {
- unset($custom);
- }
- }
-
- $tout = $this->list_input($id, 'custom_header', $custom, isset($custom),
- $this->error_class($id, 'test', 'header', 'custom_header'), 15) . "\n";
-
- // matching type select (operator)
- $select_op = new html_select(array('name' => "_rule_op[]", 'id' => 'rule_op'.$id,
- 'style' => 'display:' .($rule['test']!='size' ? 'inline' : 'none'),
- 'class' => 'operator_selector',
- 'onchange' => 'rule_op_select('.$id.')'));
- $select_op->add(rcube::Q($this->gettext('filtercontains')), 'contains');
- $select_op->add(rcube::Q($this->gettext('filternotcontains')), 'notcontains');
- $select_op->add(rcube::Q($this->gettext('filteris')), 'is');
- $select_op->add(rcube::Q($this->gettext('filterisnot')), 'notis');
- $select_op->add(rcube::Q($this->gettext('filterexists')), 'exists');
- $select_op->add(rcube::Q($this->gettext('filternotexists')), 'notexists');
- $select_op->add(rcube::Q($this->gettext('filtermatches')), 'matches');
- $select_op->add(rcube::Q($this->gettext('filternotmatches')), 'notmatches');
- if (in_array('regex', $this->exts)) {
- $select_op->add(rcube::Q($this->gettext('filterregex')), 'regex');
- $select_op->add(rcube::Q($this->gettext('filternotregex')), 'notregex');
- }
- if (in_array('relational', $this->exts)) {
- $select_op->add(rcube::Q($this->gettext('countisgreaterthan')), 'count-gt');
- $select_op->add(rcube::Q($this->gettext('countisgreaterthanequal')), 'count-ge');
- $select_op->add(rcube::Q($this->gettext('countislessthan')), 'count-lt');
- $select_op->add(rcube::Q($this->gettext('countislessthanequal')), 'count-le');
- $select_op->add(rcube::Q($this->gettext('countequals')), 'count-eq');
- $select_op->add(rcube::Q($this->gettext('countnotequals')), 'count-ne');
- $select_op->add(rcube::Q($this->gettext('valueisgreaterthan')), 'value-gt');
- $select_op->add(rcube::Q($this->gettext('valueisgreaterthanequal')), 'value-ge');
- $select_op->add(rcube::Q($this->gettext('valueislessthan')), 'value-lt');
- $select_op->add(rcube::Q($this->gettext('valueislessthanequal')), 'value-le');
- $select_op->add(rcube::Q($this->gettext('valueequals')), 'value-eq');
- $select_op->add(rcube::Q($this->gettext('valuenotequals')), 'value-ne');
- }
-
- // target input (TODO: lists)
-
- if (in_array($rule['test'], array('header', 'address', 'envelope'))) {
- $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
- $target = $rule['arg2'];
- }
- else if ($rule['test'] == 'body') {
- $test = ($rule['not'] ? 'not' : '').($rule['type'] ? $rule['type'] : 'is');
- $target = $rule['arg'];
- }
- else if ($rule['test'] == 'size') {
- $test = '';
- $target = '';
- if (preg_match('/^([0-9]+)(K|M|G)?$/', $rule['arg'], $matches)) {
- $sizetarget = $matches[1];
- $sizeitem = $matches[2];
- }
- else {
- $sizetarget = $rule['arg'];
- $sizeitem = $rule['item'];
- }
- }
- else {
- $test = ($rule['not'] ? 'not' : '').$rule['test'];
- $target = '';
- }
-
- $tout .= $select_op->show($test);
- $tout .= $this->list_input($id, 'rule_target', $target,
- $rule['test'] != 'size' && $rule['test'] != 'exists',
- $this->error_class($id, 'test', 'target', 'rule_target')) . "\n";
-
- $select_size_op = new html_select(array('name' => "_rule_size_op[]", 'id' => 'rule_size_op'.$id));
- $select_size_op->add(rcube::Q($this->gettext('filterover')), 'over');
- $select_size_op->add(rcube::Q($this->gettext('filterunder')), 'under');
-
- $tout .= '<div id="rule_size' .$id. '" style="display:' . ($rule['test']=='size' ? 'inline' : 'none') .'">';
- $tout .= $select_size_op->show($rule['test']=='size' ? $rule['type'] : '');
- $tout .= '<input type="text" name="_rule_size_target[]" id="rule_size_i'.$id.'" value="'.$sizetarget.'" size="10" '
- . $this->error_class($id, 'test', 'sizetarget', 'rule_size_i') .' />
- <label><input type="radio" name="_rule_size_item['.$id.']" value=""'
- . (!$sizeitem ? ' checked="checked"' : '') .' class="radio" />'.$this->rc->gettext('B').'</label>
- <label><input type="radio" name="_rule_size_item['.$id.']" value="K"'
- . ($sizeitem=='K' ? ' checked="checked"' : '') .' class="radio" />'.$this->rc->gettext('KB').'</label>
- <label><input type="radio" name="_rule_size_item['.$id.']" value="M"'
- . ($sizeitem=='M' ? ' checked="checked"' : '') .' class="radio" />'.$this->rc->gettext('MB').'</label>
- <label><input type="radio" name="_rule_size_item['.$id.']" value="G"'
- . ($sizeitem=='G' ? ' checked="checked"' : '') .' class="radio" />'.$this->rc->gettext('GB').'</label>';
- $tout .= '</div>';
-
- // Advanced modifiers (address, envelope)
- $select_mod = new html_select(array('name' => "_rule_mod[]", 'id' => 'rule_mod_op'.$id,
- 'onchange' => 'rule_mod_select(' .$id .')'));
- $select_mod->add(rcube::Q($this->gettext('none')), '');
- $select_mod->add(rcube::Q($this->gettext('address')), 'address');
- if (in_array('envelope', $this->exts))
- $select_mod->add(rcube::Q($this->gettext('envelope')), 'envelope');
-
- $select_type = new html_select(array('name' => "_rule_mod_type[]", 'id' => 'rule_mod_type'.$id));
- $select_type->add(rcube::Q($this->gettext('allparts')), 'all');
- $select_type->add(rcube::Q($this->gettext('domain')), 'domain');
- $select_type->add(rcube::Q($this->gettext('localpart')), 'localpart');
- if (in_array('subaddress', $this->exts)) {
- $select_type->add(rcube::Q($this->gettext('user')), 'user');
- $select_type->add(rcube::Q($this->gettext('detail')), 'detail');
- }
-
- $need_mod = $rule['test'] != 'size' && $rule['test'] != 'body';
- $mout = '<div id="rule_mod' .$id. '" class="adv" style="display:' . ($need_mod ? 'block' : 'none') .'">';
- $mout .= ' <span>';
- $mout .= rcube::Q($this->gettext('modifier')) . ' ';
- $mout .= $select_mod->show($rule['test']);
- $mout .= '</span>';
- $mout .= ' <span id="rule_mod_type' . $id . '"';
- $mout .= ' style="display:' . (in_array($rule['test'], array('address', 'envelope')) ? 'inline' : 'none') .'">';
- $mout .= rcube::Q($this->gettext('modtype')) . ' ';
- $mout .= $select_type->show($rule['part']);
- $mout .= '</span>';
- $mout .= '</div>';
-
- // Advanced modifiers (body transformations)
- $select_mod = new html_select(array('name' => "_rule_trans[]", 'id' => 'rule_trans_op'.$id,
- 'onchange' => 'rule_trans_select(' .$id .')'));
- $select_mod->add(rcube::Q($this->gettext('text')), 'text');
- $select_mod->add(rcube::Q($this->gettext('undecoded')), 'raw');
- $select_mod->add(rcube::Q($this->gettext('contenttype')), 'content');
-
- $mout .= '<div id="rule_trans' .$id. '" class="adv" style="display:' . ($rule['test'] == 'body' ? 'block' : 'none') .'">';
- $mout .= ' <span>';
- $mout .= rcube::Q($this->gettext('modifier')) . ' ';
- $mout .= $select_mod->show($rule['part']);
- $mout .= '<input type="text" name="_rule_trans_type[]" id="rule_trans_type'.$id
- . '" value="'.(is_array($rule['content']) ? implode(',', $rule['content']) : $rule['content'])
- .'" size="20" style="display:' . ($rule['part'] == 'content' ? 'inline' : 'none') .'"'
- . $this->error_class($id, 'test', 'part', 'rule_trans_type') .' />';
- $mout .= '</span>';
- $mout .= '</div>';
-
- // Advanced modifiers (body transformations)
- $select_comp = new html_select(array('name' => "_rule_comp[]", 'id' => 'rule_comp_op'.$id));
- $select_comp->add(rcube::Q($this->gettext('default')), '');
- $select_comp->add(rcube::Q($this->gettext('octet')), 'i;octet');
- $select_comp->add(rcube::Q($this->gettext('asciicasemap')), 'i;ascii-casemap');
- if (in_array('comparator-i;ascii-numeric', $this->exts)) {
- $select_comp->add(rcube::Q($this->gettext('asciinumeric')), 'i;ascii-numeric');
- }
-
- $mout .= '<div id="rule_comp' .$id. '" class="adv" style="display:' . ($rule['test'] != 'size' ? 'block' : 'none') .'">';
- $mout .= ' <span>';
- $mout .= rcube::Q($this->gettext('comparator')) . ' ';
- $mout .= $select_comp->show($rule['comparator']);
- $mout .= '</span>';
- $mout .= '</div>';
-
- // Build output table
- $out = $div ? '<div class="rulerow" id="rulerow' .$id .'">'."\n" : '';
- $out .= '<table><tr>';
- $out .= '<td class="advbutton">';
- $out .= '<a href="#" id="ruleadv' . $id .'" title="'. rcube::Q($this->gettext('advancedopts')). '"
- onclick="rule_adv_switch(' . $id .', this)" class="show">&nbsp;&nbsp;</a>';
- $out .= '</td>';
- $out .= '<td class="rowactions">' . $aout . '</td>';
- $out .= '<td class="rowtargets">' . $tout . "\n";
- $out .= '<div id="rule_advanced' .$id. '" style="display:none">' . $mout . '</div>';
- $out .= '</td>';
-
- // add/del buttons
- $out .= '<td class="rowbuttons">';
- $out .= '<a href="#" id="ruleadd' . $id .'" title="'. rcube::Q($this->gettext('add')). '"
- onclick="rcmail.managesieve_ruleadd(' . $id .')" class="button add"></a>';
- $out .= '<a href="#" id="ruledel' . $id .'" title="'. rcube::Q($this->gettext('del')). '"
- onclick="rcmail.managesieve_ruledel(' . $id .')" class="button del' . ($rows_num<2 ? ' disabled' : '') .'"></a>';
- $out .= '</td>';
- $out .= '</tr></table>';
-
- $out .= $div ? "</div>\n" : '';
-
- return $out;
- }
-
- function action_div($fid, $id, $div=true)
- {
- $action = isset($this->form) ? $this->form['actions'][$id] : $this->script[$fid]['actions'][$id];
- $rows_num = isset($this->form) ? sizeof($this->form['actions']) : sizeof($this->script[$fid]['actions']);
-
- $out = $div ? '<div class="actionrow" id="actionrow' .$id .'">'."\n" : '';
-
- $out .= '<table><tr><td class="rowactions">';
-
- // action select
- $select_action = new html_select(array('name' => "_action_type[$id]", 'id' => 'action_type'.$id,
- 'onchange' => 'action_type_select(' .$id .')'));
- if (in_array('fileinto', $this->exts))
- $select_action->add(rcube::Q($this->gettext('messagemoveto')), 'fileinto');
- if (in_array('fileinto', $this->exts) && in_array('copy', $this->exts))
- $select_action->add(rcube::Q($this->gettext('messagecopyto')), 'fileinto_copy');
- $select_action->add(rcube::Q($this->gettext('messageredirect')), 'redirect');
- if (in_array('copy', $this->exts))
- $select_action->add(rcube::Q($this->gettext('messagesendcopy')), 'redirect_copy');
- if (in_array('reject', $this->exts))
- $select_action->add(rcube::Q($this->gettext('messagediscard')), 'reject');
- else if (in_array('ereject', $this->exts))
- $select_action->add(rcube::Q($this->gettext('messagediscard')), 'ereject');
- if (in_array('vacation', $this->exts))
- $select_action->add(rcube::Q($this->gettext('messagereply')), 'vacation');
- $select_action->add(rcube::Q($this->gettext('messagedelete')), 'discard');
- if (in_array('imapflags', $this->exts) || in_array('imap4flags', $this->exts)) {
- $select_action->add(rcube::Q($this->gettext('setflags')), 'setflag');
- $select_action->add(rcube::Q($this->gettext('addflags')), 'addflag');
- $select_action->add(rcube::Q($this->gettext('removeflags')), 'removeflag');
- }
- if (in_array('variables', $this->exts)) {
- $select_action->add(rcube::Q($this->gettext('setvariable')), 'set');
- }
- if (in_array('enotify', $this->exts) || in_array('notify', $this->exts)) {
- $select_action->add(rcube::Q($this->gettext('notify')), 'notify');
- }
- $select_action->add(rcube::Q($this->gettext('rulestop')), 'stop');
-
- $select_type = $action['type'];
- if (in_array($action['type'], array('fileinto', 'redirect')) && $action['copy']) {
- $select_type .= '_copy';
- }
-
- $out .= $select_action->show($select_type);
- $out .= '</td>';
-
- // actions target inputs
- $out .= '<td class="rowtargets">';
- // shared targets
- $out .= '<input type="text" name="_action_target['.$id.']" id="action_target' .$id. '" '
- .'value="' .($action['type']=='redirect' ? rcube::Q($action['target'], 'strict', false) : ''). '" size="35" '
- .'style="display:' .($action['type']=='redirect' ? 'inline' : 'none') .'" '
- . $this->error_class($id, 'action', 'target', 'action_target') .' />';
- $out .= '<textarea name="_action_target_area['.$id.']" id="action_target_area' .$id. '" '
- .'rows="3" cols="35" '. $this->error_class($id, 'action', 'targetarea', 'action_target_area')
- .'style="display:' .(in_array($action['type'], array('reject', 'ereject')) ? 'inline' : 'none') .'">'
- . (in_array($action['type'], array('reject', 'ereject')) ? rcube::Q($action['target'], 'strict', false) : '')
- . "</textarea>\n";
-
- // vacation
- $vsec = in_array('vacation-seconds', $this->exts);
- $out .= '<div id="action_vacation' .$id.'" style="display:' .($action['type']=='vacation' ? 'inline' : 'none') .'">';
- $out .= '<span class="label">'. rcube::Q($this->gettext('vacationreason')) .'</span><br />'
- .'<textarea name="_action_reason['.$id.']" id="action_reason' .$id. '" '
- .'rows="3" cols="35" '. $this->error_class($id, 'action', 'reason', 'action_reason') . '>'
- . Q($action['reason'], 'strict', false) . "</textarea>\n";
- $out .= '<br /><span class="label">' .rcube::Q($this->gettext('vacationsubject')) . '</span><br />'
- .'<input type="text" name="_action_subject['.$id.']" id="action_subject'.$id.'" '
- .'value="' . (is_array($action['subject']) ? rcube::Q(implode(', ', $action['subject']), 'strict', false) : $action['subject']) . '" size="35" '
- . $this->error_class($id, 'action', 'subject', 'action_subject') .' />';
- $out .= '<br /><span class="label">' .rcube::Q($this->gettext('vacationaddr')) . '</span><br />'
- . $this->list_input($id, 'action_addresses', $action['addresses'], true,
- $this->error_class($id, 'action', 'addresses', 'action_addresses'), 30);
- $out .= '<br /><span class="label">' . rcube::Q($this->gettext($vsec ? 'vacationinterval' : 'vacationdays')) . '</span><br />'
- .'<input type="text" name="_action_interval['.$id.']" id="action_interval'.$id.'" '
- .'value="' .rcube::Q(isset($action['seconds']) ? $action['seconds'] : $action['days'], 'strict', false) . '" size="2" '
- . $this->error_class($id, 'action', 'interval', 'action_interval') .' />';
- if ($vsec) {
- $out .= '&nbsp;<label><input type="radio" name="_action_interval_type['.$id.']" value="days"'
- . (!isset($action['seconds']) ? ' checked="checked"' : '') .' class="radio" />'.$this->gettext('days').'</label>'
- . '&nbsp;<label><input type="radio" name="_action_interval_type['.$id.']" value="seconds"'
- . (isset($action['seconds']) ? ' checked="checked"' : '') .' class="radio" />'.$this->gettext('seconds').'</label>';
- }
- $out .= '</div>';
-
- // flags
- $flags = array(
- 'read' => '\\Seen',
- 'answered' => '\\Answered',
- 'flagged' => '\\Flagged',
- 'deleted' => '\\Deleted',
- 'draft' => '\\Draft',
- );
- $flags_target = (array)$action['target'];
-
- $out .= '<div id="action_flags' .$id.'" style="display:'
- . (preg_match('/^(set|add|remove)flag$/', $action['type']) ? 'inline' : 'none') . '"'
- . $this->error_class($id, 'action', 'flags', 'action_flags') . '>';
- foreach ($flags as $fidx => $flag) {
- $out .= '<input type="checkbox" name="_action_flags[' .$id .'][]" value="' . $flag . '"'
- . (in_array_nocase($flag, $flags_target) ? 'checked="checked"' : '') . ' />'
- . rcube::Q($this->gettext('flag'.$fidx)) .'<br>';
- }
- $out .= '</div>';
-
- // set variable
- $set_modifiers = array(
- 'lower',
- 'upper',
- 'lowerfirst',
- 'upperfirst',
- 'quotewildcard',
- 'length'
- );
-
- $out .= '<div id="action_set' .$id.'" style="display:' .($action['type']=='set' ? 'inline' : 'none') .'">';
- $out .= '<span class="label">' .rcube::Q($this->gettext('setvarname')) . '</span><br />'
- .'<input type="text" name="_action_varname['.$id.']" id="action_varname'.$id.'" '
- .'value="' . rcube::Q($action['name']) . '" size="35" '
- . $this->error_class($id, 'action', 'name', 'action_varname') .' />';
- $out .= '<br /><span class="label">' .rcube::Q($this->gettext('setvarvalue')) . '</span><br />'
- .'<input type="text" name="_action_varvalue['.$id.']" id="action_varvalue'.$id.'" '
- .'value="' . rcube::Q($action['value']) . '" size="35" '
- . $this->error_class($id, 'action', 'value', 'action_varvalue') .' />';
- $out .= '<br /><span class="label">' .rcube::Q($this->gettext('setvarmodifiers')) . '</span><br />';
- foreach ($set_modifiers as $s_m) {
- $s_m_id = 'action_varmods' . $id . $s_m;
- $out .= sprintf('<input type="checkbox" name="_action_varmods[%s][]" value="%s" id="%s"%s />%s<br>',
- $id, $s_m, $s_m_id,
- (array_key_exists($s_m, (array)$action) && $action[$s_m] ? ' checked="checked"' : ''),
- rcube::Q($this->gettext('var' . $s_m)));
- }
- $out .= '</div>';
-
- // notify
- // skip :options tag - not used by the mailto method
- $out .= '<div id="action_notify' .$id.'" style="display:' .($action['type']=='notify' ? 'inline' : 'none') .'">';
- $out .= '<span class="label">' .rcube::Q($this->gettext('notifyaddress')) . '</span><br />'
- .'<input type="text" name="_action_notifyaddress['.$id.']" id="action_notifyaddress'.$id.'" '
- .'value="' . rcube::Q($action['address']) . '" size="35" '
- . $this->error_class($id, 'action', 'address', 'action_notifyaddress') .' />';
- $out .= '<br /><span class="label">'. rcube::Q($this->gettext('notifybody')) .'</span><br />'
- .'<textarea name="_action_notifybody['.$id.']" id="action_notifybody' .$id. '" '
- .'rows="3" cols="35" '. $this->error_class($id, 'action', 'method', 'action_notifybody') . '>'
- . rcube::Q($action['body'], 'strict', false) . "</textarea>\n";
- $out .= '<br /><span class="label">' .rcube::Q($this->gettext('notifysubject')) . '</span><br />'
- .'<input type="text" name="_action_notifymessage['.$id.']" id="action_notifymessage'.$id.'" '
- .'value="' . rcube::Q($action['message']) . '" size="35" '
- . $this->error_class($id, 'action', 'message', 'action_notifymessage') .' />';
- $out .= '<br /><span class="label">' .rcube::Q($this->gettext('notifyfrom')) . '</span><br />'
- .'<input type="text" name="_action_notifyfrom['.$id.']" id="action_notifyfrom'.$id.'" '
- .'value="' . rcube::Q($action['from']) . '" size="35" '
- . $this->error_class($id, 'action', 'from', 'action_notifyfrom') .' />';
- $importance_options = array(
- 3 => 'notifyimportancelow',
- 2 => 'notifyimportancenormal',
- 1 => 'notifyimportancehigh'
- );
- $select_importance = new html_select(array(
- 'name' => '_action_notifyimportance[' . $id . ']',
- 'id' => '_action_notifyimportance' . $id,
- 'class' => $this->error_class($id, 'action', 'importance', 'action_notifyimportance')));
- foreach ($importance_options as $io_v => $io_n) {
- $select_importance->add(rcube::Q($this->gettext($io_n)), $io_v);
- }
- $out .= '<br /><span class="label">' . rcube::Q($this->gettext('notifyimportance')) . '</span><br />';
- $out .= $select_importance->show($action['importance'] ? $action['importance'] : 2);
- $out .= '</div>';
-
- // mailbox select
- if ($action['type'] == 'fileinto')
- $mailbox = $this->mod_mailbox($action['target'], 'out');
- else
- $mailbox = '';
-
- $select = $this->rc->folder_selector(array(
- 'realnames' => false,
- 'maxlength' => 100,
- 'id' => 'action_mailbox' . $id,
- 'name' => "_action_mailbox[$id]",
- 'style' => 'display:'.(!isset($action) || $action['type']=='fileinto' ? 'inline' : 'none')
- ));
- $out .= $select->show($mailbox);
- $out .= '</td>';
-
- // add/del buttons
- $out .= '<td class="rowbuttons">';
- $out .= '<a href="#" id="actionadd' . $id .'" title="'. rcube::Q($this->gettext('add')). '"
- onclick="rcmail.managesieve_actionadd(' . $id .')" class="button add"></a>';
- $out .= '<a href="#" id="actiondel' . $id .'" title="'. rcube::Q($this->gettext('del')). '"
- onclick="rcmail.managesieve_actiondel(' . $id .')" class="button del' . ($rows_num<2 ? ' disabled' : '') .'"></a>';
- $out .= '</td>';
-
- $out .= '</tr></table>';
-
- $out .= $div ? "</div>\n" : '';
-
- return $out;
- }
-
- private function genid()
- {
- return preg_replace('/[^0-9]/', '', microtime(true));
- }
-
- private function strip_value($str, $allow_html = false, $trim = true)
- {
- if (is_array($str)) {
- foreach ($str as $idx => $val) {
- $val = $this->strip_value($val, $allow_html, $trim);
-
- if ($val === '') {
- unset($str[$idx]);
- }
- }
-
- return $str;
- }
-
- if (!$allow_html) {
- $str = strip_tags($str);
- }
-
- return $trim ? trim($str) : $str;
- }
-
- private function error_class($id, $type, $target, $elem_prefix='')
- {
- // TODO: tooltips
- if (($type == 'test' && ($str = $this->errors['tests'][$id][$target])) ||
- ($type == 'action' && ($str = $this->errors['actions'][$id][$target]))
- ) {
- $this->add_tip($elem_prefix.$id, $str, true);
- return ' class="error"';
- }
-
- return '';
- }
-
- private function add_tip($id, $str, $error=false)
- {
- if ($error)
- $str = html::span('sieve error', $str);
-
- $this->tips[] = array($id, $str);
- }
-
- private function print_tips()
- {
- if (empty($this->tips))
- return;
-
- $script = rcmail_output::JS_OBJECT_NAME.'.managesieve_tip_register('.json_encode($this->tips).');';
- $this->rc->output->add_script($script, 'foot');
- }
-
- private function list_input($id, $name, $value, $enabled, $class, $size=null)
- {
- $value = (array) $value;
- $value = array_map(array('rcube', 'Q'), $value);
- $value = implode("\n", $value);
-
- return '<textarea data-type="list" name="_' . $name . '['.$id.']" id="' . $name.$id . '"'
- . ($enabled ? '' : ' disabled="disabled"')
- . ($size ? ' data-size="'.$size.'"' : '')
- . $class
- . ' style="display:none">' . $value . '</textarea>';
- }
-
- /**
- * Converts mailbox name from/to UTF7-IMAP from/to internal Sieve encoding
- * with delimiter replacement.
- *
- * @param string $mailbox Mailbox name
- * @param string $mode Conversion direction ('in'|'out')
- *
- * @return string Mailbox name
- */
- private function mod_mailbox($mailbox, $mode = 'out')
- {
- $delimiter = $_SESSION['imap_delimiter'];
- $replace_delimiter = $this->rc->config->get('managesieve_replace_delimiter');
- $mbox_encoding = $this->rc->config->get('managesieve_mbox_encoding', 'UTF7-IMAP');
-
- if ($mode == 'out') {
- $mailbox = rcube_charset::convert($mailbox, $mbox_encoding, 'UTF7-IMAP');
- if ($replace_delimiter && $replace_delimiter != $delimiter)
- $mailbox = str_replace($replace_delimiter, $delimiter, $mailbox);
- }
- else {
- $mailbox = rcube_charset::convert($mailbox, 'UTF7-IMAP', $mbox_encoding);
- if ($replace_delimiter && $replace_delimiter != $delimiter)
- $mailbox = str_replace($delimiter, $replace_delimiter, $mailbox);
- }
-
- return $mailbox;
- }
-
- /**
- * List sieve scripts
- *
- * @return array Scripts list
- */
- public function list_scripts()
- {
- if ($this->list !== null) {
- return $this->list;
- }
-
- $this->list = $this->sieve->get_scripts();
-
- // Handle active script(s) and list of scripts according to Kolab's KEP:14
- if ($this->rc->config->get('managesieve_kolab_master')) {
-
- // Skip protected names
- foreach ((array)$this->list as $idx => $name) {
- $_name = strtoupper($name);
- if ($_name == 'MASTER')
- $master_script = $name;
- else if ($_name == 'MANAGEMENT')
- $management_script = $name;
- else if($_name == 'USER')
- $user_script = $name;
- else
- continue;
-
- unset($this->list[$idx]);
- }
-
- // get active script(s), read USER script
- if ($user_script) {
- $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
- $filename_regex = '/'.preg_quote($extension, '/').'$/';
- $_SESSION['managesieve_user_script'] = $user_script;
-
- $this->sieve->load($user_script);
-
- foreach ($this->sieve->script->as_array() as $rules) {
- foreach ($rules['actions'] as $action) {
- if ($action['type'] == 'include' && empty($action['global'])) {
- $name = preg_replace($filename_regex, '', $action['target']);
- $this->active[] = $name;
- }
- }
- }
- }
- // create USER script if it doesn't exist
- else {
- $content = "# USER Management Script\n"
- ."#\n"
- ."# This script includes the various active sieve scripts\n"
- ."# it is AUTOMATICALLY GENERATED. DO NOT EDIT MANUALLY!\n"
- ."#\n"
- ."# For more information, see http://wiki.kolab.org/KEP:14#USER\n"
- ."#\n";
- if ($this->sieve->save_script('USER', $content)) {
- $_SESSION['managesieve_user_script'] = 'USER';
- if (empty($this->master_file))
- $this->sieve->activate('USER');
- }
- }
- }
- else if (!empty($this->list)) {
- // Get active script name
- if ($active = $this->sieve->get_active()) {
- $this->active = array($active);
- }
-
- // Hide scripts from config
- $exceptions = $this->rc->config->get('managesieve_filename_exceptions');
- if (!empty($exceptions)) {
- $this->list = array_diff($this->list, (array)$exceptions);
- }
- }
-
- return $this->list;
- }
-
- /**
- * Removes sieve script
- *
- * @param string $name Script name
- *
- * @return bool True on success, False on failure
- */
- public function remove_script($name)
- {
- $result = $this->sieve->remove($name);
-
- // Kolab's KEP:14
- if ($result && $this->rc->config->get('managesieve_kolab_master')) {
- $this->deactivate_script($name);
- }
-
- return $result;
- }
-
- /**
- * Activates sieve script
- *
- * @param string $name Script name
- *
- * @return bool True on success, False on failure
- */
- public function activate_script($name)
- {
- // Kolab's KEP:14
- if ($this->rc->config->get('managesieve_kolab_master')) {
- $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
- $user_script = $_SESSION['managesieve_user_script'];
-
- // if the script is not active...
- if ($user_script && array_search($name, $this->active) === false) {
- // ...rewrite USER file adding appropriate include command
- if ($this->sieve->load($user_script)) {
- $script = $this->sieve->script->as_array();
- $list = array();
- $regexp = '/' . preg_quote($extension, '/') . '$/';
-
- // Create new include entry
- $rule = array(
- 'actions' => array(
- 0 => array(
- 'target' => $name.$extension,
- 'type' => 'include',
- 'personal' => true,
- )));
-
- // get all active scripts for sorting
- foreach ($script as $rid => $rules) {
- foreach ($rules['actions'] as $action) {
- if ($action['type'] == 'include' && empty($action['global'])) {
- $target = $extension ? preg_replace($regexp, '', $action['target']) : $action['target'];
- $list[] = $target;
- }
- }
- }
- $list[] = $name;
-
- // Sort and find current script position
- asort($list, SORT_LOCALE_STRING);
- $list = array_values($list);
- $index = array_search($name, $list);
-
- // add rule at the end of the script
- if ($index === false || $index == count($list)-1) {
- $this->sieve->script->add_rule($rule);
- }
- // add rule at index position
- else {
- $script2 = array();
- foreach ($script as $rid => $rules) {
- if ($rid == $index) {
- $script2[] = $rule;
- }
- $script2[] = $rules;
- }
- $this->sieve->script->content = $script2;
- }
-
- $result = $this->sieve->save();
- if ($result) {
- $this->active[] = $name;
- }
- }
- }
- }
- else {
- $result = $this->sieve->activate($name);
- if ($result)
- $this->active = array($name);
- }
-
- return $result;
- }
-
- /**
- * Deactivates sieve script
- *
- * @param string $name Script name
- *
- * @return bool True on success, False on failure
- */
- public function deactivate_script($name)
- {
- // Kolab's KEP:14
- if ($this->rc->config->get('managesieve_kolab_master')) {
- $extension = $this->rc->config->get('managesieve_filename_extension', '.sieve');
- $user_script = $_SESSION['managesieve_user_script'];
-
- // if the script is active...
- if ($user_script && ($key = array_search($name, $this->active)) !== false) {
- // ...rewrite USER file removing appropriate include command
- if ($this->sieve->load($user_script)) {
- $script = $this->sieve->script->as_array();
- $name = $name.$extension;
-
- foreach ($script as $rid => $rules) {
- foreach ($rules['actions'] as $action) {
- if ($action['type'] == 'include' && empty($action['global'])
- && $action['target'] == $name
- ) {
- break 2;
- }
- }
- }
-
- // Entry found
- if ($rid < count($script)) {
- $this->sieve->script->delete_rule($rid);
- $result = $this->sieve->save();
- if ($result) {
- unset($this->active[$key]);
- }
- }
- }
- }
- }
- else {
- $result = $this->sieve->deactivate();
- if ($result)
- $this->active = array();
- }
-
- return $result;
+ $engine = $this->get_engine();
+ $engine->save();
}
/**
- * Saves current script (adding some variables)
+ * Initializes engine object
*/
- public function save_script($name = null)
+ private function get_engine()
{
- // Kolab's KEP:14
- if ($this->rc->config->get('managesieve_kolab_master')) {
- $this->sieve->script->set_var('EDITOR', self::PROGNAME);
- $this->sieve->script->set_var('EDITOR_VERSION', self::VERSION);
- }
+ if (!$this->engine) {
+ $this->load_config();
- return $this->sieve->save($name);
- }
+ // Add include path for internal classes
+ $include_path = $this->home . '/lib' . PATH_SEPARATOR;
+ $include_path .= ini_get('include_path');
+ set_include_path($include_path);
- /**
- * Returns list of rules from the current script
- *
- * @return array List of rules
- */
- public function list_rules()
- {
- $result = array();
- $i = 1;
-
- foreach ($this->script as $idx => $filter) {
- if ($filter['type'] != 'if') {
- continue;
- }
- $fname = $filter['name'] ? $filter['name'] : "#$i";
- $result[] = array(
- 'id' => $idx,
- 'name' => rcube::Q($fname),
- 'class' => $filter['disabled'] ? 'disabled' : '',
- );
- $i++;
+ $this->engine = new rcube_sieve_engine($this);
}
- return $result;
+ return $this->engine;
}
}
diff --git a/plugins/managesieve/package.xml b/plugins/managesieve/package.xml
index a0c38b82d..9c02957a5 100644
--- a/plugins/managesieve/package.xml
+++ b/plugins/managesieve/package.xml
@@ -26,7 +26,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
@@ -93,6 +93,7 @@
<file name="skins/classic/images/add.png" role="data"></file>
<file name="skins/classic/images/del.png" role="data"></file>
<file name="skins/classic/images/down_small.gif" role="data"></file>
+ <file name="skins/classic/images/erase.png" role="data"></file>
<file name="skins/classic/images/filter.png" role="data"></file>
<file name="skins/classic/images/up_small.gif" role="data"></file>
<file name="skins/larry/managesieve.css" role="data"></file>
@@ -103,10 +104,11 @@
<file name="skins/larry/images/add.png" role="data"></file>
<file name="skins/larry/images/del.png" role="data"></file>
<file name="skins/larry/images/down_small.gif" role="data"></file>
+ <file name="skins/larry/images/erase.png" role="data"></file>
<file name="skins/larry/images/up_small.gif" role="data"></file>
- <file name="managesieve.php" role="php"></file>
- <file name="lib/rcube_sieve.php" role="php"></file>
- <file name="lib/rcube_sieve_script.php" role="php"></file>
+ <file name="lib/Roundcube/rcube_sieve.php" role="php"></file>
+ <file name="lib/Roundcube/rcube_sieve_engine.php" role="php"></file>
+ <file name="lib/Roundcube/rcube_sieve_script.php" role="php"></file>
<file name="lib/Net/Sieve.php" role="php"></file>
<file name="config.inc.php.dist" role="data"></file>
</dir>
diff --git a/plugins/managesieve/skins/classic/managesieve.css b/plugins/managesieve/skins/classic/managesieve.css
index 1f112b956..59d88cb46 100644
--- a/plugins/managesieve/skins/classic/managesieve.css
+++ b/plugins/managesieve/skins/classic/managesieve.css
@@ -212,6 +212,13 @@ td.rowtargets div.adv
padding-top: 3px;
}
+td.rowtargets div.adv span.label
+{
+ display: inline-block;
+ padding-right: 10px;
+ min-width: 65px;
+}
+
html.mozilla #filter-form select
{
padding-top: 3px;
@@ -319,6 +326,7 @@ a.button.disabled
#filter-form textarea
{
font-size: 11px;
+ vertical-align: middle;
}
/* smart multi-row input field */
diff --git a/plugins/managesieve/skins/classic/templates/managesieve.html b/plugins/managesieve/skins/classic/templates/managesieve.html
index 71eebe105..869e3ac36 100644
--- a/plugins/managesieve/skins/classic/templates/managesieve.html
+++ b/plugins/managesieve/skins/classic/templates/managesieve.html
@@ -19,7 +19,7 @@
</style>
</head>
-<body onload="rcube_init_mail_ui()">
+<body>
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -83,5 +83,9 @@
</ul>
</div>
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
</html>
diff --git a/plugins/managesieve/skins/larry/managesieve.css b/plugins/managesieve/skins/larry/managesieve.css
index a618502d2..2144fe13f 100644
--- a/plugins/managesieve/skins/larry/managesieve.css
+++ b/plugins/managesieve/skins/larry/managesieve.css
@@ -43,7 +43,7 @@
#filtersetslist
{
width: 100%;
- table-layout: fixed;
+ table-layout: fixed;
}
#filterslist tbody td,
@@ -184,6 +184,14 @@ td.rowtargets > div
td.rowtargets div.adv
{
padding-top: 3px;
+ font-size: 10px;
+}
+
+td.rowtargets div.adv span.label
+{
+ display: inline-block;
+ padding-right: 5px;
+ min-width: 70px;
}
input.disabled, input.disabled:hover
@@ -297,6 +305,7 @@ a.button.disabled
{
font-size: 11px;
padding: 1px;
+ vertical-align: middle;
}
html.mozilla #filter-form select
diff --git a/plugins/markasjunk/localization/lv_LV.inc b/plugins/markasjunk/localization/lv_LV.inc
index f0ea921ba..5389ae399 100644
--- a/plugins/markasjunk/localization/lv_LV.inc
+++ b/plugins/markasjunk/localization/lv_LV.inc
@@ -17,8 +17,8 @@
*/
$labels = array();
-$labels['buttontext'] = 'Junk';
-$labels['buttontitle'] = 'IezÄ«mÄ“t kÄ mÄ“stuli';
-$labels['reportedasjunk'] = 'SekmÄ«gi iezÄ«mÄ“ta kÄ mÄ“stule';
+$labels['buttontext'] = 'MÄ“stules';
+$labels['buttontitle'] = 'AtzÄ«mÄ“t kÄ mÄ“stuli';
+$labels['reportedasjunk'] = 'SekmÄ«gi iatzÄ«mÄ“ta kÄ mÄ“stule';
?> \ No newline at end of file
diff --git a/plugins/new_user_dialog/localization/lv_LV.inc b/plugins/new_user_dialog/localization/lv_LV.inc
index 2e3642330..0447d995a 100644
--- a/plugins/new_user_dialog/localization/lv_LV.inc
+++ b/plugins/new_user_dialog/localization/lv_LV.inc
@@ -17,7 +17,7 @@
*/
$labels = array();
-$labels['identitydialogtitle'] = 'LÅ«dzu, aizpildiet nosÅ«tÄ«tÄja identifikÄcijas informÄciju';
-$labels['identitydialoghint'] = 'Å is logs parÄdÄ«sies tikai pirmajÄ pieteikÅ¡anÄs reizÄ“';
+$labels['identitydialogtitle'] = 'LÅ«dzu aizpildiet JÅ«su, kÄ sÅ«tÄ«tÄja, identitÄtes informÄciju';
+$labels['identitydialoghint'] = 'Å is logs parÄdÄ«sies tikai pirmajÄ autorizÄcijas reizÄ“.';
?> \ No newline at end of file
diff --git a/plugins/new_user_identity/new_user_identity.php b/plugins/new_user_identity/new_user_identity.php
index d32051e00..bb0821a53 100644
--- a/plugins/new_user_identity/new_user_identity.php
+++ b/plugins/new_user_identity/new_user_identity.php
@@ -8,6 +8,7 @@
*
* @version @package_version@
* @author Kris Steinhoff
+ * @license GNU GPLv3+
*
* Example configuration:
*
diff --git a/plugins/new_user_identity/package.xml b/plugins/new_user_identity/package.xml
index e50cd9255..45a3c4c8d 100644
--- a/plugins/new_user_identity/package.xml
+++ b/plugins/new_user_identity/package.xml
@@ -24,7 +24,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/newmail_notifier/localization/lv_LV.inc b/plugins/newmail_notifier/localization/lv_LV.inc
index 9df738b25..da9603cd5 100644
--- a/plugins/newmail_notifier/localization/lv_LV.inc
+++ b/plugins/newmail_notifier/localization/lv_LV.inc
@@ -16,14 +16,14 @@
For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/plugin-newmail_notifier/
*/
-$labels['basic'] = 'Attēlot paziņojumu pie jaunas vēstules saņemšanas';
-$labels['desktop'] = 'Attēlot darbvirsmas paziņojumu pie jaunas vēstules saņemšanas';
-$labels['sound'] = 'Atskaņot skaņas signÄlu pie jaunas vÄ“stules saņemÅ¡anas';
-$labels['test'] = 'Test';
-$labels['title'] = 'Jauns E-pasts!';
-$labels['body'] = 'Jūs esat saņēmis jaunu e-pastu.';
+$labels['basic'] = 'Saņemot jaunu vÄ“stuli, parÄdÄ«t paziņojumu';
+$labels['desktop'] = 'Saņemot jaunu vÄ“stuli, parÄdÄ«t darbavirsmas paziņojumu';
+$labels['sound'] = 'Saņemot jaunu vÄ“stuli, atskaņot skaņas signÄlu';
+$labels['test'] = 'PÄrbaudÄ«t';
+$labels['title'] = 'Jauns e-pasts!';
+$labels['body'] = 'Jūs esat saņēmis jaunu vēstuli.';
$labels['testbody'] = 'Šis ir testa paziņojums.';
-$labels['desktopdisabled'] = 'Darbvirsmas paziņojumi ir atslÄ“gti JÅ«su pÄrlÅ«kprogrammÄ.';
-$labels['desktopunsupported'] = 'JÅ«su pÄrlÅ«kprogramma neatbalsta darbvirsmas paziņojumus.';
+$labels['desktopdisabled'] = 'Darbavirsmas paziņojumi JÅ«su pÄrlÅ«kprogrammÄ ir atslÄ“gti.';
+$labels['desktopunsupported'] = 'JÅ«su pÄrlÅ«kprogramma neatbalsta darbavirsmas paziņojumus.';
?>
diff --git a/plugins/newmail_notifier/newmail_notifier.php b/plugins/newmail_notifier/newmail_notifier.php
index 61f7bdbaa..ca1c2ff67 100644
--- a/plugins/newmail_notifier/newmail_notifier.php
+++ b/plugins/newmail_notifier/newmail_notifier.php
@@ -15,18 +15,18 @@
*
* Copyright (C) 2011, Kolab Systems AG
*
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
*/
class newmail_notifier extends rcube_plugin
diff --git a/plugins/newmail_notifier/package.xml b/plugins/newmail_notifier/package.xml
index ea0fcd9c1..b8ef34933 100644
--- a/plugins/newmail_notifier/package.xml
+++ b/plugins/newmail_notifier/package.xml
@@ -28,7 +28,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/password/README b/plugins/password/README
index 73c4f39aa..af70156a6 100644
--- a/plugins/password/README
+++ b/plugins/password/README
@@ -1,26 +1,24 @@
-----------------------------------------------------------------------
Password Plugin for Roundcube
-----------------------------------------------------------------------
-
Plugin that adds a possibility to change user password using many
methods (drivers) via Settings/Password tab.
-
-----------------------------------------------------------------------
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2
- as published by the Free Software Foundation.
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see http://www.gnu.org/licenses/.
@version @package_version@
- @author Aleksander 'A.L.E.C' Machniak <alec@alec.pl>
+ @author Aleksander Machniak <alec@alec.pl>
@author <see driver files for driver authors>
-----------------------------------------------------------------------
diff --git a/plugins/password/localization/gl_ES.inc b/plugins/password/localization/gl_ES.inc
index 245d1c634..93c505a6a 100644
--- a/plugins/password/localization/gl_ES.inc
+++ b/plugins/password/localization/gl_ES.inc
@@ -26,7 +26,7 @@ $messages = array();
$messages['nopassword'] = 'Por favor, introduza un contrasinal novo.';
$messages['nocurpassword'] = 'Por favor, introduza o contrasinal actual.';
$messages['passwordincorrect'] = 'O contrasinal actual é incorrecto.';
-$messages['passwordinconsistency'] = 'Os contrasinals non coinciden. Por favor, inténteo de novo.';
+$messages['passwordinconsistency'] = 'Os contrasinais non cadran. Por favor, inténteo outra vez.';
$messages['crypterror'] = 'Non foi posible gardar o contrasinal novo. Falta a función de cifrado.';
$messages['connecterror'] = 'Non foi posible gardar o contrasinal novo. Erro de conexión';
$messages['internalerror'] = 'Non foi posible gardar o contrasinal novo.';
diff --git a/plugins/password/localization/lv_LV.inc b/plugins/password/localization/lv_LV.inc
index 650d31b2c..ac0e5da79 100644
--- a/plugins/password/localization/lv_LV.inc
+++ b/plugins/password/localization/lv_LV.inc
@@ -20,18 +20,18 @@ $labels = array();
$labels['changepasswd'] = 'Nomainīt paroli';
$labels['curpasswd'] = 'PaÅ¡reizÄ“jÄ parole:';
$labels['newpasswd'] = 'JaunÄ parole:';
-$labels['confpasswd'] = 'VÄ“lreiz jauno paroli:';
+$labels['confpasswd'] = 'ApstiprinÄt jauno paroli:';
$messages = array();
-$messages['nopassword'] = 'LÅ«dzu, ievadiet jauno paroli.';
-$messages['nocurpassword'] = 'Lūdzu, ievadiet pašreizējo paroli.';
-$messages['passwordincorrect'] = 'PaÅ¡reizÄ“jÄ parole nepareiza.';
+$messages['nopassword'] = 'LÅ«dzu ievadiet jauno paroli.';
+$messages['nocurpassword'] = 'Lūdzu ievadiet pašreizējo paroli.';
+$messages['passwordincorrect'] = 'PaÅ¡reizÄ“jÄ parole nav pareiza.';
$messages['passwordinconsistency'] = 'Paroles nesakrīt. Lūdzu, ievadiet vēlreiz.';
-$messages['crypterror'] = 'NevarÄ“ja saglabÄt jauno paroli. TrÅ«kst kriptÄ“Å¡anas funkcija.';
+$messages['crypterror'] = 'NevarÄ“ja saglabÄt jauno paroli. TrÅ«kst kriptÄ“Å¡anas funkcijas.';
$messages['connecterror'] = 'NevarÄ“ja saglabÄt jauno paroli. Savienojuma kļūda.';
$messages['internalerror'] = 'NevarÄ“ja saglabÄt jauno paroli.';
-$messages['passwordshort'] = 'Jaunajai parolei jÄbÅ«t vismaz $length simbola garai.';
-$messages['passwordweak'] = 'Jaunajai parolei jÄsatur vismaz viens cipars un punktuÄcijas simbols.';
-$messages['passwordforbidden'] = 'Password contains forbidden characters.';
+$messages['passwordshort'] = 'Jaunajai parolei jÄbÅ«t vismaz $length simbolu garai.';
+$messages['passwordweak'] = 'Jaunajai parolei jÄsatur vismaz viens cipars un speciÄlais simbols.';
+$messages['passwordforbidden'] = 'Parole satur neatļautus simbolus.';
?>
diff --git a/plugins/password/package.xml b/plugins/password/package.xml
index 81427a986..16eda1ad0 100644
--- a/plugins/password/package.xml
+++ b/plugins/password/package.xml
@@ -24,7 +24,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>
Added password_force_save option
</notes>
diff --git a/plugins/password/password.php b/plugins/password/password.php
index e16b4d0b9..f1a3e17b9 100644
--- a/plugins/password/password.php
+++ b/plugins/password/password.php
@@ -1,32 +1,26 @@
<?php
-/*
- +-------------------------------------------------------------------------+
- | Password Plugin for Roundcube |
- | @version @package_version@ |
- | |
- | Copyright (C) 2009-2010, Roundcube Dev. |
- | |
- | This program is free software; you can redistribute it and/or modify |
- | it under the terms of the GNU General Public License version 2 |
- | as published by the Free Software Foundation. |
- | |
- | This program is distributed in the hope that it will be useful, |
- | but WITHOUT ANY WARRANTY; without even the implied warranty of |
- | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
- | GNU General Public License for more details. |
- | |
- | You should have received a copy of the GNU General Public License along |
- | with this program; if not, write to the Free Software Foundation, Inc., |
- | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
- | |
- +-------------------------------------------------------------------------+
- | Author: Aleksander Machniak <alec@alec.pl> |
- +-------------------------------------------------------------------------+
-
- $Id: index.php 2645 2009-06-15 07:01:36Z alec $
-
-*/
+/**
+ * Password Plugin for Roundcube
+ *
+ * @version @package_version@
+ * @author Aleksander Machniak <alec@alec.pl>
+ *
+ * Copyright (C) 2005-2013, The Roundcube Dev Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see http://www.gnu.org/licenses/.
+ */
define('PASSWORD_CRYPT_ERROR', 1);
define('PASSWORD_ERROR', 2);
diff --git a/plugins/show_additional_headers/package.xml b/plugins/show_additional_headers/package.xml
index 7297916c3..9ca60baa9 100644
--- a/plugins/show_additional_headers/package.xml
+++ b/plugins/show_additional_headers/package.xml
@@ -24,7 +24,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/show_additional_headers/show_additional_headers.php b/plugins/show_additional_headers/show_additional_headers.php
index c18e6d4b5..c2b0ca1d3 100644
--- a/plugins/show_additional_headers/show_additional_headers.php
+++ b/plugins/show_additional_headers/show_additional_headers.php
@@ -11,7 +11,7 @@
*
* @version @package_version@
* @author Thomas Bruederli
- * @website http://roundcube.net
+ * @license GNU GPLv3+
*/
class show_additional_headers extends rcube_plugin
{
diff --git a/plugins/subscriptions_option/localization/gl_ES.inc b/plugins/subscriptions_option/localization/gl_ES.inc
index bbff10c3b..a273777da 100644
--- a/plugins/subscriptions_option/localization/gl_ES.inc
+++ b/plugins/subscriptions_option/localization/gl_ES.inc
@@ -17,6 +17,6 @@
*/
$labels = array();
-$labels['useimapsubscriptions'] = 'Usar suscripcións IMAP';
+$labels['useimapsubscriptions'] = 'Usar subscricións IMAP';
?>
diff --git a/plugins/subscriptions_option/package.xml b/plugins/subscriptions_option/package.xml
index 79d44f8c2..04f2c1b3c 100644
--- a/plugins/subscriptions_option/package.xml
+++ b/plugins/subscriptions_option/package.xml
@@ -32,7 +32,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/subscriptions_option/subscriptions_option.php b/plugins/subscriptions_option/subscriptions_option.php
index 70ca5602b..284c048df 100644
--- a/plugins/subscriptions_option/subscriptions_option.php
+++ b/plugins/subscriptions_option/subscriptions_option.php
@@ -21,6 +21,7 @@
*
* @version @package_version@
* @author Ziba Scott
+ * @license GNU GPLv3+
*/
class subscriptions_option extends rcube_plugin
{
diff --git a/plugins/vcard_attachments/localization/gl_ES.inc b/plugins/vcard_attachments/localization/gl_ES.inc
index b502c85c7..806f6bb7d 100644
--- a/plugins/vcard_attachments/localization/gl_ES.inc
+++ b/plugins/vcard_attachments/localization/gl_ES.inc
@@ -17,7 +17,7 @@
*/
$labels = array();
-$labels['addvcardmsg'] = 'Engadir a tarxeta ao caderno de enderezos';
-$labels['vcardsavefailed'] = 'Non foi posible gardar a tarxeta';
+$labels['addvcardmsg'] = 'Engadir vCard ao caderno de enderezos';
+$labels['vcardsavefailed'] = 'Non foi posible gardar a vCard';
?> \ No newline at end of file
diff --git a/plugins/virtuser_query/package.xml b/plugins/virtuser_query/package.xml
index b7ea565d8..9430bf69d 100644
--- a/plugins/virtuser_query/package.xml
+++ b/plugins/virtuser_query/package.xml
@@ -22,7 +22,7 @@
<release>stable</release>
<api>stable</api>
</stability>
- <license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
+ <license uri="http://www.gnu.org/licenses/gpl.html">GNU GPLv3+</license>
<notes>-</notes>
<contents>
<dir baseinstalldir="/" name="/">
diff --git a/plugins/virtuser_query/virtuser_query.php b/plugins/virtuser_query/virtuser_query.php
index 88001d452..04dcaf131 100644
--- a/plugins/virtuser_query/virtuser_query.php
+++ b/plugins/virtuser_query/virtuser_query.php
@@ -23,6 +23,7 @@
* @version @package_version@
* @author Aleksander Machniak <alec@alec.pl>
* @author Steffen Vogel
+ * @license GNU GPLv3+
*/
class virtuser_query extends rcube_plugin
{
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index fd625ba4d..d430cd350 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -162,7 +162,7 @@ class rcmail extends rcube
setlocale(LC_ALL, $lang . '.utf8', $lang . '.UTF-8', 'en_US.utf8', 'en_US.UTF-8');
// workaround for http://bugs.php.net/bug.php?id=18556
- if (in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
+ if (version_compare(PHP_VERSION, '5.5.0', '<') && in_array($lang, array('tr_TR', 'ku', 'az_AZ'))) {
setlocale(LC_CTYPE, 'en_US.utf8', 'en_US.UTF-8');
}
}
@@ -294,7 +294,7 @@ class rcmail extends rcube
$list[$id] = array(
'id' => $id,
'name' => html::quote($prop['name']),
- 'groups' => is_array($prop['groups']),
+ 'groups' => !empty($prop['groups']) || !empty($prop['group_filters']),
'readonly' => !$prop['writable'],
'hidden' => $prop['hidden'],
'autocomplete' => in_array($id, $autocomplete)
@@ -749,11 +749,6 @@ class rcmail extends rcube
$book->close();
}
- // before closing the database connection, write session data
- if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) {
- $this->session->write_close();
- }
-
// write performance stats to logs/console
if ($this->config->get('devel_mode')) {
if (function_exists('memory_get_usage'))
@@ -1765,7 +1760,8 @@ class rcmail extends rcube
public function upload_init()
{
// Enable upload progress bar
- if (($seconds = $this->config->get('upload_progress')) && ini_get('apc.rfc1867')) {
+ $rfc1867 = filter_var(ini_get('apc.rfc1867'), FILTER_VALIDATE_BOOLEAN);
+ if ($rfc1867 && ($seconds = $this->config->get('upload_progress'))) {
if ($field_name = ini_get('apc.rfc1867_name')) {
$this->output->set_env('upload_progress_name', $field_name);
$this->output->set_env('upload_progress_time', (int) $seconds);
diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php
index 29a86b9f7..c96a40ab9 100644
--- a/program/include/rcmail_output_html.php
+++ b/program/include/rcmail_output_html.php
@@ -72,7 +72,7 @@ class rcmail_output_html extends rcmail_output
// add cookie info
$this->set_env('cookie_domain', ini_get('session.cookie_domain'));
$this->set_env('cookie_path', ini_get('session.cookie_path'));
- $this->set_env('cookie_secure', ini_get('session.cookie_secure'));
+ $this->set_env('cookie_secure', filter_var(ini_get('session.cookie_secure'), FILTER_VALIDATE_BOOLEAN));
// load the correct skin (in case user-defined)
$skin = $this->config->get('skin');
@@ -106,7 +106,6 @@ class rcmail_output_html extends rcmail_output
));
}
-
/**
* Set environment variable
*
@@ -122,7 +121,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Getter for the current page title
*
@@ -146,17 +144,17 @@ class rcmail_output_html extends rcmail_output
return $title;
}
-
/**
* Set skin
*/
public function set_skin($skin)
{
$valid = false;
+ $path = RCUBE_INSTALL_PATH . 'skins/';
- if (!empty($skin) && is_dir('skins/'.$skin) && is_readable('skins/'.$skin)) {
- $skin_path = 'skins/'.$skin;
- $valid = true;
+ if (!empty($skin) && is_dir($path . $skin) && is_readable($path . $skin)) {
+ $skin_path = 'skins/' . $skin;
+ $valid = true;
}
else {
$skin_path = $this->config->get('skin_path');
@@ -184,13 +182,16 @@ class rcmail_output_html extends rcmail_output
$this->skin_paths[] = $skin_path;
// read meta file and check for dependecies
- $meta = @json_decode(@file_get_contents($skin_path.'/meta.json'), true);
- if ($meta['extends'] && is_dir('skins/' . $meta['extends'])) {
- $this->load_skin('skins/' . $meta['extends']);
+ $meta = @file_get_contents(RCUBE_INSTALL_PATH . $skin_path . '/meta.json');
+ $meta = @json_decode($meta, true);
+ if ($meta['extends']) {
+ $path = RCUBE_INSTALL_PATH . 'skins/';
+ if (is_dir($path . $meta['extends']) && is_readable($path . $meta['extends'])) {
+ $this->load_skin('skins/' . $meta['extends']);
+ }
}
}
-
/**
* Check if a specific template exists
*
@@ -199,16 +200,17 @@ class rcmail_output_html extends rcmail_output
*/
public function template_exists($name)
{
- $found = false;
foreach ($this->skin_paths as $skin_path) {
- $filename = $skin_path . '/templates/' . $name . '.html';
- $found = (is_file($filename) && is_readable($filename)) || ($this->deprecated_templates[$name] && $this->template_exists($this->deprecated_templates[$name]));
- if ($found)
- break;
+ $filename = RCUBE_INSTALL_PATH . $skin_path . '/templates/' . $name . '.html';
+ if ((is_file($filename) && is_readable($filename))
+ || ($this->deprecated_templates[$name] && $this->template_exists($this->deprecated_templates[$name]))
+ ) {
+ return true;
+ }
}
- return $found;
- }
+ return false;
+ }
/**
* Find the given file in the current skin path stack
@@ -234,7 +236,6 @@ class rcmail_output_html extends rcmail_output
return false;
}
-
/**
* Register a GUI object to the client script
*
@@ -247,7 +248,6 @@ class rcmail_output_html extends rcmail_output
$this->add_script(self::JS_OBJECT_NAME.".gui_object('$obj', '$id');");
}
-
/**
* Call a client method
*
@@ -263,7 +263,6 @@ class rcmail_output_html extends rcmail_output
$this->js_commands[] = $cmd;
}
-
/**
* Add a localized label to the client environment
*/
@@ -278,7 +277,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Invoke display_message command
*
@@ -305,7 +303,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Delete all stored env variables and commands
*
@@ -328,7 +325,6 @@ class rcmail_output_html extends rcmail_output
$this->body = '';
}
-
/**
* Redirect to a certain url
*
@@ -344,7 +340,6 @@ class rcmail_output_html extends rcmail_output
exit;
}
-
/**
* Send the request output to the client.
* This will either parse a skin tempalte or send an AJAX response
@@ -378,7 +373,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Process template and write to stdOut
*
@@ -414,7 +408,6 @@ class rcmail_output_html extends rcmail_output
$this->_write($template, $this->config->get('skin_path'));
}
-
/**
* Parse a specific skin template and deliver to stdout (or return)
*
@@ -539,7 +532,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Return executable javascript code for all registered commands
*
@@ -571,7 +563,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Make URLs starting with a slash point to skin directory
*
@@ -591,7 +582,6 @@ class rcmail_output_html extends rcmail_output
return $str;
}
-
/**
* Show error page and terminate script execution
*
@@ -626,7 +616,6 @@ class rcmail_output_html extends rcmail_output
array($this, 'globals_callback'), $input);
}
-
/**
* Callback funtion for preg_replace_callback() in parse_with_globals()
*/
@@ -635,7 +624,6 @@ class rcmail_output_html extends rcmail_output
return $GLOBALS[$matches[1]];
}
-
/**
* Correct absolute paths in images and other tags
* add timestamp to .js and .css filename
@@ -647,7 +635,6 @@ class rcmail_output_html extends rcmail_output
array($this, 'file_callback'), $output);
}
-
/**
* Callback function for preg_replace_callback in write()
*
@@ -673,7 +660,6 @@ class rcmail_output_html extends rcmail_output
return $matches[1] . '=' . $matches[2] . $file . $matches[4];
}
-
/**
* Public wrapper to dipp into template parsing.
*
@@ -690,7 +676,6 @@ class rcmail_output_html extends rcmail_output
return $input;
}
-
/**
* Parse for conditional tags
*
@@ -728,7 +713,6 @@ class rcmail_output_html extends rcmail_output
return $input;
}
-
/**
* Determines if a given condition is met
*
@@ -741,7 +725,6 @@ class rcmail_output_html extends rcmail_output
return $this->eval_expression($condition);
}
-
/**
* Inserts hidden field with CSRF-prevention-token into POST forms
*/
@@ -758,7 +741,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Parse & evaluate a given expression and return its result.
*
@@ -805,7 +787,6 @@ class rcmail_output_html extends rcmail_output
return $fn($this->app, $this->browser, $this->env);
}
-
/**
* Search for special tags in input and replace them
* with the appropriate content
@@ -820,7 +801,6 @@ class rcmail_output_html extends rcmail_output
return preg_replace_callback('/<roundcube:([-_a-z]+)\s+((?:[^>]|\\\\>)+)(?<!\\\\)>/Ui', array($this, 'xml_command'), $input);
}
-
/**
* Callback function for parsing an xml command tag
* and turn it into real html content
@@ -1029,7 +1009,6 @@ class rcmail_output_html extends rcmail_output
return '';
}
-
/**
* Include a specific file and return it's contents
*
@@ -1046,7 +1025,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Create and register a button
*
@@ -1202,7 +1180,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Link an external script file
*
@@ -1233,7 +1210,6 @@ class rcmail_output_html extends rcmail_output
$this->script_files[$position][] = $file;
}
-
/**
* Add inline javascript code
*
@@ -1250,7 +1226,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Link an external css file
*
@@ -1261,7 +1236,6 @@ class rcmail_output_html extends rcmail_output
$this->css_files[] = $file;
}
-
/**
* Add HTML code to the page header
*
@@ -1272,7 +1246,6 @@ class rcmail_output_html extends rcmail_output
$this->header .= "\n" . $str;
}
-
/**
* Add HTML code to the page footer
* To be added right befor </body>
@@ -1284,7 +1257,6 @@ class rcmail_output_html extends rcmail_output
$this->footer .= "\n" . $str;
}
-
/**
* Process template and write to stdOut
*
@@ -1409,7 +1381,6 @@ class rcmail_output_html extends rcmail_output
}
}
-
/**
* Returns iframe object, registers some related env variables
*
@@ -1440,7 +1411,6 @@ class rcmail_output_html extends rcmail_output
/* ************* common functions delivering gui objects ************** */
-
/**
* Create a form tag with the necessary hidden fields
*
@@ -1467,7 +1437,6 @@ class rcmail_output_html extends rcmail_output
array('id','class','style','name','method','action','enctype','onsubmit'));
}
-
/**
* Build a form tag with a unique request token
*
@@ -1498,7 +1467,6 @@ class rcmail_output_html extends rcmail_output
return $this->form_tag($attrib, $hidden->show() . $content);
}
-
/**
* GUI object 'username'
* Showing IMAP username of the current session
@@ -1530,7 +1498,6 @@ class rcmail_output_html extends rcmail_output
return rcube_utils::idn_to_utf8($username);
}
-
/**
* GUI object 'loginform'
* Returns code for the webmail login form
@@ -1630,7 +1597,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* GUI object 'preloader'
* Loads javascript code for images preloading
@@ -1653,7 +1619,6 @@ class rcmail_output_html extends rcmail_output
}', 'docready');
}
-
/**
* GUI object 'searchform'
* Returns code for search function
@@ -1692,7 +1657,6 @@ class rcmail_output_html extends rcmail_output
return $out;
}
-
/**
* Builder for GUI object 'message'
*
@@ -1710,7 +1674,6 @@ class rcmail_output_html extends rcmail_output
return html::div($attrib, '');
}
-
/**
* GUI object 'charsetselector'
*
diff --git a/program/js/app.js b/program/js/app.js
index 0dea59216..45a17d640 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -191,7 +191,7 @@ function rcube_webmail()
case 'mail':
// enable mail commands
- this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
+ this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', 'import-messages', true);
if (this.gui_objects.messagelist) {
this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {
@@ -229,7 +229,7 @@ function rcube_webmail()
this.set_button_titles();
this.env.message_commands = ['show', 'reply', 'reply-all', 'reply-list',
- 'moveto', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource',
+ 'move', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource',
'print', 'load-attachment', 'download-attachment', 'show-headers', 'hide-headers', 'download',
'forward', 'forward-inline', 'forward-attachment', 'change-format'];
@@ -255,7 +255,8 @@ function rcube_webmail()
}
}
else if (this.env.action == 'compose') {
- this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses', 'search', 'reset-search', 'extwin'];
+ this.env.address_group_stack = [];
+ this.env.compose_commands = ['send-attachment', 'remove-attachment', 'send', 'cancel', 'toggle-editor', 'list-adresses', 'pushgroup', 'search', 'reset-search', 'extwin'];
if (this.env.drafts_mailbox)
this.env.compose_commands.push('savedraft')
@@ -276,12 +277,15 @@ function rcube_webmail()
// init message compose form
this.init_messageform();
}
+ else if (this.env.action == 'get')
+ this.enable_command('download', 'print', true);
// show printing dialog
- else if (this.env.action == 'print' && this.env.uid)
+ else if (this.env.action == 'print' && this.env.uid) {
if (bw.safari)
setTimeout('window.print()', 10);
else
window.print();
+ }
// get unread count for each mailbox
if (this.gui_objects.mailboxlist) {
@@ -322,11 +326,13 @@ function rcube_webmail()
break;
case 'addressbook':
+ this.env.address_group_stack = [];
+
if (this.gui_objects.folderlist)
this.env.contactfolders = $.extend($.extend({}, this.env.address_sources), this.env.contactgroups);
this.enable_command('add', 'import', this.env.writable_source);
- this.enable_command('list', 'listgroup', 'listsearch', 'advanced-search', true);
+ this.enable_command('list', 'listgroup', 'pushgroup', 'popgroup', 'listsearch', 'advanced-search', true);
if (this.gui_objects.contactslist) {
this.contact_list = new rcube_list_widget(this.gui_objects.contactslist,
@@ -370,7 +376,7 @@ function rcube_webmail()
}
if (this.gui_objects.qsearchbox)
- this.enable_command('search', 'reset-search', 'moveto', true);
+ this.enable_command('search', 'reset-search', true);
break;
@@ -789,16 +795,18 @@ function rcube_webmail()
// mail task commands
case 'move':
- case 'moveto':
+ case 'moveto': // deprecated
if (this.task == 'mail')
this.move_messages(props);
else if (this.task == 'addressbook')
- this.copy_contact(null, props);
+ this.move_contacts(props);
break;
case 'copy':
if (this.task == 'mail')
this.copy_messages(props);
+ else if (this.task == 'addressbook')
+ this.copy_contacts(props);
break;
case 'mark':
@@ -860,7 +868,7 @@ function rcube_webmail()
// open attachment in frame if it's of a supported mimetype
if (command != 'download-attachment' && mimetype && this.env.mimetypes && $.inArray(mimetype, this.env.mimetypes) >= 0) {
- if (this.open_window(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', true, true))
+ if (this.open_window(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1'))
break;
}
@@ -1000,7 +1008,7 @@ function rcube_webmail()
// Reset the auto-save timer
clearTimeout(this.save_timer);
- this.upload_file(props || this.gui_objects.uploadform);
+ this.upload_file(props || this.gui_objects.uploadform, 'upload');
break;
case 'insert-sig':
@@ -1044,7 +1052,10 @@ function rcube_webmail()
break;
case 'print':
- if (uid = this.get_single_uid()) {
+ if (this.env.action == 'get') {
+ this.gui_objects.messagepartframe.contentWindow.print();
+ }
+ else if (uid = this.get_single_uid()) {
ref.printwin = this.open_window(this.env.comm_path+'&_action=print&_uid='+uid+'&_mbox='+urlencode(this.env.mailbox)+(this.env.safemode ? '&_safe=1' : ''), true, true);
if (this.printwin) {
if (this.env.action != 'show')
@@ -1059,7 +1070,10 @@ function rcube_webmail()
break;
case 'download':
- if (uid = this.get_single_uid())
+ if (this.env.action == 'get') {
+ location.href = location.href.replace(/_frame=/, '_download=');
+ }
+ else if (uid = this.get_single_uid())
this.goto_url('viewsource', { _uid: uid, _mbox: this.env.mailbox, _save: 1 });
break;
@@ -1096,11 +1110,31 @@ function rcube_webmail()
}
break;
+ case 'pushgroup':
+ // add group ID to stack
+ this.env.address_group_stack.push(props.id);
+ if (obj && event)
+ rcube_event.cancel(event);
+
case 'listgroup':
this.reset_qsearch();
this.list_contacts(props.source, props.id);
break;
+ case 'popgroup':
+ if (this.env.address_group_stack.length > 1) {
+ this.env.address_group_stack.pop();
+ this.reset_qsearch();
+ this.list_contacts(props.source, this.env.address_group_stack[this.env.address_group_stack.length-1]);
+ }
+ break;
+
+ case 'import-messages':
+ var form = props || this.gui_objects.importform;
+ $('input[name="_unlock"]', form).val(this.set_busy(true, 'importwait'));
+ this.upload_file(form, 'import');
+ break;
+
case 'import':
if (this.env.action == 'import' && this.gui_objects.importform) {
var file = document.getElementById('rcmimportfile');
@@ -1318,7 +1352,7 @@ function rcube_webmail()
this.drag_menu = function(e, target)
{
var modkey = rcube_event.get_modifier(e),
- menu = this.gui_objects.message_dragmenu;
+ menu = this.gui_objects.dragmenu;
if (menu && modkey == SHIFT_KEY && this.commands['copy']) {
var pos = rcube_event.get_mouse_pos(e);
@@ -1332,7 +1366,7 @@ function rcube_webmail()
this.drag_menu_action = function(action)
{
- var menu = this.gui_objects.message_dragmenu;
+ var menu = this.gui_objects.dragmenu;
if (menu) {
$(menu).hide();
}
@@ -1447,8 +1481,12 @@ function rcube_webmail()
list.draglayer.hide();
this.drag_end(e);
- if (!this.drag_menu(e, target))
- this.command('moveto', target);
+ if (this.contact_list) {
+ if (!this.contacts_drag_menu(e, target))
+ this.command('move', target);
+ }
+ else if (!this.drag_menu(e, target))
+ this.command('move', target);
}
// reset 'pressed' buttons
@@ -1495,7 +1533,7 @@ function rcube_webmail()
}
}
// Multi-message commands
- this.enable_command('delete', 'moveto', 'copy', 'mark', 'forward', 'forward-attachment', list.selection.length > 0);
+ this.enable_command('delete', 'move', 'copy', 'mark', 'forward', 'forward-attachment', list.selection.length > 0);
// reset all-pages-selection
if (selected || (list.selection.length && list.selection.length != list.rowcount))
@@ -1598,28 +1636,28 @@ function rcube_webmail()
this.check_droptarget = function(id)
{
- if (this.task == 'mail')
- return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual) ? 1 : 0;
+ switch (this.task) {
+ case 'mail':
+ return (this.env.mailboxes[id] && this.env.mailboxes[id].id != this.env.mailbox && !this.env.mailboxes[id].virtual) ? 1 : 0;
- if (this.task == 'settings')
- return id != this.env.mailbox ? 1 : 0;
+ case 'settings':
+ return id != this.env.mailbox ? 1 : 0;
- if (this.task == 'addressbook') {
- if (id != this.env.source && this.env.contactfolders[id]) {
- // droptarget is a group - contact add to group action
- if (this.env.contactfolders[id].type == 'group') {
- var target_abook = this.env.contactfolders[id].source;
- if (this.env.contactfolders[id].id != this.env.group && !this.env.contactfolders[target_abook].readonly) {
- // search result may contain contacts from many sources
- return (this.env.selection_sources.length > 1 || $.inArray(target_abook, this.env.selection_sources) == -1) ? 2 : 1;
+ case 'addressbook':
+ var target;
+ if (id != this.env.source && (target = this.env.contactfolders[id])) {
+ // droptarget is a group
+ if (target.type == 'group') {
+ if (target.id != this.env.group && !this.env.contactfolders[target.source].readonly) {
+ var is_other = this.env.selection_sources.length > 1 || $.inArray(target.source, this.env.selection_sources) == -1;
+ return !is_other || this.commands.move ? 1 : 2;
+ }
+ }
+ // droptarget is a (writable) addressbook and it's not the source
+ else if (!target.readonly && (this.env.selection_sources.length > 1 || $.inArray(id, this.env.selection_sources) == -1)) {
+ return this.commands.move ? 1 : 2;
}
}
- // droptarget is a (writable) addressbook - contact copy action
- else if (!this.env.contactfolders[id].readonly) {
- // search result may contain contacts from many sources
- return (this.env.selection_sources.length > 1 || $.inArray(id, this.env.selection_sources) == -1) ? 2 : 0;
- }
- }
}
return 0;
@@ -1976,14 +2014,18 @@ function rcube_webmail()
if (name && (frame = this.get_frame_element(name))) {
if (!show && (win = this.get_frame_window(name))) {
- if (win.location && win.location.href.indexOf(this.env.blankpage)<0)
- win.location.href = this.env.blankpage;
+ if (win.stop)
+ win.stop();
+ else // IE
+ win.document.execCommand('Stop');
+
+ win.location.href = this.env.blankpage;
}
else if (!bw.safari && !bw.konq)
$(frame)[show ? 'show' : 'hide']();
}
- if (!show && this.busy)
+ if (!show && this.env.frame_lock)
this.set_busy(false, null, this.env.frame_lock);
};
@@ -2111,12 +2153,12 @@ function rcube_webmail()
this.clear_message_list = function()
{
- this.env.messages = {};
- this.last_selected = 0;
+ this.env.messages = {};
+ this.last_selected = 0;
- this.show_contentframe(false);
- if (this.message_list)
- this.message_list.clear(true);
+ this.show_contentframe(false);
+ if (this.message_list)
+ this.message_list.clear(true);
};
// send remote request to load message list
@@ -2561,7 +2603,7 @@ function rcube_webmail()
// Hide message command buttons until a message is selected
this.enable_command(this.env.message_commands, false);
- this._with_selected_messages('moveto', post_data, lock);
+ this._with_selected_messages('move', post_data, lock);
};
// delete selected messages from the current mailbox
@@ -2620,7 +2662,7 @@ function rcube_webmail()
this._with_selected_messages('delete', post_data);
};
- // Send a specifc moveto/delete request with UIDs of all selected messages
+ // Send a specifc move/delete request with UIDs of all selected messages
// @private
this._with_selected_messages = function(action, post_data, lock)
{
@@ -2662,7 +2704,7 @@ function rcube_webmail()
this.delete_excessive_thread_rows();
if (!lock) {
- msg = action == 'moveto' ? 'movingmessage' : 'deletingmessage';
+ msg = action == 'move' ? 'movingmessage' : 'deletingmessage';
lock = this.display_message(this.get_label(msg), 'loading');
}
@@ -3023,7 +3065,7 @@ function rcube_webmail()
this.set_caret_pos(input_message, this.env.top_posting ? 0 : $(input_message).val().length);
// add signature according to selected identity
// if we have HTML editor, signature is added in callback
- if (input_from.prop('type') == 'select-one' && !this.env.opened_extwin) {
+ if (input_from.prop('type') == 'select-one') {
this.change_identity(input_from[0]);
}
}
@@ -3084,7 +3126,13 @@ function rcube_webmail()
this.compose_recipient_select = function(list)
{
- this.enable_command('add-recipient', list.selection.length > 0);
+ var id, n, recipients = 0;
+ for (n=0; n < list.selection.length; n++) {
+ id = list.selection[n];
+ if (this.env.contactdata[id])
+ recipients++;
+ }
+ this.enable_command('add-recipient', recipients);
};
this.compose_add_recipient = function(field)
@@ -3354,6 +3402,15 @@ function rcube_webmail()
if (!show_sig)
show_sig = this.env.show_sig;
+ // first function execution
+ if (!this.env.identities_initialized) {
+ this.env.identities_initialized = true;
+ if (this.env.show_sig_later)
+ this.env.show_sig = true;
+ if (this.env.opened_extwin)
+ return;
+ }
+
var i, rx, cursor_pos, p = -1,
id = obj.options[obj.selectedIndex].value,
input_message = $("[name='_message']"),
@@ -3492,8 +3549,8 @@ function rcube_webmail()
return true;
};
- // upload attachment file
- this.upload_file = function(form)
+ // upload (attachment) file
+ this.upload_file = function(form, action)
{
if (!form)
return false;
@@ -3520,7 +3577,7 @@ function rcube_webmail()
return;
}
- var frame_name = this.async_upload_form(form, 'upload', function(e) {
+ var frame_name = this.async_upload_form(form, action || 'upload', function(e) {
var d, content = '';
try {
if (this.contentDocument) {
@@ -4102,7 +4159,7 @@ function rcube_webmail()
if (this.preview_timer)
clearTimeout(this.preview_timer);
- var n, id, sid, ref = this, writable = false,
+ var n, id, sid, contact, ref = this, writable = false,
source = this.env.source ? this.env.address_sources[this.env.source] : null;
// we don't have dblclick handler here, so use 200 instead of this.dblclick_time
@@ -4112,34 +4169,45 @@ function rcube_webmail()
this.show_contentframe(false);
if (list.selection.length) {
+ list.draggable = false;
+
// no source = search result, we'll need to detect if any of
// selected contacts are in writable addressbook to enable edit/delete
// we'll also need to know sources used in selection for copy
// and group-addmember operations (drag&drop)
this.env.selection_sources = [];
- if (!source) {
- for (n in list.selection) {
+
+ if (source) {
+ this.env.selection_sources.push(this.env.source);
+ }
+
+ for (n in list.selection) {
+ contact = list.data[list.selection[n]];
+ if (!source) {
sid = String(list.selection[n]).replace(/^[^-]+-/, '');
if (sid && this.env.address_sources[sid]) {
- writable = writable || !this.env.address_sources[sid].readonly;
+ writable = writable || (!this.env.address_sources[sid].readonly && !contact.readonly);
this.env.selection_sources.push(sid);
}
}
- this.env.selection_sources = $.unique(this.env.selection_sources);
- }
- else {
- this.env.selection_sources.push(this.env.source);
- writable = !source.readonly;
+ else {
+ writable = writable || (!source.readonly && !contact.readonly);
+ }
+
+ if (contact._type != 'group')
+ list.draggable = true;
}
+
+ this.env.selection_sources = $.unique(this.env.selection_sources);
}
// if a group is currently selected, and there is at least one contact selected
// thend we can enable the group-remove-selected command
- this.enable_command('group-remove-selected', this.env.group && list.selection.length > 0);
+ this.enable_command('group-remove-selected', this.env.group && list.selection.length > 0 && writable);
this.enable_command('compose', this.env.group || list.selection.length > 0);
- this.enable_command('export-selected', list.selection.length > 0);
+ this.enable_command('export-selected', 'copy', list.selection.length > 0);
this.enable_command('edit', id && writable);
- this.enable_command('delete', list.selection.length && writable);
+ this.enable_command('delete', 'move', list.selection.length > 0 && writable);
return false;
};
@@ -4167,11 +4235,29 @@ function rcube_webmail()
else if (!this.env.search_request)
folder = group ? 'G'+src+group : src;
- this.select_folder(folder, '', true);
-
this.env.source = src;
this.env.group = group;
+ // truncate groups listing stack
+ var index = $.inArray(this.env.group, this.env.address_group_stack);
+ if (index < 0)
+ this.env.address_group_stack = [];
+ else
+ this.env.address_group_stack = this.env.address_group_stack.slice(0,index);
+
+ // make sure the current group is on top of the stack
+ if (this.env.group) {
+ this.env.address_group_stack.push(this.env.group);
+
+ // mark the first group on the stack as selected in the directory list
+ folder = 'G'+src+this.env.address_group_stack[0];
+ }
+ else if (this.gui_objects.addresslist_title) {
+ $(this.gui_objects.addresslist_title).html(this.get_label('contacts'));
+ }
+
+ this.select_folder(folder, '', true);
+
// load contacts remotely
if (this.gui_objects.contactslist) {
this.list_contacts_remote(src, group, page);
@@ -4226,16 +4312,38 @@ function rcube_webmail()
this.list_contacts_clear = function()
{
+ this.contact_list.data = {};
this.contact_list.clear(true);
this.show_contentframe(false);
- this.enable_command('delete', false);
+ this.enable_command('delete', 'move', 'copy', false);
this.enable_command('compose', this.env.group ? true : false);
};
+ this.set_group_prop = function(prop)
+ {
+ if (this.gui_objects.addresslist_title) {
+ var boxtitle = $(this.gui_objects.addresslist_title).html(''); // clear contents
+
+ // add link to pop back to parent group
+ if (this.env.address_group_stack.length > 1) {
+ $('<a href="#list">...</a>')
+ .addClass('poplink')
+ .appendTo(boxtitle)
+ .click(function(e){ return ref.command('popgroup','',this); });
+ boxtitle.append('&nbsp;&raquo;&nbsp;');
+ }
+
+ boxtitle.append($('<span>'+prop.name+'</span>'));
+ }
+
+ this.triggerEvent('groupupdate', prop);
+ };
+
// load contact record
this.load_contact = function(cid, action, framed)
{
- var win, url = {}, target = window;
+ var win, url = {}, target = window,
+ rec = this.contact_list ? this.contact_list.data[cid] : null;
if (win = this.get_frame_window(this.env.contentframe)) {
url._framed = 1;
@@ -4245,7 +4353,9 @@ function rcube_webmail()
// load dummy content, unselect selected row(s)
if (!cid)
this.contact_list.clear_selection();
- this.enable_command('delete', 'compose', 'export-selected', cid);
+
+ this.enable_command('compose', rec && rec.email);
+ this.enable_command('export-selected', rec && rec._type != 'group');
}
else if (framed)
return false;
@@ -4275,14 +4385,38 @@ function rcube_webmail()
this.http_post('group-'+what+'members', post_data, lock);
};
- // copy a contact to the specified target (group or directory)
- this.copy_contact = function(cid, to)
+ this.contacts_drag_menu = function(e, to)
+ {
+ var dest = to.type == 'group' ? to.source : to.id,
+ source = this.env.source;
+
+ if (!this.env.address_sources[dest] || this.env.address_sources[dest].readonly)
+ return true;
+
+ // search result may contain contacts from many sources, but if there is only one...
+ if (source == '' && this.env.selection_sources.length == 1)
+ source = this.env.selection_sources[0];
+
+ if (to.type == 'group' && dest == source) {
+ var cid = this.contact_list.get_selection().join(',');
+ this.group_member_change('add', cid, dest, to.id);
+ return true;
+ }
+ // move action is not possible, "redirect" to copy if menu wasn't requested
+ else if (!this.commands.move && rcube_event.get_modifier(e) != SHIFT_KEY) {
+ this.copy_contacts(to);
+ return true;
+ }
+
+ return this.drag_menu(e, to);
+ };
+
+ // copy contact(s) to the specified target (group or directory)
+ this.copy_contacts = function(to)
{
var n, dest = to.type == 'group' ? to.source : to.id,
source = this.env.source,
- group = this.env.group ? this.env.group : '';
-
- if (!cid)
+ group = this.env.group ? this.env.group : '',
cid = this.contact_list.get_selection().join(',');
if (!cid || !this.env.address_sources[dest] || this.env.address_sources[dest].readonly)
@@ -4295,13 +4429,12 @@ function rcube_webmail()
// tagret is a group
if (to.type == 'group') {
if (dest == source)
- this.group_member_change('add', cid, dest, to.id);
- else {
- var lock = this.display_message(this.get_label('copyingcontact'), 'loading'),
- post_data = {_cid: cid, _source: this.env.source, _to: dest, _togid: to.id, _gid: group};
+ return;
- this.http_post('copy', post_data, lock);
- }
+ var lock = this.display_message(this.get_label('copyingcontact'), 'loading'),
+ post_data = {_cid: cid, _source: this.env.source, _to: dest, _togid: to.id, _gid: group};
+
+ this.http_post('copy', post_data, lock);
}
// target is an addressbook
else if (to.id != source) {
@@ -4312,19 +4445,53 @@ function rcube_webmail()
}
};
+ // move contact(s) to the specified target (group or directory)
+ this.move_contacts = function(to)
+ {
+ var dest = to.type == 'group' ? to.source : to.id,
+ source = this.env.source,
+ group = this.env.group ? this.env.group : '';
+
+ if (!this.env.address_sources[dest] || this.env.address_sources[dest].readonly)
+ return;
+
+ // search result may contain contacts from many sources, but if there is only one...
+ if (source == '' && this.env.selection_sources.length == 1)
+ source = this.env.selection_sources[0];
+
+ if (to.type == 'group') {
+ if (dest == source)
+ return;
+
+ this._with_selected_contacts('move', {_to: dest, _togid: to.id});
+ }
+ // target is an addressbook
+ else if (to.id != source)
+ this._with_selected_contacts('move', {_to: to.id});
+ };
+
+ // delete contact(s)
this.delete_contacts = function()
{
- var selection = this.contact_list.get_selection(),
- undelete = this.env.source && this.env.address_sources[this.env.source].undelete;
+ var undelete = this.env.source && this.env.address_sources[this.env.source].undelete;
- // exit if no mailbox specified or if selection is empty
- if (!(selection.length || this.env.cid) || (!undelete && !confirm(this.get_label('deletecontactconfirm'))))
+ if (!undelete && !confirm(this.get_label('deletecontactconfirm')))
return;
- var id, n, a_cids = [],
- post_data = {_source: this.env.source, _from: (this.env.action ? this.env.action : '')},
- lock = this.display_message(this.get_label('contactdeleting'), 'loading');
+ return this._with_selected_contacts('delete');
+ };
+
+ this._with_selected_contacts = function(action, post_data)
+ {
+ var selection = this.contact_list ? this.contact_list.get_selection() : [];
+
+ // exit if no mailbox specified or if selection is empty
+ if (!selection.length && !this.env.cid)
+ return;
+ var n, a_cids = [],
+ label = action == 'delete' ? 'contactdeleting' : 'movingcontact',
+ lock = this.display_message(this.get_label(label), 'loading');
if (this.env.cid)
a_cids.push(this.env.cid);
else {
@@ -4339,6 +4506,11 @@ function rcube_webmail()
this.show_contentframe(false);
}
+ if (!post_data)
+ post_data = {};
+
+ post_data._source = this.env.source;
+ post_data._from = this.env.action;
post_data._cid = a_cids.join(',');
if (this.env.group)
@@ -4349,13 +4521,13 @@ function rcube_webmail()
post_data._search = this.env.search_request;
// send request to server
- this.http_post('delete', post_data, lock)
+ this.http_post(action, post_data, lock)
return true;
};
// update a contact record in the list
- this.update_contact_row = function(cid, cols_arr, newcid, source)
+ this.update_contact_row = function(cid, cols_arr, newcid, source, data)
{
var c, row, list = this.contact_list;
@@ -4369,10 +4541,11 @@ function rcube_webmail()
}
list.update_row(cid, cols_arr, newcid, true);
+ list.data[cid] = data;
};
// add row to contacts list
- this.add_contact_row = function(cid, cols, classes)
+ this.add_contact_row = function(cid, cols, classes, data)
{
if (!this.gui_objects.contactslist)
return false;
@@ -4394,6 +4567,8 @@ function rcube_webmail()
row.cols.push(col);
}
+ // store data in list member
+ list.data[cid] = data;
list.insert_row(row);
this.enable_command('export', list.rowcount > 0);
@@ -5811,7 +5986,7 @@ function rcube_webmail()
}
th.appendChild(tr);
thead.parentNode.replaceChild(th, thead);
- thead = th;
+ list.thead = thead = th;
}
for (n=0, len=this.env.coltypes.length; n<len; n++) {
@@ -6221,7 +6396,7 @@ function rcube_webmail()
this.enable_command('export-selected', false);
}
- case 'moveto':
+ case 'move':
if (this.env.action == 'show') {
// re-enable commands on move/delete error
this.enable_command(this.env.message_commands, true);
@@ -6262,6 +6437,7 @@ function rcube_webmail()
if ((response.action == 'list' || response.action == 'search') && this.message_list) {
this.msglist_select(this.message_list);
+ this.message_list.resize();
this.triggerEvent('listupdate', { folder:this.env.mailbox, rowcount:this.message_list.rowcount });
}
}
@@ -6272,6 +6448,7 @@ function rcube_webmail()
this.enable_command('search-create', this.env.source == '');
this.enable_command('search-delete', this.env.search_id);
this.update_group_commands();
+ this.contact_list.resize();
this.triggerEvent('listupdate', { folder:this.env.source, rowcount:this.contact_list.rowcount });
}
}
@@ -6436,7 +6613,7 @@ function rcube_webmail()
timeout: 0, // disable default timeout set in ajaxSetup()
data: formdata || multipart,
headers: {'X-Roundcube-Request': ref.env.request_token},
- beforeSend: function(xhr, s) { if (!formdata && xhr.sendAsBinary) xhr.send = xhr.sendAsBinary; },
+ xhr: function() { var xhr = jQuery.ajaxSettings.xhr(); if (!formdata && xhr.sendAsBinary) xhr.send = xhr.sendAsBinary; return xhr; },
success: function(data){ ref.http_response(data); },
error: function(o, status, err) { ref.http_error(o, status, err, null, 'attachment'); }
});
@@ -6476,7 +6653,7 @@ function rcube_webmail()
multipart += '; filename="' + (f.name_bin || file.name) + '"' + crlf;
multipart += 'Content-Length: ' + file.size + crlf;
multipart += 'Content-Type: ' + file.type + crlf + crlf;
- multipart += e.target.result + crlf;
+ multipart += reader.result + crlf;
multipart += dashdash + boundary + crlf;
if (j == last) // we're done, submit the data
diff --git a/program/js/editor.js b/program/js/editor.js
index 3782de869..e403d1f63 100644
--- a/program/js/editor.js
+++ b/program/js/editor.js
@@ -41,7 +41,7 @@ function rcmail_editor_init(config)
$.extend(conf, {
plugins: 'paste,tabfocus',
theme_advanced_buttons1: 'bold,italic,underline,strikethrough,justifyleft,justifycenter,justifyright,justifyfull,separator,outdent,indent,charmap,hr,link,unlink,code,forecolor',
- theme_advanced_buttons2: ',fontselect,fontsizeselect'
+ theme_advanced_buttons2: 'fontselect,fontsizeselect'
});
else { // mail compose
$.extend(conf, {
@@ -80,7 +80,7 @@ function rcmail_editor_callback()
if (rcmail.env.default_font)
$(tinyMCE.get(rcmail.env.composebody).getBody()).css('font-family', rcmail.env.default_font);
- if (elem && elem.type == 'select-one' && !rcmail.env.opened_extwin) {
+ if (elem && elem.type == 'select-one') {
rcmail.change_identity(elem);
// Focus previously focused element
if (fe && fe.id != rcmail.env.composebody) {
diff --git a/program/js/list.js b/program/js/list.js
index 8b8a7196e..f4bc42566 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -33,6 +33,7 @@ function rcube_list_widget(list, p)
this.tagname = this.list ? this.list.nodeName.toLowerCase() : 'table';
this.thead;
this.tbody;
+ this.fixed_header;
this.frame = null;
this.rows = [];
this.selection = [];
@@ -152,6 +153,14 @@ init_header: function()
if (this.thead) {
this.colcount = 0;
+ if (this.fixed_header) { // copy (modified) fixed header back to the actual table
+ $(this.list.tHead).replaceWith($(this.fixed_header).find('thead').clone());
+ $(this.list.tHead).find('tr td').attr('style', ''); // remove fixed widths
+ }
+ else if (!bw.ie7 && this.list.className.indexOf('fixedheader') >= 0) {
+ this.init_fixed_header();
+ }
+
var col, r, p = this;
// add events for list columns moving
if (this.column_movable && this.thead && this.thead.rows) {
@@ -166,6 +175,47 @@ init_header: function()
}
},
+init_fixed_header: function()
+{
+ var clone = $(this.list.tHead).clone();
+
+ if (!this.fixed_header) {
+ this.fixed_header = $('<table>')
+ .attr('class', this.list.className + ' fixedcopy')
+ .css({ position:'fixed' })
+ .append(clone)
+ .append('<tbody></tbody>');
+ $(this.list).before(this.fixed_header);
+
+ var me = this;
+ $(window).resize(function(){ me.resize() });
+ }
+ else {
+ $(this.fixed_header).find('thead').replaceWith(clone);
+ }
+
+ this.thead = clone.get(0);
+ this.resize();
+},
+
+resize: function()
+{
+ if (!this.fixed_header)
+ return;
+
+ var column_widths = [];
+
+ // get column widths from original thead
+ $(this.tbody).parent().find('thead tr td').each(function(index) {
+ column_widths[index] = $(this).width();
+ });
+
+ // apply fixed widths to fixed table header
+ $(this.thead).parent().width($(this.tbody).parent().width());
+ $(this.thead).find('tr td').each(function(index) {
+ $(this).css('width', column_widths[index]);
+ });
+},
/**
* Remove all list rows
@@ -494,6 +544,7 @@ collapse: function(row)
new_row = new_row.nextSibling;
}
+ this.resize();
this.triggerEvent('listupdate');
return false;
},
@@ -542,6 +593,7 @@ expand: function(row)
new_row = new_row.nextSibling;
}
+ this.resize();
this.triggerEvent('listupdate');
return false;
},
@@ -585,6 +637,7 @@ collapse_all: function(row)
new_row = new_row.nextSibling;
}
+ this.resize();
this.triggerEvent('listupdate');
return false;
},
@@ -623,6 +676,7 @@ expand_all: function(row)
new_row = new_row.nextSibling;
}
+ this.resize();
this.triggerEvent('listupdate');
return false;
},
@@ -1531,6 +1585,9 @@ column_replace: function(from, to)
else if (this.subject_col > from && to >= this.subject_col)
this.subject_col--;
+ if (this.fixed_header)
+ this.init_header();
+
this.triggerEvent('column_replace');
}
diff --git a/program/lib/Mail/mime.php b/program/lib/Mail/mime.php
index 69a032cb8..e079af7e9 100644
--- a/program/lib/Mail/mime.php
+++ b/program/lib/Mail/mime.php
@@ -48,7 +48,7 @@
* @author Aleksander Machniak <alec@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version Release: 1.8.7
+ * @version CVS: $Id$
* @link http://pear.php.net/package/Mail_mime
*
* This class is based on HTML Mime Mail class from
@@ -89,7 +89,7 @@ require_once 'Mail/mimePart.php';
* @author Sean Coates <sean@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version Release: 1.8.7
+ * @version Release: @package_version@
* @link http://pear.php.net/package/Mail_mime
*/
class Mail_mime
@@ -254,6 +254,7 @@ class Mail_mime
$this->_txtbody .= $cont;
}
}
+
return true;
}
@@ -347,7 +348,7 @@ class Mail_mime
}
if (!$content_id) {
- $content_id = md5(uniqid(time()));
+ $content_id = preg_replace('/[^0-9a-zA-Z]/', '', uniqid(time(), true));
}
$this->_html_images[] = array(
@@ -429,8 +430,7 @@ class Mail_mime
if (!strlen($filename)) {
$msg = "The supplied filename for the attachment can't be empty";
- $err = PEAR::raiseError($msg);
- return $err;
+ return $this->_raiseError($msg);
}
$this->_parts[] = array(
@@ -465,16 +465,13 @@ class Mail_mime
{
// Check state of file and raise an error properly
if (!file_exists($file_name)) {
- $err = PEAR::raiseError('File not found: ' . $file_name);
- return $err;
+ return $this->_raiseError('File not found: ' . $file_name);
}
if (!is_file($file_name)) {
- $err = PEAR::raiseError('Not a regular file: ' . $file_name);
- return $err;
+ return $this->_raiseError('Not a regular file: ' . $file_name);
}
if (!is_readable($file_name)) {
- $err = PEAR::raiseError('File is not readable: ' . $file_name);
- return $err;
+ return $this->_raiseError('File is not readable: ' . $file_name);
}
// Temporarily reset magic_quotes_runtime and read file contents
@@ -500,7 +497,7 @@ class Mail_mime
* @return object The text mimePart object
* @access private
*/
- function _addTextPart(&$obj, $text)
+ function &_addTextPart(&$obj = null, $text = '')
{
$params['content_type'] = 'text/plain';
$params['encoding'] = $this->_build_params['text_encoding'];
@@ -509,11 +506,11 @@ class Mail_mime
if (is_object($obj)) {
$ret = $obj->addSubpart($text, $params);
- return $ret;
} else {
$ret = new Mail_mimePart($text, $params);
- return $ret;
}
+
+ return $ret;
}
/**
@@ -526,7 +523,7 @@ class Mail_mime
* @return object The html mimePart object
* @access private
*/
- function _addHtmlPart(&$obj)
+ function &_addHtmlPart(&$obj = null)
{
$params['content_type'] = 'text/html';
$params['encoding'] = $this->_build_params['html_encoding'];
@@ -535,11 +532,11 @@ class Mail_mime
if (is_object($obj)) {
$ret = $obj->addSubpart($this->_htmlbody, $params);
- return $ret;
} else {
$ret = new Mail_mimePart($this->_htmlbody, $params);
- return $ret;
}
+
+ return $ret;
}
/**
@@ -550,9 +547,8 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
- function _addMixedPart()
+ function &_addMixedPart()
{
- $params = array();
$params['content_type'] = 'multipart/mixed';
$params['eol'] = $this->_build_params['eol'];
@@ -572,17 +568,18 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
- function _addAlternativePart(&$obj)
+ function &_addAlternativePart(&$obj = null)
{
$params['content_type'] = 'multipart/alternative';
$params['eol'] = $this->_build_params['eol'];
if (is_object($obj)) {
- return $obj->addSubpart('', $params);
+ $ret = $obj->addSubpart('', $params);
} else {
$ret = new Mail_mimePart('', $params);
- return $ret;
}
+
+ return $ret;
}
/**
@@ -596,17 +593,18 @@ class Mail_mime
* @return object The multipart/mixed mimePart object
* @access private
*/
- function _addRelatedPart(&$obj)
+ function &_addRelatedPart(&$obj = null)
{
$params['content_type'] = 'multipart/related';
$params['eol'] = $this->_build_params['eol'];
if (is_object($obj)) {
- return $obj->addSubpart('', $params);
+ $ret = $obj->addSubpart('', $params);
} else {
$ret = new Mail_mimePart('', $params);
- return $ret;
}
+
+ return $ret;
}
/**
@@ -619,7 +617,7 @@ class Mail_mime
* @return object The image mimePart object
* @access private
*/
- function _addHtmlImagePart(&$obj, $value)
+ function &_addHtmlImagePart(&$obj, $value)
{
$params['content_type'] = $value['c_type'];
$params['encoding'] = 'base64';
@@ -650,7 +648,7 @@ class Mail_mime
* @return object The image mimePart object
* @access private
*/
- function _addAttachmentPart(&$obj, $value)
+ function &_addAttachmentPart(&$obj, $value)
{
$params['eol'] = $this->_build_params['eol'];
$params['filename'] = $value['name'];
@@ -700,9 +698,9 @@ class Mail_mime
*
* @param string $separation The separation between these two parts.
* @param array $params The Build parameters passed to the
- * &get() function. See &get for more info.
+ * get() function. See get() for more info.
* @param array $headers The extra headers that should be passed
- * to the &headers() function.
+ * to the headers() method.
* See that function for more info.
* @param bool $overwrite Overwrite the existing headers with new.
*
@@ -722,9 +720,7 @@ class Mail_mime
return $body;
}
- $head = $this->txtHeaders($headers, $overwrite);
- $mail = $head . $separation . $body;
- return $mail;
+ return $this->txtHeaders($headers, $overwrite) . $separation . $body;
}
/**
@@ -732,7 +728,7 @@ class Mail_mime
* mail delivery method.
*
* @param array $params The Build parameters passed to the
- * &get() function. See &get for more info.
+ * get() method. See get() for more info.
*
* @return mixed The e-mail body or PEAR error object
* @access public
@@ -748,9 +744,9 @@ class Mail_mime
*
* @param string $filename Output file location
* @param array $params The Build parameters passed to the
- * &get() function. See &get for more info.
+ * get() method. See get() for more info.
* @param array $headers The extra headers that should be passed
- * to the &headers() function.
+ * to the headers() function.
* See that function for more info.
* @param bool $overwrite Overwrite the existing headers with new.
*
@@ -762,8 +758,7 @@ class Mail_mime
{
// Check state of file and raise an error properly
if (file_exists($filename) && !is_writable($filename)) {
- $err = PEAR::raiseError('File is not writable: ' . $filename);
- return $err;
+ return $this->_raiseError('File is not writable: ' . $filename);
}
// Temporarily reset magic_quotes_runtime and read file contents
@@ -772,15 +767,13 @@ class Mail_mime
}
if (!($fh = fopen($filename, 'ab'))) {
- $err = PEAR::raiseError('Unable to open file: ' . $filename);
- return $err;
+ return $this->_raiseError('Unable to open file: ' . $filename);
}
// Write message headers into file (skipping Content-* headers)
$head = $this->txtHeaders($headers, $overwrite, true);
if (fwrite($fh, $head) === false) {
- $err = PEAR::raiseError('Error writing to file: ' . $filename);
- return $err;
+ return $this->_raiseError('Error writing to file: ' . $filename);
}
fclose($fh);
@@ -797,10 +790,10 @@ class Mail_mime
/**
* Writes (appends) the complete e-mail body into file.
- *
+ *
* @param string $filename Output file location
* @param array $params The Build parameters passed to the
- * &get() function. See &get for more info.
+ * get() method. See get() for more info.
*
* @return mixed True or PEAR error object
* @access public
@@ -810,8 +803,7 @@ class Mail_mime
{
// Check state of file and raise an error properly
if (file_exists($filename) && !is_writable($filename)) {
- $err = PEAR::raiseError('File is not writable: ' . $filename);
- return $err;
+ return $this->_raiseError('File is not writable: ' . $filename);
}
// Temporarily reset magic_quotes_runtime and read file contents
@@ -820,8 +812,7 @@ class Mail_mime
}
if (!($fh = fopen($filename, 'ab'))) {
- $err = PEAR::raiseError('Unable to open file: ' . $filename);
- return $err;
+ return $this->_raiseError('Unable to open file: ' . $filename);
}
// Write the rest of the message into file
@@ -844,7 +835,7 @@ class Mail_mime
* @return mixed The MIME message content string, null or PEAR error object
* @access public
*/
- function &get($params = null, $filename = null, $skip_head = false)
+ function get($params = null, $filename = null, $skip_head = false)
{
if (isset($params)) {
while (list($key, $value) = each($params)) {
@@ -1004,8 +995,7 @@ class Mail_mime
}
if (!isset($message)) {
- $ret = null;
- return $ret;
+ return null;
}
// Use saved boundary
@@ -1023,16 +1013,14 @@ class Mail_mime
return $headers;
}
$this->_headers = array_merge($this->_headers, $headers);
- $ret = null;
- return $ret;
+ return null;
} else {
$output = $message->encode($boundary, $skip_head);
if ($this->_isError($output)) {
return $output;
}
$this->_headers = array_merge($this->_headers, $output['headers']);
- $body = $output['body'];
- return $body;
+ return $output['body'];
}
}
@@ -1050,7 +1038,7 @@ class Mail_mime
* @return array Assoc array with the mime headers
* @access public
*/
- function &headers($xtra_headers = null, $overwrite = false, $skip_content = false)
+ function headers($xtra_headers = null, $overwrite = false, $skip_content = false)
{
// Add mime version header
$headers['MIME-Version'] = '1.0';
@@ -1473,7 +1461,7 @@ class Mail_mime
}
/**
- * PEAR::isError wrapper
+ * PEAR::isError implementation
*
* @param mixed $data Object
*
@@ -1490,4 +1478,18 @@ class Mail_mime
return false;
}
+ /**
+ * PEAR::raiseError implementation
+ *
+ * @param $message A text error message
+ *
+ * @return PEAR_Error Instance of PEAR_Error
+ * @access private
+ */
+ function _raiseError($message)
+ {
+ // PEAR::raiseError() is not PHP 5.4 compatible
+ return new PEAR_Error($message);
+ }
+
} // End of class
diff --git a/program/lib/Mail/mimePart.php b/program/lib/Mail/mimePart.php
index f3e75dd10..c6e9f4aa8 100644
--- a/program/lib/Mail/mimePart.php
+++ b/program/lib/Mail/mimePart.php
@@ -48,7 +48,7 @@
* @author Aleksander Machniak <alec@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version Release: 1.8.7
+ * @version CVS: $Id$
* @link http://pear.php.net/package/Mail_mime
*/
@@ -70,7 +70,7 @@
* @author Aleksander Machniak <alec@php.net>
* @copyright 2003-2006 PEAR <pear-group@php.net>
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
- * @version Release: 1.8.7
+ * @version Release: @package_version@
* @link http://pear.php.net/package/Mail_mime
*/
class Mail_mimePart
@@ -368,12 +368,12 @@ class Mail_mimePart
function encodeToFile($filename, $boundary=null, $skip_head=false)
{
if (file_exists($filename) && !is_writable($filename)) {
- $err = PEAR::raiseError('File is not writeable: ' . $filename);
+ $err = $this->_raiseError('File is not writeable: ' . $filename);
return $err;
}
if (!($fh = fopen($filename, 'ab'))) {
- $err = PEAR::raiseError('Unable to open file: ' . $filename);
+ $err = $this->_raiseError('Unable to open file: ' . $filename);
return $err;
}
@@ -456,7 +456,7 @@ class Mail_mimePart
* @param array $params The parameters for the subpart, same
* as the $params argument for constructor.
*
- * @return Mail_mimePart A reference to the part you just added. It is
+ * @return Mail_mimePart A reference to the part you just added. In PHP4, it is
* crucial if using multipart/* in your subparts that
* you use =& in your script when calling this function,
* otherwise you will not be able to add further subparts.
@@ -464,8 +464,8 @@ class Mail_mimePart
*/
function &addSubpart($body, $params)
{
- $this->_subparts[] = new Mail_mimePart($body, $params);
- return $this->_subparts[count($this->_subparts) - 1];
+ $this->_subparts[] = $part = new Mail_mimePart($body, $params);
+ return $part;
}
/**
@@ -511,12 +511,12 @@ class Mail_mimePart
function _getEncodedDataFromFile($filename, $encoding, $fh=null)
{
if (!is_readable($filename)) {
- $err = PEAR::raiseError('Unable to read file: ' . $filename);
+ $err = $this->_raiseError('Unable to read file: ' . $filename);
return $err;
}
if (!($fd = fopen($filename, 'rb'))) {
- $err = PEAR::raiseError('Could not open file: ' . $filename);
+ $err = $this->_raiseError('Could not open file: ' . $filename);
return $err;
}
@@ -648,7 +648,7 @@ class Mail_mimePart
}
/**
- * Encodes the paramater of a header.
+ * Encodes the parameter of a header.
*
* @param string $name The name of the header-parameter
* @param string $value The value of the paramter
@@ -1013,7 +1013,7 @@ class Mail_mimePart
$value = substr($value, $cutpoint);
$cutpoint = $maxLength;
// RFC 2047 specifies that any split header should
- // be seperated by a CRLF SPACE.
+ // be separated by a CRLF SPACE.
if ($output) {
$output .= $eol . ' ';
}
@@ -1055,7 +1055,7 @@ class Mail_mimePart
}
// RFC 2047 specifies that any split header should
- // be seperated by a CRLF SPACE
+ // be separated by a CRLF SPACE
if ($output) {
$output .= $eol . ' ';
}
@@ -1227,7 +1227,7 @@ class Mail_mimePart
}
/**
- * PEAR::isError wrapper
+ * PEAR::isError implementation
*
* @param mixed $data Object
*
@@ -1244,4 +1244,18 @@ class Mail_mimePart
return false;
}
+ /**
+ * PEAR::raiseError implementation
+ *
+ * @param $message A text error message
+ *
+ * @return PEAR_Error Instance of PEAR_Error
+ * @access private
+ */
+ function _raiseError($message)
+ {
+ // PEAR::raiseError() is not PHP 5.4 compatible
+ return new PEAR_Error($message);
+ }
+
} // End of class
diff --git a/program/lib/Roundcube/bootstrap.php b/program/lib/Roundcube/bootstrap.php
index 5a371d2f0..182ea1232 100644
--- a/program/lib/Roundcube/bootstrap.php
+++ b/program/lib/Roundcube/bootstrap.php
@@ -39,13 +39,13 @@ $config = array(
if (php_sapi_name() != 'cli') {
$config += array(
'suhosin.session.encrypt' => 0,
- 'session.auto_start' => 0,
'file_uploads' => 1,
);
}
foreach ($config as $optname => $optval) {
- if ($optval != ini_get($optname) && @ini_set($optname, $optval) === false) {
+ $ini_optval = filter_var(ini_get($optname), FILTER_VALIDATE_BOOLEAN);
+ if ($optval != $ini_optval && @ini_set($optname, $optval) === false) {
$error = "ERROR: Wrong '$optname' option value and it wasn't possible to set it to required value ($optval).\n"
. "Check your PHP configuration (including php_admin_flag).";
if (defined('STDERR')) fwrite(STDERR, $error); else echo $error;
diff --git a/program/lib/Roundcube/html.php b/program/lib/Roundcube/html.php
index eb23c8b2e..3e6e47a56 100644
--- a/program/lib/Roundcube/html.php
+++ b/program/lib/Roundcube/html.php
@@ -360,8 +360,8 @@ class html_inputfield extends html
protected $allowed = array(
'type','name','value','size','tabindex','autocapitalize',
'autocomplete','checked','onchange','onclick','disabled','readonly',
- 'spellcheck','results','maxlength','src','multiple','placeholder',
- 'autofocus',
+ 'spellcheck','results','maxlength','src','multiple','accept',
+ 'placeholder','autofocus',
);
/**
diff --git a/program/lib/Roundcube/rcube.php b/program/lib/Roundcube/rcube.php
index 8d17827be..05a94f3be 100644
--- a/program/lib/Roundcube/rcube.php
+++ b/program/lib/Roundcube/rcube.php
@@ -99,7 +99,6 @@ class rcube
protected $texts;
protected $caches = array();
protected $shutdown_functions = array();
- protected $expunge_cache = false;
/**
@@ -378,6 +377,7 @@ class rcube
'auth_pw' => $this->config->get("{$driver}_auth_pw"),
'debug' => (bool) $this->config->get("{$driver}_debug"),
'force_caps' => (bool) $this->config->get("{$driver}_force_caps"),
+ 'disabled_caps' => $this->config->get("{$driver}_disabled_caps"),
'timeout' => (int) $this->config->get("{$driver}_timeout"),
'skip_deleted' => (bool) $this->config->get('skip_deleted'),
'driver' => $driver,
@@ -462,7 +462,7 @@ class rcube
// use database for storing session data
$this->session = new rcube_session($this->get_dbh(), $this->config);
- $this->session->register_gc_handler(array($this, 'gc_handler'));
+ $this->session->register_gc_handler(array($this, 'gc'));
$this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME']));
$this->session->set_ip_check($this->config->get('ip_check'));
@@ -512,18 +512,6 @@ class rcube
/**
- * Garbage collector for cache entries.
- * Set flag to expunge caches on shutdown
- */
- public function gc_handler()
- {
- // because this gc function is called before storage is initialized,
- // we just set a flag to expunge storage cache on shutdown.
- $this->expunge_cache = true;
- }
-
-
- /**
* Runs garbage collector with probability based on
* session settings. This is intended for environments
* without a session.
@@ -922,12 +910,16 @@ class rcube
call_user_func($function);
}
- if (is_object($this->smtp)) {
- $this->smtp->disconnect();
+ // write session data as soon as possible and before
+ // closing database connection, don't do this before
+ // registered shutdown functions, they may need the session
+ // Note: this will run registered gc handlers (ie. cache gc)
+ if ($_SERVER['REMOTE_ADDR'] && is_object($this->session)) {
+ $this->session->write_close();
}
- if ($this->expunge_cache) {
- $this->gc();
+ if (is_object($this->smtp)) {
+ $this->smtp->disconnect();
}
foreach ($this->caches as $cache) {
@@ -1496,7 +1488,7 @@ class rcube
$subject = str_replace("\r\n", $delim, $subject);
}
- if (ini_get('safe_mode'))
+ if (filter_var(ini_get('safe_mode'), FILTER_VALIDATE_BOOLEAN))
$sent = mail($to, $subject, $msg_body, $header_str);
else
$sent = mail($to, $subject, $msg_body, $header_str, "-f$from");
diff --git a/program/lib/Roundcube/rcube_addressbook.php b/program/lib/Roundcube/rcube_addressbook.php
index d23ad3687..4ed139c45 100644
--- a/program/lib/Roundcube/rcube_addressbook.php
+++ b/program/lib/Roundcube/rcube_addressbook.php
@@ -539,10 +539,10 @@ abstract class rcube_addressbook
// add email to a key to not skip contacts with the same name (#1488375)
if (!empty($contact['email'])) {
- $key .= ':' . implode(':', (array)$contact['email']);
- }
+ $key .= ':' . implode(':', (array)$contact['email']);
+ }
- return $key;
+ return $key;
}
/**
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 3ca8a07c9..b60aefc5f 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -1189,11 +1189,13 @@ class rcube_imap extends rcube_storage
* @param string $sort_field Sort column
* @param string $sort_order Sort order [ASC, DESC]
* @param bool $no_threads Get not threaded index
+ * @param bool $no_search Get index not limited to search result (optionally)
*
* @return rcube_result_index|rcube_result_thread List of messages (UIDs)
*/
- public function index($folder = '', $sort_field = NULL, $sort_order = NULL, $no_threads = false)
- {
+ public function index($folder = '', $sort_field = NULL, $sort_order = NULL,
+ $no_threads = false, $no_search = false
+ ) {
if (!$no_threads && $this->threading) {
return $this->thread_index($folder, $sort_field, $sort_order);
}
@@ -1206,43 +1208,50 @@ class rcube_imap extends rcube_storage
// we have a saved search result, get index from there
if ($this->search_string) {
- if ($this->search_threads) {
- $this->search($folder, $this->search_string, $this->search_charset, $this->sort_field);
+ if ($this->search_set->is_empty()) {
+ return new rcube_result_index($folder, '* SORT');
}
- // use message index sort as default sorting
- if (!$this->sort_field || $this->search_sorted) {
- if ($this->sort_field && $this->search_sort_field != $this->sort_field) {
- $this->search($folder, $this->search_string, $this->search_charset, $this->sort_field);
- }
+ // search result is an index with the same sorting?
+ if (($this->search_set instanceof rcube_result_index)
+ && ((!$this->sort_field && !$this->search_sorted) ||
+ ($this->search_sorted && $this->search_sort_field == $this->sort_field))
+ ) {
$index = $this->search_set;
}
- else if (!$this->check_connection()) {
- return new rcube_result_index();
- }
- else {
- $index = $this->conn->index($folder, $this->search_set->get(),
- $this->sort_field, $this->options['skip_deleted'], true, true);
+ // $no_search is enabled when we are not interested in
+ // fetching index for search result, e.g. to sort
+ // threaded search result we can use full mailbox index.
+ // This makes possible to use index from cache
+ else if (!$no_search) {
+ if (!$this->sort_field) {
+ // No sorting needed, just build index from the search result
+ // @TODO: do we need to sort by UID here?
+ $search = $this->search_set->get_compressed();
+ $index = new rcube_result_index($folder, '* ESEARCH ALL ' . $search);
+ }
+ else {
+ $index = $this->index_direct($folder, $this->search_charset,
+ $this->sort_field, $this->search_set);
+ }
}
- if ($this->sort_order != $index->get_parameters('ORDER')) {
- $index->revert();
- }
+ if (isset($index)) {
+ if ($this->sort_order != $index->get_parameters('ORDER')) {
+ $index->revert();
+ }
- return $index;
+ return $index;
+ }
}
// check local cache
if ($mcache = $this->get_mcache_engine()) {
- $index = $mcache->get_index($folder, $this->sort_field, $this->sort_order);
- }
- // fetch from IMAP server
- else {
- $index = $this->index_direct(
- $folder, $this->sort_field, $this->sort_order);
+ return $mcache->get_index($folder, $this->sort_field, $this->sort_order);
}
- return $index;
+ // fetch from IMAP server
+ return $this->index_direct($folder, $this->sort_field, $this->sort_order);
}
@@ -1250,18 +1259,24 @@ class rcube_imap extends rcube_storage
* Return sorted list of message UIDs ignoring current search settings.
* Doesn't uses cache by default.
*
- * @param string $folder Folder to get index from
- * @param string $sort_field Sort column
- * @param string $sort_order Sort order [ASC, DESC]
+ * @param string $folder Folder to get index from
+ * @param string $sort_field Sort column
+ * @param string $sort_order Sort order [ASC, DESC]
+ * @param rcube_result_* $search Optional messages set to limit the result
*
* @return rcube_result_index Sorted list of message UIDs
*/
- public function index_direct($folder, $sort_field = null, $sort_order = null)
+ public function index_direct($folder, $sort_field = null, $sort_order = null, $search = null)
{
+ if (!empty($search)) {
+ $search = $this->search_set->get_compressed();
+ }
+
// use message index sort as default sorting
if (!$sort_field) {
// use search result from count() if possible
- if ($this->options['skip_deleted'] && !empty($this->icache['undeleted_idx'])
+ if (empty($search) && $this->options['skip_deleted']
+ && !empty($this->icache['undeleted_idx'])
&& $this->icache['undeleted_idx']->get_parameters('ALL') !== null
&& $this->icache['undeleted_idx']->get_parameters('MAILBOX') == $folder
) {
@@ -1271,8 +1286,12 @@ class rcube_imap extends rcube_storage
return new rcube_result_index();
}
else {
- $index = $this->conn->search($folder,
- 'ALL' .($this->options['skip_deleted'] ? ' UNDELETED' : ''), true);
+ $query = $this->options['skip_deleted'] ? 'UNDELETED' : '';
+ if ($search) {
+ $query = trim($query . ' UID ' . $search);
+ }
+
+ $index = $this->conn->search($folder, $query, true);
}
}
else if (!$this->check_connection()) {
@@ -1281,13 +1300,18 @@ class rcube_imap extends rcube_storage
// fetch complete message index
else {
if ($this->get_capability('SORT')) {
- $index = $this->conn->sort($folder, $sort_field,
- $this->options['skip_deleted'] ? 'UNDELETED' : '', true);
+ $query = $this->options['skip_deleted'] ? 'UNDELETED' : '';
+ if ($search) {
+ $query = trim($query . ' UID ' . $search);
+ }
+
+ $index = $this->conn->sort($folder, $sort_field, $query, true);
}
if (empty($index) || $index->is_error()) {
- $index = $this->conn->index($folder, "1:*", $sort_field,
- $this->options['skip_deleted'], false, true);
+ $index = $this->conn->index($folder, $search ? $search : "1:*",
+ $sort_field, $this->options['skip_deleted'],
+ $search ? true : false, true);
}
}
@@ -1346,9 +1370,9 @@ class rcube_imap extends rcube_storage
// THREAD=REFERENCES: sorting by sent date of root message
// THREAD=REFS: sorting by the most recent date in each thread
- if ($this->get_capability('THREAD') != 'REFS') {
+ if ($this->threading != 'REFS' || ($this->sort_field && $this->sort_field != 'date')) {
$sortby = $this->sort_field ? $this->sort_field : 'date';
- $index = $this->index($this->folder, $sortby, $this->sort_order, true);
+ $index = $this->index($this->folder, $sortby, $this->sort_order, true, true);
if (!$index->is_empty()) {
$threads->sort($index);
@@ -2243,13 +2267,14 @@ class rcube_imap extends rcube_storage
/**
* Append a mail message (source) to a specific folder
*
- * @param string $folder Target folder
- * @param string $message The message source string or filename
- * @param string $headers Headers string if $message contains only the body
- * @param boolean $is_file True if $message is a filename
- * @param array $flags Message flags
- * @param mixed $date Message internal date
- * @param bool $binary Enables BINARY append
+ * @param string $folder Target folder
+ * @param string|array $message The message source string or filename
+ * or array (of strings and file pointers)
+ * @param string $headers Headers string if $message contains only the body
+ * @param boolean $is_file True if $message is a filename
+ * @param array $flags Message flags
+ * @param mixed $date Message internal date
+ * @param bool $binary Enables BINARY append
*
* @return int|bool Appended message UID or True on success, False on error
*/
@@ -2642,7 +2667,6 @@ class rcube_imap extends rcube_storage
if ($list_extended) {
// unsubscribe non-existent folders, remove from the list
- // we can do this only when LIST response is available
if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) {
foreach ($a_folders as $idx => $folder) {
if (($opts = $this->conn->data['LIST'][$folder])
@@ -2655,19 +2679,14 @@ class rcube_imap extends rcube_storage
}
}
else {
- // unsubscribe non-existent folders, remove them from the list,
- // we can do this only when LIST response is available
- if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) {
- foreach ($a_folders as $idx => $folder) {
- if (!isset($this->conn->data['LIST'][$folder])
- || in_array('\\Noselect', $this->conn->data['LIST'][$folder])
- ) {
- // Some servers returns \Noselect for existing folders
- if (!$this->folder_exists($folder)) {
- $this->conn->unsubscribe($folder);
- unset($a_folders[$idx]);
- }
- }
+ // unsubscribe non-existent folders, remove them from the list
+ if (is_array($a_folders) && !empty($a_folders) && $name == '*') {
+ $existing = $this->list_folders($root, $name);
+ $nonexisting = array_diff($a_folders, $existing);
+ $a_folders = array_diff($a_folders, $nonexisting);
+
+ foreach ($nonexisting as $folder) {
+ $this->conn->unsubscribe($folder);
}
}
}
diff --git a/program/lib/Roundcube/rcube_imap_generic.php b/program/lib/Roundcube/rcube_imap_generic.php
index 292b932e1..920c7184a 100644
--- a/program/lib/Roundcube/rcube_imap_generic.php
+++ b/program/lib/Roundcube/rcube_imap_generic.php
@@ -715,6 +715,10 @@ class rcube_imap_generic
$auth_method = 'CHECK';
}
+ if (!empty($this->prefs['disabled_caps'])) {
+ $this->prefs['disabled_caps'] = array_map('strtoupper', (array)$this->prefs['disabled_caps']);
+ }
+
$result = false;
// initialize connection
@@ -1329,9 +1333,8 @@ class rcube_imap_generic
$folders[$mailbox] = array();
}
- // store LSUB options only if not empty, this way
- // we can detect a situation when LIST doesn't return specified folder
- if (!empty($opts) || $cmd == 'LIST') {
+ // store folder options
+ if ($cmd == 'LIST') {
// Add to options array
if (empty($this->data['LIST'][$mailbox]))
$this->data['LIST'][$mailbox] = $opts;
@@ -1563,11 +1566,12 @@ class rcube_imap_generic
}
// message IDs
- if (!empty($add))
+ if (!empty($add)) {
$add = $this->compressMessageSet($add);
+ }
list($code, $response) = $this->execute($return_uid ? 'UID SORT' : 'SORT',
- array("($field)", $encoding, 'ALL' . (!empty($add) ? ' '.$add : '')));
+ array("($field)", $encoding, !empty($add) ? $add : 'ALL'));
if ($code != self::ERROR_OK) {
$response = null;
@@ -2158,14 +2162,18 @@ class rcube_imap_generic
else if ($name == 'RFC822') {
$result[$id]->body = $value;
}
- else if ($name == 'BODY') {
- $body = $this->tokenizeResponse($line, 1);
- if ($value[0] == 'HEADER.FIELDS')
- $headers = $body;
- else if (!empty($value))
- $result[$id]->bodypart[$value[0]] = $body;
+ else if (stripos($name, 'BODY[') === 0) {
+ $name = str_replace(']', '', substr($name, 5));
+
+ if ($name == 'HEADER.FIELDS') {
+ // skip ']' after headers list
+ $this->tokenizeResponse($line, 1);
+ $headers = $this->tokenizeResponse($line, 1);
+ }
+ else if (strlen($name))
+ $result[$id]->bodypart[$name] = $value;
else
- $result[$id]->body = $body;
+ $result[$id]->body = $value;
}
}
@@ -2505,6 +2513,7 @@ class rcube_imap_generic
// handle one line response
if ($line[0] == '(' && substr($line, -1) == ')') {
// tokenize content inside brackets
+ // the content can be e.g.: (UID 9844 BODY[2.4] NIL)
$tokens = $this->tokenizeResponse(preg_replace('/(^\(|\)$)/', '', $line));
for ($i=0; $i<count($tokens); $i+=2) {
@@ -2533,7 +2542,11 @@ class rcube_imap_generic
$prev = '';
$found = true;
- while ($bytes > 0) {
+ // empty body
+ if (!$bytes) {
+ $result = '';
+ }
+ else while ($bytes > 0) {
$line = $this->readLine(8192);
if ($line === NULL) {
@@ -2615,11 +2628,11 @@ class rcube_imap_generic
/**
* Handler for IMAP APPEND command
*
- * @param string $mailbox Mailbox name
- * @param string $message Message content
- * @param array $flags Message flags
- * @param string $date Message internal date
- * @param bool $binary Enable BINARY append (RFC3516)
+ * @param string $mailbox Mailbox name
+ * @param string|array $message The message source string or array (of strings and file pointers)
+ * @param array $flags Message flags
+ * @param string $date Message internal date
+ * @param bool $binary Enable BINARY append (RFC3516)
*
* @return string|bool On success APPENDUID response (if available) or True, False on failure
*/
@@ -2633,13 +2646,28 @@ class rcube_imap_generic
$binary = $binary && $this->getCapability('BINARY');
$literal_plus = !$binary && $this->prefs['literal+'];
+ $len = 0;
+ $msg = is_array($message) ? $message : array(&$message);
+ $chunk_size = 512000;
+
+ for ($i=0, $cnt=count($msg); $i<$cnt; $i++) {
+ if (is_resource($msg[$i])) {
+ $stat = fstat($msg[$i]);
+ if ($stat === false) {
+ return false;
+ }
+ $len += $stat['size'];
+ }
+ else {
+ if (!$binary) {
+ $msg[$i] = str_replace("\r", '', $msg[$i]);
+ $msg[$i] = str_replace("\n", "\r\n", $msg[$i]);
+ }
- if (!$binary) {
- $message = str_replace("\r", '', $message);
- $message = str_replace("\n", "\r\n", $message);
+ $len += strlen($msg[$i]);
+ }
}
- $len = strlen($message);
if (!$len) {
return false;
}
@@ -2664,7 +2692,32 @@ class rcube_imap_generic
}
}
- if (!$this->putLine($message)) {
+ foreach ($msg as $msg_part) {
+ // file pointer
+ if (is_resource($msg_part)) {
+ rewind($msg_part);
+ while (!feof($msg_part) && $this->fp) {
+ $buffer = fread($msg_part, $chunk_size);
+ $this->putLine($buffer, false);
+ }
+ fclose($msg_part);
+ }
+ // string
+ else {
+ $size = strlen($msg_part);
+
+ // Break up the data by sending one chunk (up to 512k) at a time.
+ // This approach reduces our peak memory usage
+ for ($offset = 0; $offset < $size; $offset += $chunk_size) {
+ $chunk = substr($msg_part, $offset, $chunk_size);
+ if (!$this->putLine($chunk, false)) {
+ return false;
+ }
+ }
+ }
+ }
+
+ if (!$this->putLine('')) { // \r\n
return false;
}
@@ -2703,94 +2756,23 @@ class rcube_imap_generic
*/
function appendFromFile($mailbox, $path, $headers=null, $flags = array(), $date = null, $binary = false)
{
- unset($this->data['APPENDUID']);
-
- if ($mailbox === null || $mailbox === '') {
- return false;
- }
-
// open message file
- $in_fp = false;
if (file_exists(realpath($path))) {
- $in_fp = fopen($path, 'r');
+ $fp = fopen($path, 'r');
}
- if (!$in_fp) {
+ if (!$fp) {
$this->setError(self::ERROR_UNKNOWN, "Couldn't open $path for reading");
return false;
}
- $body_separator = "\r\n\r\n";
- $len = filesize($path);
-
- if (!$len) {
- return false;
- }
-
+ $message = array();
if ($headers) {
- $headers = preg_replace('/[\r\n]+$/', '', $headers);
- $len += strlen($headers) + strlen($body_separator);
+ $message[] = trim($headers, "\r\n") . "\r\n\r\n";
}
+ $message[] = $fp;
- $binary = $binary && $this->getCapability('BINARY');
- $literal_plus = !$binary && $this->prefs['literal+'];
-
- // build APPEND command
- $key = $this->nextTag();
- $request = "$key APPEND " . $this->escape($mailbox) . ' (' . $this->flagsToStr($flags) . ')';
- if (!empty($date)) {
- $request .= ' ' . $this->escape($date);
- }
- $request .= ' ' . ($binary ? '~' : '') . '{' . $len . ($literal_plus ? '+' : '') . '}';
-
- // send APPEND command
- if ($this->putLine($request)) {
- // Don't wait when LITERAL+ is supported
- if (!$literal_plus) {
- $line = $this->readReply();
-
- if ($line[0] != '+') {
- $this->parseResult($line, 'APPEND: ');
- return false;
- }
- }
-
- // send headers with body separator
- if ($headers) {
- $this->putLine($headers . $body_separator, false);
- }
-
- // send file
- while (!feof($in_fp) && $this->fp) {
- $buffer = fgets($in_fp, 4096);
- $this->putLine($buffer, false);
- }
- fclose($in_fp);
-
- if (!$this->putLine('')) { // \r\n
- return false;
- }
-
- // read response
- do {
- $line = $this->readLine();
- } while (!$this->startsWith($line, $key, true, true));
-
- // Clear internal status cache
- unset($this->data['STATUS:'.$mailbox]);
-
- if ($this->parseResult($line, 'APPEND: ') != self::ERROR_OK)
- return false;
- else if (!empty($this->data['APPENDUID']))
- return $this->data['APPENDUID'];
- else
- return true;
- }
- else {
- $this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
- }
-
- return false;
+ return $this->append($mailbox, $message, $flags, $date, $binary);
}
/**
@@ -3008,7 +2990,7 @@ class rcube_imap_generic
}
foreach ($entries as $name => $value) {
- $entries[$name] = $this->escape($name) . ' ' . $this->escape($value);
+ $entries[$name] = $this->escape($name) . ' ' . $this->escape($value, true);
}
$entries = implode(' ', $entries);
@@ -3505,25 +3487,24 @@ class rcube_imap_generic
// Parenthesized list
case '(':
- case '[':
$str = substr($str, 1);
$result[] = self::tokenizeResponse($str);
break;
case ')':
- case ']':
$str = substr($str, 1);
return $result;
break;
- // String atom, number, NIL, *, %
+ // String atom, number, astring, NIL, *, %
default:
// empty string
if ($str === '' || $str === null) {
break 2;
}
- // excluded chars: SP, CTL, ), [, ]
- if (preg_match('/^([^\x00-\x20\x29\x5B\x5D\x7F]+)/', $str, $m)) {
+ // excluded chars: SP, CTL, ), DEL
+ // we do not exclude [ and ] (#1489223)
+ if (preg_match('/^([^\x00-\x20\x29\x7F]+)/', $str, $m)) {
$result[] = $m[1] == 'NIL' ? NULL : $m[1];
$str = substr($str, strlen($m[1]));
}
@@ -3714,6 +3695,10 @@ class rcube_imap_generic
$this->capability = explode(' ', strtoupper($str));
+ if (!empty($this->prefs['disabled_caps'])) {
+ $this->capability = array_diff($this->capability, $this->prefs['disabled_caps']);
+ }
+
if (!isset($this->prefs['literal+']) && in_array('LITERAL+', $this->capability)) {
$this->prefs['literal+'] = true;
}
diff --git a/program/lib/Roundcube/rcube_ldap.php b/program/lib/Roundcube/rcube_ldap.php
index 39a48b456..555a56471 100644
--- a/program/lib/Roundcube/rcube_ldap.php
+++ b/program/lib/Roundcube/rcube_ldap.php
@@ -3,8 +3,8 @@
/*
+-----------------------------------------------------------------------+
| This file is part of the Roundcube Webmail client |
- | Copyright (C) 2006-2012, The Roundcube Dev Team |
- | Copyright (C) 2011-2012, Kolab Systems AG |
+ | Copyright (C) 2006-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. |
@@ -27,38 +27,50 @@
*/
class rcube_ldap extends rcube_addressbook
{
- /** public properties */
+ // public properties
public $primary_key = 'ID';
- public $groups = false;
- public $readonly = true;
- public $ready = false;
- public $group_id = 0;
- public $coltypes = array();
-
- /** private properties */
- protected $conn;
- protected $prop = array();
+ public $groups = false;
+ public $readonly = true;
+ public $ready = false;
+ public $group_id = 0;
+ public $coltypes = array();
+
+ // private properties
+ protected $ldap;
+ protected $prop = array();
protected $fieldmap = array();
+ protected $filter = '';
protected $sub_filter;
- protected $filter = '';
- protected $result = null;
- protected $ldap_result = null;
+ protected $result;
+ protected $ldap_result;
protected $mail_domain = '';
protected $debug = false;
- private $base_dn = '';
+ /**
+ * Group objectclass (lowercase) to member attribute mapping
+ *
+ * @var array
+ */
+ private static $group_types = array(
+ 'group' => 'member',
+ 'groupofnames' => 'member',
+ 'kolabgroupofnames' => 'member',
+ 'groupofuniquenames' => 'uniqueMember',
+ 'kolabgroupofuniquenames' => 'uniqueMember',
+ 'univentiongroup' => 'uniqueMember',
+ 'groupofurls' => null,
+ );
+
+ private $base_dn = '';
private $groups_base_dn = '';
- private $group_url = null;
+ private $group_url;
private $cache;
- private $vlv_active = false;
- private $vlv_count = 0;
-
/**
* Object constructor
*
- * @param array $p LDAP connection properties
+ * @param array $p LDAP connection properties
* @param boolean $debug Enables debug mode
* @param string $mail_domain Current user mail domain name
*/
@@ -66,8 +78,7 @@ class rcube_ldap extends rcube_addressbook
{
$this->prop = $p;
- if (isset($p['searchonly']))
- $this->searchonly = $p['searchonly'];
+ $fetch_attributes = array('objectClass');
// check if groups are configured
if (is_array($p['groups']) && count($p['groups'])) {
@@ -82,6 +93,21 @@ class rcube_ldap extends rcube_addressbook
$this->prop['groups']['name_attr'] = 'cn';
if (empty($this->prop['groups']['scope']))
$this->prop['groups']['scope'] = 'sub';
+
+ // add group name attrib to the list of attributes to be fetched
+ $fetch_attributes[] = $this->prop['groups']['name_attr'];
+ }
+ if (is_array($p['group_filters']) && count($p['group_filters'])) {
+ $this->groups = true;
+
+ foreach ($p['group_filters'] as $k => $group_filter) {
+ // set default name attribute to cn
+ if (empty($group_filter['name_attr']) && empty($this->prop['groups']['name_attr']))
+ $this->prop['group_filters'][$k]['name_attr'] = $group_filter['name_attr'] = 'cn';
+
+ if ($group_filter['name_attr'])
+ $fetch_attributes[] = $group_filter['name_attr'];
+ }
}
// fieldmap property is given
@@ -185,12 +211,25 @@ class rcube_ldap extends rcube_addressbook
$this->mail_domain = $mail_domain;
// initialize cache
- $rcube = rcube::get_instance();
- $cache_type = $rcube->config->get('ldap_cache', 'db');
- $cache_ttl = $rcube->config->get('ldap_cache_ttl', '10m');
- $cache_name = 'LDAP.' . asciiwords($this->prop['name']);
+ $rcube = rcube::get_instance();
+ if ($cache_type = $rcube->config->get('ldap_cache', 'db')) {
+ $cache_ttl = $rcube->config->get('ldap_cache_ttl', '10m');
+ $cache_name = 'LDAP.' . asciiwords($this->prop['name']);
- $this->cache = $rcube->get_cache($cache_name, $cache_type, $cache_ttl);
+ $this->cache = $rcube->get_cache($cache_name, $cache_type, $cache_ttl);
+ }
+
+ // determine which attributes to fetch
+ $this->prop['list_attributes'] = array_unique($fetch_attributes);
+ $this->prop['attributes'] = array_merge(array_values($this->fieldmap), $fetch_attributes);
+ foreach ($rcube->config->get('contactlist_fields') as $col) {
+ $this->prop['list_attributes'] = array_merge($this->prop['list_attributes'], $this->_map_field($col));
+ }
+
+ // initialize ldap wrapper object
+ $this->ldap = new rcube_ldap_generic($this->prop);
+ $this->ldap->set_cache($this->cache);
+ $this->ldap->set_debug($this->debug);
$this->_connect();
}
@@ -203,49 +242,18 @@ class rcube_ldap extends rcube_addressbook
{
$rcube = rcube::get_instance();
- if (!function_exists('ldap_connect'))
- rcube::raise_error(array('code' => 100, 'type' => 'ldap',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "No ldap support in this installation of PHP"),
- true, true);
-
- if (is_resource($this->conn))
+ if ($this->ready)
return true;
if (!is_array($this->prop['hosts']))
$this->prop['hosts'] = array($this->prop['hosts']);
- if (empty($this->prop['ldap_version']))
- $this->prop['ldap_version'] = 3;
-
// try to connect + bind for every host configured
// with OpenLDAP 2.x ldap_connect() always succeeds but ldap_bind will fail if host isn't reachable
// see http://www.php.net/manual/en/function.ldap-connect.php
foreach ($this->prop['hosts'] as $host) {
- $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
- $hostname = $host.($this->prop['port'] ? ':'.$this->prop['port'] : '');
-
- $this->_debug("C: Connect [$hostname] [{$this->prop['name']}]");
-
- if ($lc = @ldap_connect($host, $this->prop['port'])) {
- if ($this->prop['use_tls'] === true)
- if (!ldap_start_tls($lc))
- continue;
-
- $this->_debug("S: OK");
-
- ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, $this->prop['ldap_version']);
- $this->prop['host'] = $host;
- $this->conn = $lc;
-
- if (!empty($this->prop['network_timeout']))
- ldap_set_option($lc, LDAP_OPT_NETWORK_TIMEOUT, $this->prop['network_timeout']);
-
- if (isset($this->prop['referrals']))
- ldap_set_option($lc, LDAP_OPT_REFERRALS, $this->prop['referrals']);
- }
- else {
- $this->_debug("S: NOT OK");
+ // skip host if connection failed
+ if (!$this->ldap->connect($host)) {
continue;
}
@@ -260,7 +268,7 @@ class rcube_ldap extends rcube_addressbook
$this->base_dn = $this->prop['base_dn'];
$this->groups_base_dn = ($this->prop['groups']['base_dn']) ?
- $this->prop['groups']['base_dn'] : $this->base_dn;
+ $this->prop['groups']['base_dn'] : $this->base_dn;
// User specific access, generate the proper values to use.
if ($this->prop['user_specific']) {
@@ -279,29 +287,46 @@ class rcube_ldap extends rcube_addressbook
$replaces = array('%dn' => '', '%dc' => $dc, '%d' => $d, '%fu' => $fu, '%u' => $u);
+ // Search for the dn to use to authenticate
if ($this->prop['search_base_dn'] && $this->prop['search_filter']) {
- if (!empty($this->prop['search_bind_dn']) && !empty($this->prop['search_bind_pw'])) {
- $this->bind($this->prop['search_bind_dn'], $this->prop['search_bind_pw']);
- }
-
- // Search for the dn to use to authenticate
- $this->prop['search_base_dn'] = strtr($this->prop['search_base_dn'], $replaces);
- $this->prop['search_filter'] = strtr($this->prop['search_filter'], $replaces);
+ $search_bind_dn = strtr($this->prop['search_bind_dn'], $replaces);
+ $search_base_dn = strtr($this->prop['search_base_dn'], $replaces);
+ $search_filter = strtr($this->prop['search_filter'], $replaces);
- $this->_debug("S: searching with base {$this->prop['search_base_dn']} for {$this->prop['search_filter']}");
+ $cache_key = 'DN.' . md5("$host:$search_bind_dn:$search_base_dn:$search_filter:"
+ .$this->prop['search_bind_pw']);
- $res = @ldap_search($this->conn, $this->prop['search_base_dn'], $this->prop['search_filter'], array('uid'));
- if ($res) {
- if (($entry = ldap_first_entry($this->conn, $res))
- && ($bind_dn = ldap_get_dn($this->conn, $entry))
- ) {
- $this->_debug("S: search returned dn: $bind_dn");
- $dn = ldap_explode_dn($bind_dn, 1);
- $replaces['%dn'] = $dn[0];
- }
+ if ($this->cache && ($dn = $this->cache->get($cache_key))) {
+ $replaces['%dn'] = $dn;
}
else {
- $this->_debug("S: ".ldap_error($this->conn));
+ $ldap = $this->ldap;
+ if (!empty($search_bind_dn) && !empty($this->prop['search_bind_pw'])) {
+ // To protect from "Critical extension is unavailable" error
+ // we need to use a separate LDAP connection
+ if (!empty($this->prop['vlv'])) {
+ $ldap = new rcube_ldap_generic($this->prop);
+ $ldap->set_debug($this->debug);
+ $ldap->set_cache($this->cache);
+ if (!$ldap->connect($host)) {
+ continue;
+ }
+ }
+
+ if (!$ldap->bind($search_bind_dn, $this->prop['search_bind_pw'])) {
+ continue; // bind failed, try next host
+ }
+ }
+
+ $res = $ldap->search($search_base_dn, $search_filter, 'sub', array('uid'));
+ if ($res) {
+ $res->rewind();
+ $replaces['%dn'] = $res->get_dn();
+ }
+
+ if ($ldap != $this->ldap) {
+ $ldap->close();
+ }
}
// DN not found
@@ -313,9 +338,13 @@ class rcube_ldap extends rcube_addressbook
'code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
'message' => "DN not found using LDAP search."), true);
- return false;
+ continue;
}
}
+
+ if ($this->cache && !empty($replaces['%dn'])) {
+ $this->cache->set($cache_key, $replaces['%dn']);
+ }
}
// Replace the bind_dn and base_dn variables.
@@ -333,13 +362,13 @@ class rcube_ldap extends rcube_addressbook
}
else {
if (!empty($bind_dn)) {
- $this->ready = $this->bind($bind_dn, $bind_pass);
+ $this->ready = $this->ldap->bind($bind_dn, $bind_pass);
}
else if (!empty($this->prop['auth_cid'])) {
- $this->ready = $this->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user);
+ $this->ready = $this->ldap->sasl_bind($this->prop['auth_cid'], $bind_pass, $bind_user);
}
else {
- $this->ready = $this->sasl_bind($bind_user, $bind_pass);
+ $this->ready = $this->ldap->sasl_bind($bind_user, $bind_pass);
}
}
@@ -350,10 +379,10 @@ class rcube_ldap extends rcube_addressbook
} // end foreach hosts
- if (!is_resource($this->conn)) {
+ if (!is_resource($this->ldap->conn)) {
rcube::raise_error(array('code' => 100, 'type' => 'ldap',
'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Could not connect to any LDAP server, last tried $hostname"), true);
+ 'message' => "Could not connect to any LDAP server, last tried $host"), true);
return false;
}
@@ -363,112 +392,47 @@ class rcube_ldap extends rcube_addressbook
/**
- * Bind connection with (SASL-) user and password
- *
- * @param string $authc Authentication user
- * @param string $pass Bind password
- * @param string $authz Autorization user
- *
- * @return boolean True on success, False on error
+ * Close connection to LDAP server
*/
- public function sasl_bind($authc, $pass, $authz=null)
+ function close()
{
- if (!$this->conn) {
- return false;
- }
-
- if (!function_exists('ldap_sasl_bind')) {
- rcube::raise_error(array('code' => 100, 'type' => 'ldap',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Unable to bind: ldap_sasl_bind() not exists"),
- true, true);
+ if ($this->ldap) {
+ $this->ldap->close();
}
-
- if (!empty($authz)) {
- $authz = 'u:' . $authz;
- }
-
- if (!empty($this->prop['auth_method'])) {
- $method = $this->prop['auth_method'];
- }
- else {
- $method = 'DIGEST-MD5';
- }
-
- $this->_debug("C: Bind [mech: $method, authc: $authc, authz: $authz] [pass: $pass]");
-
- if (ldap_sasl_bind($this->conn, NULL, $pass, $method, NULL, $authc, $authz)) {
- $this->_debug("S: OK");
- return true;
- }
-
- $this->_debug("S: ".ldap_error($this->conn));
-
- rcube::raise_error(array(
- 'code' => ldap_errno($this->conn), 'type' => 'ldap',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Bind failed for authcid=$authc ".ldap_error($this->conn)),
- true);
-
- return false;
}
/**
- * Bind connection with DN and password
- *
- * @param string Bind DN
- * @param string Bind password
+ * Returns address book name
*
- * @return boolean True on success, False on error
+ * @return string Address book name
*/
- public function bind($dn, $pass)
+ function get_name()
{
- if (!$this->conn) {
- return false;
- }
-
- $this->_debug("C: Bind [dn: $dn] [pass: $pass]");
-
- if (@ldap_bind($this->conn, $dn, $pass)) {
- $this->_debug("S: OK");
- return true;
- }
-
- $this->_debug("S: ".ldap_error($this->conn));
-
- rcube::raise_error(array(
- 'code' => ldap_errno($this->conn), 'type' => 'ldap',
- 'file' => __FILE__, 'line' => __LINE__,
- 'message' => "Bind failed for dn=$dn: ".ldap_error($this->conn)),
- true);
-
- return false;
+ return $this->prop['name'];
}
/**
- * Close connection to LDAP server
+ * Set internal list page
+ *
+ * @param number Page number to list
*/
- function close()
+ function set_page($page)
{
- if ($this->conn)
- {
- $this->_debug("C: Close");
- ldap_unbind($this->conn);
- $this->conn = null;
- }
+ $this->list_page = (int)$page;
+ $this->ldap->set_vlv_page($this->list_page, $this->page_size);
}
-
/**
- * Returns address book name
+ * Set internal page size
*
- * @return string Address book name
+ * @param number Number of records to display on one page
*/
- function get_name()
+ function set_pagesize($size)
{
- return $this->prop['name'];
+ $this->page_size = (int)$size;
+ $this->ldap->set_vlv_page($this->list_page, $this->page_size);
}
@@ -528,16 +492,14 @@ class rcube_ldap extends rcube_addressbook
*/
function list_records($cols=null, $subset=0)
{
- if ($this->prop['searchonly'] && empty($this->filter) && !$this->group_id)
- {
+ if ($this->prop['searchonly'] && empty($this->filter) && !$this->group_id) {
$this->result = new rcube_result_set(0);
$this->result->searchonly = true;
return $this->result;
}
// fetch group members recursively
- if ($this->group_id && $this->group_data['dn'])
- {
+ if ($this->group_id && $this->group_data['dn']) {
$entries = $this->list_group_members($this->group_data['dn']);
// make list of entries unique and sort it
@@ -551,34 +513,34 @@ class rcube_ldap extends rcube_addressbook
$entries['count'] = count($entries);
$this->result = new rcube_result_set($entries['count'], ($this->list_page-1) * $this->page_size);
}
- else
- {
- // add general filter to query
- if (!empty($this->prop['filter']) && empty($this->filter))
- $this->set_search_set($this->prop['filter']);
+ else {
+ $prop = $this->group_id ? $this->group_data : $this->prop;
+
+ // use global search filter
+ if (!empty($this->filter))
+ $prop['filter'] = $this->filter;
// exec LDAP search if no result resource is stored
- if ($this->conn && !$this->ldap_result)
- $this->_exec_search();
+ if ($this->ready && !$this->ldap_result)
+ $this->ldap_result = $this->ldap->search($prop['base_dn'], $prop['filter'], $prop['scope'], $this->prop['attributes'], $prop);
// count contacts for this user
$this->result = $this->count();
// we have a search result resource
- if ($this->ldap_result && $this->result->count > 0)
- {
+ if ($this->ldap_result && $this->result->count > 0) {
// sorting still on the ldap server
- if ($this->sort_col && $this->prop['scope'] !== 'base' && !$this->vlv_active)
- ldap_sort($this->conn, $this->ldap_result, $this->sort_col);
+ if ($this->sort_col && $prop['scope'] !== 'base' && !$this->ldap->vlv_active)
+ $this->ldap_result->sort($this->sort_col);
// get all entries from the ldap server
- $entries = ldap_get_entries($this->conn, $this->ldap_result);
+ $entries = $this->ldap_result->entries();
}
} // end else
// start and end of the page
- $start_row = $this->vlv_active ? 0 : $this->result->first;
+ $start_row = $this->ldap->vlv_active ? 0 : $this->result->first;
$start_row = $subset < 0 ? $start_row + $this->page_size + $subset : $start_row;
$last_row = $this->result->first + $this->page_size;
$last_row = $subset != 0 ? $start_row + abs($subset) : $last_row;
@@ -603,43 +565,34 @@ class rcube_ldap extends rcube_addressbook
// fetch group object
if (empty($entries)) {
- $result = @ldap_read($this->conn, $dn, '(objectClass=*)', array('dn','objectClass','member','uniqueMember','memberURL'));
- if ($result === false)
- {
- $this->_debug("S: ".ldap_error($this->conn));
+ $attribs = array('dn','objectClass','member','uniqueMember','memberURL');
+ $entries = $this->ldap->read_entries($dn, '(objectClass=*)', $attribs);
+ if ($entries === false) {
return $group_members;
}
-
- $entries = @ldap_get_entries($this->conn, $result);
}
- for ($i=0; $i < $entries['count']; $i++)
- {
+ for ($i=0; $i < $entries['count']; $i++) {
$entry = $entries[$i];
+ $attrs = array();
- if (empty($entry['objectclass']))
- continue;
+ foreach ((array)$entry['objectclass'] as $objectclass) {
+ if (strtolower($objectclass) == 'groupofurls') {
+ $members = $this->_list_group_memberurl($dn, $entry, $count);
+ $group_members = array_merge($group_members, $members);
+ }
+ else if (($member_attr = $this->get_group_member_attr(array($objectclass), ''))
+ && ($member_attr = strtolower($member_attr)) && !in_array($member_attr, $attrs)
+ ) {
+ $members = $this->_list_group_members($dn, $entry, $member_attr, $count);
+ $group_members = array_merge($group_members, $members);
+ $attrs[] = $member_attr;
+ }
- foreach ((array)$entry['objectclass'] as $objectclass)
- {
- switch (strtolower($objectclass)) {
- case "group":
- case "groupofnames":
- case "kolabgroupofnames":
- $group_members = array_merge($group_members, $this->_list_group_members($dn, $entry, 'member', $count));
- break;
- case "groupofuniquenames":
- case "kolabgroupofuniquenames":
- $group_members = array_merge($group_members, $this->_list_group_members($dn, $entry, 'uniquemember', $count));
- break;
- case "groupofurls":
- $group_members = array_merge($group_members, $this->_list_group_memberurl($dn, $entry, $count));
- break;
+ if ($this->prop['sizelimit'] && count($group_members) > $this->prop['sizelimit']) {
+ break 2;
}
}
-
- if ($this->prop['sizelimit'] && count($group_members) > $this->prop['sizelimit'])
- break;
}
return array_filter($group_members);
@@ -658,28 +611,24 @@ class rcube_ldap extends rcube_addressbook
// Use the member attributes to return an array of member ldap objects
// NOTE that the member attribute is supposed to contain a DN
$group_members = array();
- if (empty($entry[$attr]))
+ if (empty($entry[$attr])) {
return $group_members;
+ }
// read these attributes for all members
- $attrib = $count ? array('dn') : array_values($this->fieldmap);
- $attrib[] = 'objectClass';
+ $attrib = $count ? array('dn','objectClass') : $this->prop['list_attributes'];
$attrib[] = 'member';
$attrib[] = 'uniqueMember';
$attrib[] = 'memberURL';
- for ($i=0; $i < $entry[$attr]['count']; $i++)
- {
+ $filter = $this->prop['groups']['member_filter'] ? $this->prop['groups']['member_filter'] : '(objectclass=*)';
+
+ for ($i=0; $i < $entry[$attr]['count']; $i++) {
if (empty($entry[$attr][$i]))
continue;
- $result = @ldap_read($this->conn, $entry[$attr][$i], '(objectclass=*)',
- $attrib, 0, (int)$this->prop['sizelimit'], (int)$this->prop['timelimit']);
-
- $members = @ldap_get_entries($this->conn, $result);
- if ($members == false)
- {
- $this->_debug("S: ".ldap_error($this->conn));
+ $members = $this->ldap->read_entries($entry[$attr][$i], $filter, $attrib);
+ if ($members == false) {
$members = array();
}
@@ -705,34 +654,22 @@ class rcube_ldap extends rcube_addressbook
{
$group_members = array();
- for ($i=0; $i < $entry['memberurl']['count']; $i++)
- {
+ for ($i=0; $i < $entry['memberurl']['count']; $i++) {
// extract components from url
if (!preg_match('!ldap:///([^\?]+)\?\?(\w+)\?(.*)$!', $entry['memberurl'][$i], $m))
continue;
// add search filter if any
$filter = $this->filter ? '(&(' . $m[3] . ')(' . $this->filter . '))' : $m[3];
- $func = $m[2] == 'sub' ? 'ldap_search' : ($m[2] == 'base' ? 'ldap_read' : 'ldap_list');
-
- $attrib = $count ? array('dn') : array_values($this->fieldmap);
- if ($result = @$func($this->conn, $m[1], $filter,
- $attrib, 0, (int)$this->prop['sizelimit'], (int)$this->prop['timelimit'])
- ) {
- $this->_debug("S: ".ldap_count_entries($this->conn, $result)." record(s) for ".$m[1]);
- }
- else {
- $this->_debug("S: ".ldap_error($this->conn));
- return $group_members;
- }
-
- $entries = @ldap_get_entries($this->conn, $result);
- for ($j = 0; $j < $entries['count']; $j++)
- {
- if ($nested_group_members = $this->list_group_members($entries[$j]['dn'], $count))
- $group_members = array_merge($group_members, $nested_group_members);
- else
- $group_members[] = $entries[$j];
+ $attrs = $count ? array('dn','objectClass') : $this->prop['list_attributes'];
+ if ($result = $this->ldap->search($m[1], $filter, $m[2], $attrs, $this->group_data)) {
+ $entries = $result->entries();
+ for ($j = 0; $j < $entries['count']; $j++) {
+ if (self::is_group_entry($entries[$j]) && ($nested_group_members = $this->list_group_members($entries[$j]['dn'], $count)))
+ $group_members = array_merge($group_members, $nested_group_members);
+ else
+ $group_members[] = $entries[$j];
+ }
}
}
@@ -768,14 +705,11 @@ class rcube_ldap extends rcube_addressbook
$mode = intval($mode);
// special treatment for ID-based search
- if ($fields == 'ID' || $fields == $this->primary_key)
- {
+ if ($fields == 'ID' || $fields == $this->primary_key) {
$ids = !is_array($value) ? explode(',', $value) : $value;
$result = new rcube_result_set();
- foreach ($ids as $id)
- {
- if ($rec = $this->get_record($id, true))
- {
+ foreach ($ids as $id) {
+ if ($rec = $this->get_record($id, true)) {
$result->add($rec);
$result->count++;
}
@@ -787,34 +721,20 @@ class rcube_ldap extends rcube_addressbook
$rcube = rcube::get_instance();
$list_fields = $rcube->config->get('contactlist_fields');
- if ($this->prop['vlv_search'] && $this->conn && join(',', (array)$fields) == join(',', $list_fields))
- {
- // add general filter to query
- if (!empty($this->prop['filter']) && empty($this->filter))
- $this->set_search_set($this->prop['filter']);
-
- // set VLV controls with encoded search string
- $this->_vlv_set_controls($this->prop, $this->list_page, $this->page_size, $value);
-
- $function = $this->_scope2func($this->prop['scope']);
- $this->ldap_result = @$function($this->conn, $this->base_dn, $this->filter ? $this->filter : '(objectclass=*)',
- array_values($this->fieldmap), 0, $this->page_size, (int)$this->prop['timelimit']);
-
+ if ($this->prop['vlv_search'] && $this->ready && join(',', (array)$fields) == join(',', $list_fields)) {
$this->result = new rcube_result_set(0);
- if (!$this->ldap_result) {
- $this->_debug("S: ".ldap_error($this->conn));
+ $search_suffix = $this->prop['fuzzy_search'] && $mode != 1 ? '*' : '';
+ $ldap_data = $this->ldap->search($this->base_dn, $this->prop['filter'], $this->prop['scope'], $this->prop['attributes'],
+ array('search' => $value . $search_suffix /*, 'sort' => $this->prop['sort'] */));
+ if ($ldap_data === false) {
return $this->result;
}
- $this->_debug("S: ".ldap_count_entries($this->conn, $this->ldap_result)." record(s)");
-
// get all entries of this page and post-filter those that really match the query
- $search = mb_strtolower($value);
- $entries = ldap_get_entries($this->conn, $this->ldap_result);
-
- for ($i = 0; $i < $entries['count']; $i++) {
- $rec = $this->_ldap2result($entries[$i]);
+ $search = mb_strtolower($value);
+ foreach ($ldap_data as $i => $entry) {
+ $rec = $this->_ldap2result($entry);
foreach ($fields as $f) {
foreach ((array)$rec[$f] as $val) {
if ($this->compare_search_value($f, $val, $search, $mode)) {
@@ -840,31 +760,27 @@ class rcube_ldap extends rcube_addressbook
}
}
- if ($fields == '*')
- {
+ if ($fields == '*') {
// search_fields are required for fulltext search
- if (empty($this->prop['search_fields']))
- {
+ if (empty($this->prop['search_fields'])) {
$this->set_error(self::ERROR_SEARCH, 'nofulltextsearch');
$this->result = new rcube_result_set();
return $this->result;
}
- if (is_array($this->prop['search_fields']))
- {
+ if (is_array($this->prop['search_fields'])) {
foreach ($this->prop['search_fields'] as $field) {
- $filter .= "($field=$wp" . $this->_quote_string($value) . "$ws)";
+ $filter .= "($field=$wp" . rcube_ldap_generic::quote_string($value) . "$ws)";
}
}
}
- else
- {
+ else {
foreach ((array)$fields as $idx => $field) {
$val = is_array($value) ? $value[$idx] : $value;
if ($attrs = $this->_map_field($field)) {
if (count($attrs) > 1)
$filter .= '(|';
foreach ($attrs as $f)
- $filter .= "($f=$wp" . $this->_quote_string($val) . "$ws)";
+ $filter .= "($f=$wp" . rcube_ldap_generic::quote_string($val) . "$ws)";
if (count($attrs) > 1)
$filter .= ')';
}
@@ -875,6 +791,8 @@ class rcube_ldap extends rcube_addressbook
// add required (non empty) fields filter
$req_filter = '';
foreach ((array)$required as $field) {
+ if (in_array($field, (array)$fields)) // required field is already in search filter
+ continue;
if ($attrs = $this->_map_field($field)) {
if (count($attrs) > 1)
$req_filter .= '(|';
@@ -897,7 +815,6 @@ class rcube_ldap extends rcube_addressbook
// set filter string and execute search
$this->set_search_set($filter);
- $this->_exec_search();
if ($select)
$this->list_records();
@@ -916,20 +833,20 @@ class rcube_ldap extends rcube_addressbook
function count()
{
$count = 0;
- if ($this->conn && $this->ldap_result) {
- $count = $this->vlv_active ? $this->vlv_count : ldap_count_entries($this->conn, $this->ldap_result);
+ if ($this->ldap_result) {
+ $count = $this->ldap_result->count();
}
else if ($this->group_id && $this->group_data['dn']) {
$count = count($this->list_group_members($this->group_data['dn'], true));
}
- else if ($this->conn) {
- // We have a connection but no result set, attempt to get one.
- if (empty($this->filter)) {
- // The filter is not set, set it.
- $this->filter = $this->prop['filter'];
- }
+ // We have a connection but no result set, attempt to get one.
+ else if ($this->ready) {
+ $prop = $this->group_id ? $this->group_data : $this->prop;
- $count = (int) $this->_exec_search(true);
+ if (!empty($this->filter)) { // Use global search filter
+ $prop['filter'] = $this->filter;
+ }
+ $count = $this->ldap->search($prop['base_dn'], $prop['filter'], $prop['scope'], array('dn'), $prop, true);
}
return new rcube_result_set($count, ($this->list_page-1) * $this->page_size);
@@ -959,28 +876,16 @@ class rcube_ldap extends rcube_addressbook
{
$res = $this->result = null;
- if ($this->conn && $dn)
- {
+ if ($this->ready && $dn) {
$dn = self::dn_decode($dn);
- $this->_debug("C: Read [dn: $dn] [(objectclass=*)]");
-
- if ($ldap_result = @ldap_read($this->conn, $dn, '(objectclass=*)', array_values($this->fieldmap))) {
- $this->_debug("S: OK");
-
- $entry = ldap_first_entry($this->conn, $ldap_result);
-
- if ($entry && ($rec = ldap_get_attributes($this->conn, $entry))) {
- $rec = array_change_key_case($rec, CASE_LOWER);
- }
- }
- else {
- $this->_debug("S: ".ldap_error($this->conn));
+ if ($rec = $this->ldap->get_entry($dn)) {
+ $rec = array_change_key_case($rec, CASE_LOWER);
}
// Use ldap_list to get subentries like country (c) attribute (#1488123)
if (!empty($rec) && $this->sub_filter) {
- if ($entries = $this->ldap_list($dn, $this->sub_filter, array_keys($this->prop['sub_fields']))) {
+ if ($entries = $this->ldap->list_entries($dn, $this->sub_filter, array_keys($this->prop['sub_fields']))) {
foreach ($entries as $entry) {
$lrec = array_change_key_case($entry, CASE_LOWER);
$rec = array_merge($lrec, $rec);
@@ -992,7 +897,7 @@ class rcube_ldap extends rcube_addressbook
// Add in the dn for the entry.
$rec['dn'] = $dn;
$res = $this->_ldap2result($rec);
- $this->result = new rcube_result_set();
+ $this->result = new rcube_result_set(1);
$this->result->add($res);
}
}
@@ -1105,7 +1010,7 @@ class rcube_ldap extends rcube_addressbook
}
// Build the new entries DN.
- $dn = $this->prop['LDAP_rdn'].'='.$this->_quote_string($newentry[$this->prop['LDAP_rdn']], true).','.$this->base_dn;
+ $dn = $this->prop['LDAP_rdn'].'='.rcube_ldap_generic::quote_string($newentry[$this->prop['LDAP_rdn']], true).','.$this->base_dn;
// Remove attributes that need to be added separately (child objects)
$xfields = array();
@@ -1118,19 +1023,19 @@ class rcube_ldap extends rcube_addressbook
}
}
- if (!$this->ldap_add($dn, $newentry)) {
+ if (!$this->ldap->add($dn, $newentry)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
foreach ($xfields as $xidx => $xf) {
- $xdn = $xidx.'='.$this->_quote_string($xf).','.$dn;
+ $xdn = $xidx.'='.rcube_ldap_generic::quote_string($xf).','.$dn;
$xf = array(
$xidx => $xf,
'objectClass' => (array) $this->prop['sub_fields'][$xidx],
);
- $this->ldap_add($xdn, $xf);
+ $this->ldap->add($xdn, $xf);
}
$dn = self::dn_encode($dn);
@@ -1236,7 +1141,7 @@ class rcube_ldap extends rcube_addressbook
// Update the entry as required.
if (!empty($deletedata)) {
// Delete the fields.
- if (!$this->ldap_mod_del($dn, $deletedata)) {
+ if (!$this->ldap->mod_del($dn, $deletedata)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1246,17 +1151,17 @@ class rcube_ldap extends rcube_addressbook
// Handle RDN change
if ($replacedata[$this->prop['LDAP_rdn']]) {
$newdn = $this->prop['LDAP_rdn'].'='
- .$this->_quote_string($replacedata[$this->prop['LDAP_rdn']], true)
+ .rcube_ldap_generic::quote_string($replacedata[$this->prop['LDAP_rdn']], true)
.','.$this->base_dn;
if ($dn != $newdn) {
$newrdn = $this->prop['LDAP_rdn'].'='
- .$this->_quote_string($replacedata[$this->prop['LDAP_rdn']], true);
+ .rcube_ldap_generic::quote_string($replacedata[$this->prop['LDAP_rdn']], true);
unset($replacedata[$this->prop['LDAP_rdn']]);
}
}
// Replace the fields.
if (!empty($replacedata)) {
- if (!$this->ldap_mod_replace($dn, $replacedata)) {
+ if (!$this->ldap->mod_replace($dn, $replacedata)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1272,8 +1177,8 @@ class rcube_ldap extends rcube_addressbook
// remove sub-entries
if (!empty($subdeldata)) {
foreach ($subdeldata as $fld => $val) {
- $subdn = $fld.'='.$this->_quote_string($val).','.$dn;
- if (!$this->ldap_delete($subdn)) {
+ $subdn = $fld.'='.rcube_ldap_generic::quote_string($val).','.$dn;
+ if (!$this->ldap->delete($subdn)) {
return false;
}
}
@@ -1281,7 +1186,7 @@ class rcube_ldap extends rcube_addressbook
if (!empty($newdata)) {
// Add the fields.
- if (!$this->ldap_mod_add($dn, $newdata)) {
+ if (!$this->ldap->mod_add($dn, $newdata)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1289,7 +1194,7 @@ class rcube_ldap extends rcube_addressbook
// Handle RDN change
if (!empty($newrdn)) {
- if (!$this->ldap_rename($dn, $newrdn, null, true)) {
+ if (!$this->ldap->rename($dn, $newrdn, null, true)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1300,8 +1205,7 @@ class rcube_ldap extends rcube_addressbook
// change the group membership of the contact
if ($this->groups) {
$group_ids = $this->get_record_groups($dn);
- foreach ($group_ids as $group_id)
- {
+ foreach (array_keys($group_ids) as $group_id) {
$this->remove_from_group($group_id, $dn);
$this->add_to_group($group_id, $newdn);
}
@@ -1313,12 +1217,12 @@ class rcube_ldap extends rcube_addressbook
// add sub-entries
if (!empty($subnewdata)) {
foreach ($subnewdata as $fld => $val) {
- $subdn = $fld.'='.$this->_quote_string($val).','.$dn;
+ $subdn = $fld.'='.rcube_ldap_generic::quote_string($val).','.$dn;
$xf = array(
$fld => $val,
'objectClass' => (array) $this->prop['sub_fields'][$fld],
);
- $this->ldap_add($subdn, $xf);
+ $this->ldap->add($subdn, $xf);
}
}
@@ -1346,9 +1250,9 @@ class rcube_ldap extends rcube_addressbook
// Need to delete all sub-entries first
if ($this->sub_filter) {
- if ($entries = $this->ldap_list($dn, $this->sub_filter)) {
+ if ($entries = $this->ldap->list_entries($dn, $this->sub_filter)) {
foreach ($entries as $entry) {
- if (!$this->ldap_delete($entry['dn'])) {
+ if (!$this->ldap->delete($entry['dn'])) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1357,7 +1261,7 @@ class rcube_ldap extends rcube_addressbook
}
// Delete the record.
- if (!$this->ldap_delete($dn)) {
+ if (!$this->ldap->delete($dn)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
@@ -1366,7 +1270,7 @@ class rcube_ldap extends rcube_addressbook
if ($this->groups) {
$dn = self::dn_encode($dn);
$group_ids = $this->get_record_groups($dn);
- foreach ($group_ids as $group_id) {
+ foreach (array_keys($group_ids) as $group_id) {
$this->remove_from_group($group_id, $dn);
}
}
@@ -1381,8 +1285,8 @@ class rcube_ldap extends rcube_addressbook
*/
function delete_all()
{
- //searching for contact entries
- $dn_list = $this->ldap_list($this->base_dn, $this->prop['filter'] ? $this->prop['filter'] : '(objectclass=*)');
+ // searching for contact entries
+ $dn_list = $this->ldap->list_entries($this->base_dn, $this->prop['filter'] ? $this->prop['filter'] : '(objectclass=*)');
if (!empty($dn_list)) {
foreach ($dn_list as $idx => $entry) {
@@ -1432,120 +1336,26 @@ class rcube_ldap extends rcube_addressbook
}
}
- /**
- * Execute the LDAP search based on the stored credentials
- */
- private function _exec_search($count = false)
- {
- if ($this->ready)
- {
- $filter = $this->filter ? $this->filter : '(objectclass=*)';
- $function = $this->_scope2func($this->prop['scope'], $ns_function);
-
- $this->_debug("C: Search [$filter][dn: $this->base_dn]");
-
- // when using VLV, we get the total count by...
- if (!$count && $function != 'ldap_read' && $this->prop['vlv'] && !$this->group_id) {
- // ...either reading numSubOrdinates attribute
- if ($this->prop['numsub_filter'] && ($result_count = @$ns_function($this->conn, $this->base_dn, $this->prop['numsub_filter'], array('numSubOrdinates'), 0, 0, 0))) {
- $counts = ldap_get_entries($this->conn, $result_count);
- for ($this->vlv_count = $j = 0; $j < $counts['count']; $j++)
- $this->vlv_count += $counts[$j]['numsubordinates'][0];
- $this->_debug("D: total numsubordinates = " . $this->vlv_count);
- }
- else if (!function_exists('ldap_parse_virtuallist_control')) // ...or by fetching all records dn and count them
- $this->vlv_count = $this->_exec_search(true);
-
- $this->vlv_active = $this->_vlv_set_controls($this->prop, $this->list_page, $this->page_size);
- }
-
- // only fetch dn for count (should keep the payload low)
- $attrs = $count ? array('dn') : array_values($this->fieldmap);
- if ($this->ldap_result = @$function($this->conn, $this->base_dn, $filter,
- $attrs, 0, (int)$this->prop['sizelimit'], (int)$this->prop['timelimit'])
- ) {
- // when running on a patched PHP we can use the extended functions to retrieve the total count from the LDAP search result
- if ($this->vlv_active && function_exists('ldap_parse_virtuallist_control')) {
- if (ldap_parse_result($this->conn, $this->ldap_result,
- $errcode, $matcheddn, $errmsg, $referrals, $serverctrls)
- && $serverctrls // can be null e.g. in case of adm. limit error
- ) {
- ldap_parse_virtuallist_control($this->conn, $serverctrls,
- $last_offset, $this->vlv_count, $vresult);
- $this->_debug("S: VLV result: last_offset=$last_offset; content_count=$this->vlv_count");
- }
- else {
- $this->_debug("S: ".($errmsg ? $errmsg : ldap_error($this->conn)));
- }
- }
-
- $entries_count = ldap_count_entries($this->conn, $this->ldap_result);
- $this->_debug("S: $entries_count record(s)");
-
- return $count ? $entries_count : true;
- }
- else {
- $this->_debug("S: ".ldap_error($this->conn));
- }
- }
-
- return false;
- }
-
- /**
- * Choose the right PHP function according to scope property
- */
- private function _scope2func($scope, &$ns_function = null)
- {
- switch ($scope) {
- case 'sub':
- $function = $ns_function = 'ldap_search';
- break;
- case 'base':
- $function = $ns_function = 'ldap_read';
- break;
- default:
- $function = 'ldap_list';
- $ns_function = 'ldap_read';
- break;
- }
-
- return $function;
- }
-
- /**
- * Set server controls for Virtual List View (paginated listing)
- */
- private function _vlv_set_controls($prop, $list_page, $page_size, $search = null)
- {
- $sort_ctrl = array('oid' => "1.2.840.113556.1.4.473", 'value' => $this->_sort_ber_encode((array)$prop['sort']));
- $vlv_ctrl = array('oid' => "2.16.840.1.113730.3.4.9", 'value' => $this->_vlv_ber_encode(($offset = ($list_page-1) * $page_size + 1), $page_size, $search), 'iscritical' => true);
-
- $sort = (array)$prop['sort'];
- $this->_debug("C: set controls sort=" . join(' ', unpack('H'.(strlen($sort_ctrl['value'])*2), $sort_ctrl['value'])) . " ($sort[0]);"
- . " vlv=" . join(' ', (unpack('H'.(strlen($vlv_ctrl['value'])*2), $vlv_ctrl['value']))) . " ($offset/$page_size)");
-
- if (!ldap_set_option($this->conn, LDAP_OPT_SERVER_CONTROLS, array($sort_ctrl, $vlv_ctrl))) {
- $this->_debug("S: ".ldap_error($this->conn));
- $this->set_error(self::ERROR_SEARCH, 'vlvnotsupported');
- return false;
- }
-
- return true;
- }
-
/**
* Converts LDAP entry into an array
*/
private function _ldap2result($rec)
{
- $out = array();
+ $out = array('_type' => 'person');
+ $fieldmap = $this->fieldmap;
if ($rec['dn'])
$out[$this->primary_key] = self::dn_encode($rec['dn']);
- foreach ($this->fieldmap as $rf => $lf)
+ // determine record type
+ if (self::is_group_entry($rec)) {
+ $out['_type'] = 'group';
+ $out['readonly'] = true;
+ $fieldmap['name'] = $this->group_data['name_attr'] ? $this->group_data['name_attr'] : $this->prop['groups']['name_attr'];
+ }
+
+ foreach ($fieldmap as $rf => $lf)
{
for ($i=0; $i < $rec[$lf]['count']; $i++) {
if (!($value = $rec[$lf][$i]))
@@ -1607,8 +1417,10 @@ class rcube_ldap extends rcube_addressbook
if (is_array($colprop['serialized'])) {
foreach ($colprop['serialized'] as $subtype => $delim) {
$key = $col.':'.$subtype;
- foreach ((array)$save_cols[$key] as $i => $val)
- $save_cols[$key][$i] = join($delim, array($val['street'], $val['locality'], $val['zipcode'], $val['country']));
+ foreach ((array)$save_cols[$key] as $i => $val) {
+ $values = array($val['street'], $val['locality'], $val['zipcode'], $val['country']);
+ $save_cols[$key][$i] = count(array_filter($values)) ? join($delim, $values) : null;
+ }
}
}
}
@@ -1646,11 +1458,11 @@ class rcube_ldap extends rcube_addressbook
{
// list of known attribute aliases
static $aliases = array(
- 'gn' => 'givenname',
+ 'gn' => 'givenname',
'rfc822mailbox' => 'email',
- 'userid' => 'uid',
- 'emailaddress' => 'email',
- 'pkcs9email' => 'email',
+ 'userid' => 'uid',
+ 'emailaddress' => 'email',
+ 'pkcs9email' => 'email',
);
list($name, $limit) = explode(':', $namev, 2);
@@ -1659,6 +1471,15 @@ class rcube_ldap extends rcube_addressbook
return (isset($aliases[$name]) ? $aliases[$name] : $name) . $suffix;
}
+ /**
+ * Determines whether the given LDAP entry is a group record
+ */
+ private static function is_group_entry($entry)
+ {
+ $classes = array_map('strtolower', (array)$entry['objectclass']);
+
+ return count(array_intersect(array_keys(self::$group_types), $classes)) > 0;
+ }
/**
* Prints debug info to the log
@@ -1675,55 +1496,27 @@ class rcube_ldap extends rcube_addressbook
* Activate/deactivate debug mode
*
* @param boolean $dbg True if LDAP commands should be logged
- * @access public
*/
function set_debug($dbg = true)
{
$this->debug = $dbg;
- }
-
-
- /**
- * Quotes attribute value string
- *
- * @param string $str Attribute value
- * @param bool $dn True if the attribute is a DN
- *
- * @return string Quoted string
- */
- private static function _quote_string($str, $dn=false)
- {
- // take firt entry if array given
- if (is_array($str))
- $str = reset($str);
-
- if ($dn)
- $replace = array(','=>'\2c', '='=>'\3d', '+'=>'\2b', '<'=>'\3c',
- '>'=>'\3e', ';'=>'\3b', '\\'=>'\5c', '"'=>'\22', '#'=>'\23');
- else
- $replace = array('*'=>'\2a', '('=>'\28', ')'=>'\29', '\\'=>'\5c',
- '/'=>'\2f');
- return strtr($str, $replace);
+ if ($this->ldap) {
+ $this->ldap->set_debug($dbg);
+ }
}
/**
* Setter for the current group
- * (empty, has to be re-implemented by extending class)
*/
function set_group($group_id)
{
- if ($group_id)
- {
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
-
+ if ($group_id) {
$this->group_id = $group_id;
- $this->group_data = $group_cache[$group_id];
+ $this->group_data = $this->get_group_entry($group_id);
}
- else
- {
+ else {
$this->group_id = 0;
$this->group_data = null;
}
@@ -1742,15 +1535,13 @@ class rcube_ldap extends rcube_addressbook
*/
function list_groups($search = null, $mode = 0)
{
- if (!$this->groups)
+ if (!$this->groups) {
return array();
+ }
- // use cached list for searching
- $this->cache->expunge();
- if (!$search || ($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
+ $group_cache = $this->_fetch_groups();
+ $groups = array();
- $groups = array();
if ($search) {
foreach ($group_cache as $group) {
if ($this->compare_search_value('name', $group['name'], $search, $mode)) {
@@ -1758,8 +1549,9 @@ class rcube_ldap extends rcube_addressbook
}
}
}
- else
+ else {
$groups = $group_cache;
+ }
return array_values($groups);
}
@@ -1767,80 +1559,139 @@ class rcube_ldap extends rcube_addressbook
/**
* Fetch groups from server
*/
- private function _fetch_groups($vlv_page = 0)
+ private function _fetch_groups($vlv_page = null)
{
- $base_dn = $this->groups_base_dn;
- $filter = $this->prop['groups']['filter'];
- $name_attr = $this->prop['groups']['name_attr'];
+ // special case: list groups from 'group_filters' config
+ if ($vlv_page === null && !empty($this->prop['group_filters'])) {
+ $groups = array();
+
+ // list regular groups configuration as special filter
+ if (!empty($this->prop['groups']['filter'])) {
+ $id = '__groups__';
+ $groups[$id] = array('ID' => $id, 'name' => rcube_label('groups'), 'virtual' => true) + $this->prop['groups'];
+ }
+
+ foreach ($this->prop['group_filters'] as $id => $prop) {
+ $groups[$id] = $prop + array('ID' => $id, 'name' => ucfirst($id), 'virtual' => true, 'base_dn' => $this->base_dn);
+ }
+
+ return $groups;
+ }
+
+ if ($this->cache && $vlv_page === null && ($groups = $this->cache->get('groups')) !== null) {
+ return $groups;
+ }
+
+ $base_dn = $this->groups_base_dn;
+ $filter = $this->prop['groups']['filter'];
+ $name_attr = $this->prop['groups']['name_attr'];
$email_attr = $this->prop['groups']['email_attr'] ? $this->prop['groups']['email_attr'] : 'mail';
$sort_attrs = $this->prop['groups']['sort'] ? (array)$this->prop['groups']['sort'] : array($name_attr);
- $sort_attr = $sort_attrs[0];
+ $sort_attr = $sort_attrs[0];
- $this->_debug("C: Search [$filter][dn: $base_dn]");
+ $ldap = $this->ldap;
// use vlv to list groups
if ($this->prop['groups']['vlv']) {
$page_size = 200;
- if (!$this->prop['groups']['sort'])
+ if (!$this->prop['groups']['sort']) {
$this->prop['groups']['sort'] = $sort_attrs;
- $vlv_active = $this->_vlv_set_controls($this->prop['groups'], $vlv_page+1, $page_size);
+ }
+
+ $ldap = clone $this->ldap;
+ $ldap->set_config($this->prop['groups']);
+ $ldap->set_vlv_page($vlv_page+1, $page_size);
}
- $function = $this->_scope2func($this->prop['groups']['scope']);
- $res = @$function($this->conn, $base_dn, $filter, array_unique(array('dn', 'objectClass', $name_attr, $email_attr, $sort_attr)));
- if ($res === false)
- {
- $this->_debug("S: ".ldap_error($this->conn));
+ $attrs = array_unique(array('dn', 'objectClass', $name_attr, $email_attr, $sort_attr));
+ $ldap_data = $ldap->search($base_dn, $filter, $this->prop['groups']['scope'], $attrs, $this->prop['groups']);
+
+ if ($ldap_data === false) {
return array();
}
- $ldap_data = ldap_get_entries($this->conn, $res);
- $this->_debug("S: ".ldap_count_entries($this->conn, $res)." record(s)");
-
- $groups = array();
+ $groups = array();
$group_sortnames = array();
- $group_count = $ldap_data["count"];
- for ($i=0; $i < $group_count; $i++)
- {
- $group_name = is_array($ldap_data[$i][$name_attr]) ? $ldap_data[$i][$name_attr][0] : $ldap_data[$i][$name_attr];
- $group_id = self::dn_encode($group_name);
+ $group_count = $ldap_data->count();
+
+ foreach ($ldap_data as $entry) {
+ if (!$entry['dn']) // DN is mandatory
+ $entry['dn'] = $ldap_data->get_dn();
+
+ $group_name = is_array($entry[$name_attr]) ? $entry[$name_attr][0] : $entry[$name_attr];
+ $group_id = self::dn_encode($entry['dn']);
$groups[$group_id]['ID'] = $group_id;
- $groups[$group_id]['dn'] = $ldap_data[$i]['dn'];
+ $groups[$group_id]['dn'] = $entry['dn'];
$groups[$group_id]['name'] = $group_name;
- $groups[$group_id]['member_attr'] = $this->get_group_member_attr($ldap_data[$i]['objectclass']);
+ $groups[$group_id]['member_attr'] = $this->get_group_member_attr($entry['objectclass']);
// list email attributes of a group
- for ($j=0; $ldap_data[$i][$email_attr] && $j < $ldap_data[$i][$email_attr]['count']; $j++) {
- if (strpos($ldap_data[$i][$email_attr][$j], '@') > 0)
- $groups[$group_id]['email'][] = $ldap_data[$i][$email_attr][$j];
+ for ($j=0; $entry[$email_attr] && $j < $entry[$email_attr]['count']; $j++) {
+ if (strpos($entry[$email_attr][$j], '@') > 0)
+ $groups[$group_id]['email'][] = $entry[$email_attr][$j];
}
- $group_sortnames[] = mb_strtolower($ldap_data[$i][$sort_attr][0]);
+ $group_sortnames[] = mb_strtolower($entry[$sort_attr][0]);
}
// recursive call can exit here
- if ($vlv_page > 0)
+ if ($vlv_page > 0) {
return $groups;
+ }
// call recursively until we have fetched all groups
- while ($vlv_active && $group_count == $page_size)
- {
- $next_page = $this->_fetch_groups(++$vlv_page);
- $groups = array_merge($groups, $next_page);
+ while ($this->prop['groups']['vlv'] && $group_count == $page_size) {
+ $next_page = $this->_fetch_groups(++$vlv_page);
+ $groups = array_merge($groups, $next_page);
$group_count = count($next_page);
}
// when using VLV the list of groups is already sorted
- if (!$this->prop['groups']['vlv'])
+ if (!$this->prop['groups']['vlv']) {
array_multisort($group_sortnames, SORT_ASC, SORT_STRING, $groups);
+ }
// cache this
- $this->cache->set('groups', $groups);
+ if ($this->cache) {
+ $this->cache->set('groups', $groups);
+ }
return $groups;
}
/**
+ * Fetch a group entry from LDAP and save in local cache
+ */
+ private function get_group_entry($group_id)
+ {
+ $group_cache = $this->_fetch_groups();
+
+ // add group record to cache if it isn't yet there
+ if (!isset($group_cache[$group_id])) {
+ $name_attr = $this->prop['groups']['name_attr'];
+ $dn = self::dn_decode($group_id);
+
+ if ($list = $this->ldap->read_entries($dn, '(objectClass=*)', array('dn','objectClass','member','uniqueMember','memberURL',$name_attr,$this->fieldmap['email']))) {
+ $entry = $list[0];
+ $group_name = is_array($entry[$name_attr]) ? $entry[$name_attr][0] : $entry[$name_attr];
+ $group_cache[$group_id]['ID'] = $group_id;
+ $group_cache[$group_id]['dn'] = $dn;
+ $group_cache[$group_id]['name'] = $group_name;
+ $group_cache[$group_id]['member_attr'] = $this->get_group_member_attr($entry['objectclass']);
+ }
+ else {
+ $group_cache[$group_id] = false;
+ }
+
+ if ($this->cache) {
+ $this->cache->set('groups', $group_cache);
+ }
+ }
+
+ return $group_cache[$group_id];
+ }
+
+ /**
* Get group properties such as name and email address(es)
*
* @param string Group identifier
@@ -1848,10 +1699,7 @@ class rcube_ldap extends rcube_addressbook
*/
function get_group($group_id)
{
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
-
- $group_data = $group_cache[$group_id];
+ $group_data = $this->get_group_entry($group_id);
unset($group_data['dn'], $group_data['member_attr']);
return $group_data;
@@ -1865,24 +1713,24 @@ class rcube_ldap extends rcube_addressbook
*/
function create_group($group_name)
{
- $base_dn = $this->groups_base_dn;
- $new_dn = "cn=$group_name,$base_dn";
- $new_gid = self::dn_encode($group_name);
+ $new_dn = 'cn=' . rcube_ldap_generic::quote_string($group_name, true) . ',' . $this->groups_base_dn;
+ $new_gid = self::dn_encode($new_dn);
$member_attr = $this->get_group_member_attr();
- $name_attr = $this->prop['groups']['name_attr'] ? $this->prop['groups']['name_attr'] : 'cn';
-
- $new_entry = array(
+ $name_attr = $this->prop['groups']['name_attr'] ? $this->prop['groups']['name_attr'] : 'cn';
+ $new_entry = array(
'objectClass' => $this->prop['groups']['object_classes'],
$name_attr => $group_name,
$member_attr => '',
);
- if (!$this->ldap_add($new_dn, $new_entry)) {
+ if (!$this->ldap->add($new_dn, $new_entry)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ $this->cache->remove('groups');
+ }
return array('id' => $new_gid, 'name' => $group_name);
}
@@ -1895,19 +1743,18 @@ class rcube_ldap extends rcube_addressbook
*/
function delete_group($group_id)
{
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
-
- $base_dn = $this->groups_base_dn;
- $group_name = $group_cache[$group_id]['name'];
- $del_dn = "cn=$group_name,$base_dn";
+ $group_cache = $this->_fetch_groups();
+ $del_dn = $group_cache[$group_id]['dn'];
- if (!$this->ldap_delete($del_dn)) {
+ if (!$this->ldap->delete($del_dn)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ unset($group_cache[$group_id]);
+ $this->cache->set('groups', $group_cache);
+ }
return true;
}
@@ -1922,21 +1769,19 @@ class rcube_ldap extends rcube_addressbook
*/
function rename_group($group_id, $new_name, &$new_gid)
{
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
+ $group_cache = $this->_fetch_groups();
+ $old_dn = $group_cache[$group_id]['dn'];
+ $new_rdn = "cn=" . rcube_ldap_generic::quote_string($new_name, true);
+ $new_gid = self::dn_encode($new_rdn . ',' . $this->groups_base_dn);
- $base_dn = $this->groups_base_dn;
- $group_name = $group_cache[$group_id]['name'];
- $old_dn = "cn=$group_name,$base_dn";
- $new_rdn = "cn=$new_name";
- $new_gid = self::dn_encode($new_name);
-
- if (!$this->ldap_rename($old_dn, $new_rdn, null, true)) {
+ if (!$this->ldap->rename($old_dn, $new_rdn, null, true)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return false;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ $this->cache->remove('groups');
+ }
return $new_name;
}
@@ -1951,27 +1796,27 @@ class rcube_ldap extends rcube_addressbook
*/
function add_to_group($group_id, $contact_ids)
{
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
-
- if (!is_array($contact_ids))
- $contact_ids = explode(',', $contact_ids);
-
- $base_dn = $this->groups_base_dn;
- $group_name = $group_cache[$group_id]['name'];
+ $group_cache = $this->_fetch_groups();
$member_attr = $group_cache[$group_id]['member_attr'];
- $group_dn = "cn=$group_name,$base_dn";
+ $group_dn = $group_cache[$group_id]['dn'];
$new_attrs = array();
- foreach ($contact_ids as $id)
+ if (!is_array($contact_ids)) {
+ $contact_ids = explode(',', $contact_ids);
+ }
+
+ foreach ($contact_ids as $id) {
$new_attrs[$member_attr][] = self::dn_decode($id);
+ }
- if (!$this->ldap_mod_add($group_dn, $new_attrs)) {
+ if (!$this->ldap->mod_add($group_dn, $new_attrs)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return 0;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ $this->cache->remove('groups');
+ }
return count($new_attrs[$member_attr]);
}
@@ -1986,27 +1831,27 @@ class rcube_ldap extends rcube_addressbook
*/
function remove_from_group($group_id, $contact_ids)
{
- if (($group_cache = $this->cache->get('groups')) === null)
- $group_cache = $this->_fetch_groups();
-
- if (!is_array($contact_ids))
- $contact_ids = explode(',', $contact_ids);
-
- $base_dn = $this->groups_base_dn;
- $group_name = $group_cache[$group_id]['name'];
+ $group_cache = $this->_fetch_groups();
$member_attr = $group_cache[$group_id]['member_attr'];
- $group_dn = "cn=$group_name,$base_dn";
+ $group_dn = $group_cache[$group_id]['dn'];
$del_attrs = array();
- foreach ($contact_ids as $id)
+ if (!is_array($contact_ids)) {
+ $contact_ids = explode(',', $contact_ids);
+ }
+
+ foreach ($contact_ids as $id) {
$del_attrs[$member_attr][] = self::dn_decode($id);
+ }
- if (!$this->ldap_mod_del($group_dn, $del_attrs)) {
+ if (!$this->ldap->mod_del($group_dn, $del_attrs)) {
$this->set_error(self::ERROR_SAVING, 'errorsaving');
return 0;
}
- $this->cache->remove('groups');
+ if ($this->cache) {
+ $this->cache->remove('groups');
+ }
return count($del_attrs[$member_attr]);
}
@@ -2021,206 +1866,63 @@ class rcube_ldap extends rcube_addressbook
*/
function get_record_groups($contact_id)
{
- if (!$this->groups)
+ if (!$this->groups) {
return array();
+ }
$base_dn = $this->groups_base_dn;
$contact_dn = self::dn_decode($contact_id);
$name_attr = $this->prop['groups']['name_attr'] ? $this->prop['groups']['name_attr'] : 'cn';
$member_attr = $this->get_group_member_attr();
$add_filter = '';
+
if ($member_attr != 'member' && $member_attr != 'uniqueMember')
$add_filter = "($member_attr=$contact_dn)";
$filter = strtr("(|(member=$contact_dn)(uniqueMember=$contact_dn)$add_filter)", array('\\' => '\\\\'));
- $this->_debug("C: Search [$filter][dn: $base_dn]");
-
- $res = @ldap_search($this->conn, $base_dn, $filter, array($name_attr));
- if ($res === false)
- {
- $this->_debug("S: ".ldap_error($this->conn));
+ $ldap_data = $this->ldap->search($base_dn, $filter, 'sub', array('dn', $name_attr));
+ if ($res === false) {
return array();
}
- $ldap_data = ldap_get_entries($this->conn, $res);
- $this->_debug("S: ".ldap_count_entries($this->conn, $res)." record(s)");
$groups = array();
- for ($i=0; $i<$ldap_data["count"]; $i++)
- {
- $group_name = $ldap_data[$i][$name_attr][0];
- $group_id = self::dn_encode($group_name);
- $groups[$group_id] = $group_id;
+ foreach ($ldap_data as $entry) {
+ if (!$entry['dn'])
+ $entry['dn'] = $ldap_data->get_dn();
+ $group_name = $entry[$name_attr][0];
+ $group_id = self::dn_encode($entry['dn']);
+ $groups[$group_id] = $group_name;
}
+
return $groups;
}
/**
* Detects group member attribute name
*/
- private function get_group_member_attr($object_classes = array())
+ private function get_group_member_attr($object_classes = array(), $default = 'member')
{
if (empty($object_classes)) {
$object_classes = $this->prop['groups']['object_classes'];
}
+
if (!empty($object_classes)) {
foreach ((array)$object_classes as $oc) {
- switch (strtolower($oc)) {
- case 'group':
- case 'groupofnames':
- case 'kolabgroupofnames':
- $member_attr = 'member';
- break;
-
- case 'groupofuniquenames':
- case 'kolabgroupofuniquenames':
- $member_attr = 'uniqueMember';
- break;
+ if ($attr = self::$group_types[strtolower($oc)]) {
+ return $attr;
}
}
}
- if (!empty($member_attr)) {
- return $member_attr;
- }
-
if (!empty($this->prop['groups']['member_attr'])) {
return $this->prop['groups']['member_attr'];
}
- return 'member';
+ return $default;
}
/**
- * Generate BER encoded string for Virtual List View option
- *
- * @param integer List offset (first record)
- * @param integer Records per page
- * @return string BER encoded option value
- */
- private function _vlv_ber_encode($offset, $rpp, $search = '')
- {
- # this string is ber-encoded, php will prefix this value with:
- # 04 (octet string) and 10 (length of 16 bytes)
- # the code behind this string is broken down as follows:
- # 30 = ber sequence with a length of 0e (14) bytes following
- # 02 = type integer (in two's complement form) with 2 bytes following (beforeCount): 01 00 (ie 0)
- # 02 = type integer (in two's complement form) with 2 bytes following (afterCount): 01 18 (ie 25-1=24)
- # a0 = type context-specific/constructed with a length of 06 (6) bytes following
- # 02 = type integer with 2 bytes following (offset): 01 01 (ie 1)
- # 02 = type integer with 2 bytes following (contentCount): 01 00
-
- # whith a search string present:
- # 81 = type context-specific/constructed with a length of 04 (4) bytes following (the length will change here)
- # 81 indicates a user string is present where as a a0 indicates just a offset search
- # 81 = type context-specific/constructed with a length of 06 (6) bytes following
-
- # the following info was taken from the ISO/IEC 8825-1:2003 x.690 standard re: the
- # encoding of integer values (note: these values are in
- # two-complement form so since offset will never be negative bit 8 of the
- # leftmost octet should never by set to 1):
- # 8.3.2: If the contents octets of an integer value encoding consist
- # of more than one octet, then the bits of the first octet (rightmost) and bit 8
- # of the second (to the left of first octet) octet:
- # a) shall not all be ones; and
- # b) shall not all be zero
-
- if ($search)
- {
- $search = preg_replace('/[^-[:alpha:] ,.()0-9]+/', '', $search);
- $ber_val = self::_string2hex($search);
- $str = self::_ber_addseq($ber_val, '81');
- }
- else
- {
- # construct the string from right to left
- $str = "020100"; # contentCount
-
- $ber_val = self::_ber_encode_int($offset); // returns encoded integer value in hex format
-
- // calculate octet length of $ber_val
- $str = self::_ber_addseq($ber_val, '02') . $str;
-
- // now compute length over $str
- $str = self::_ber_addseq($str, 'a0');
- }
-
- // now tack on records per page
- $str = "020100" . self::_ber_addseq(self::_ber_encode_int($rpp-1), '02') . $str;
-
- // now tack on sequence identifier and length
- $str = self::_ber_addseq($str, '30');
-
- return pack('H'.strlen($str), $str);
- }
-
-
- /**
- * create ber encoding for sort control
- *
- * @param array List of cols to sort by
- * @return string BER encoded option value
- */
- private function _sort_ber_encode($sortcols)
- {
- $str = '';
- foreach (array_reverse((array)$sortcols) as $col) {
- $ber_val = self::_string2hex($col);
-
- # 30 = ber sequence with a length of octet value
- # 04 = octet string with a length of the ascii value
- $oct = self::_ber_addseq($ber_val, '04');
- $str = self::_ber_addseq($oct, '30') . $str;
- }
-
- // now tack on sequence identifier and length
- $str = self::_ber_addseq($str, '30');
-
- return pack('H'.strlen($str), $str);
- }
-
- /**
- * Add BER sequence with correct length and the given identifier
- */
- private static function _ber_addseq($str, $identifier)
- {
- $len = dechex(strlen($str)/2);
- if (strlen($len) % 2 != 0)
- $len = '0'.$len;
-
- return $identifier . $len . $str;
- }
-
- /**
- * Returns BER encoded integer value in hex format
- */
- private static function _ber_encode_int($offset)
- {
- $val = dechex($offset);
- $prefix = '';
-
- // check if bit 8 of high byte is 1
- if (preg_match('/^[89abcdef]/', $val))
- $prefix = '00';
-
- if (strlen($val)%2 != 0)
- $prefix .= '0';
-
- return $prefix . $val;
- }
-
- /**
- * Returns ascii string encoded in hex
- */
- private static function _string2hex($str)
- {
- $hex = '';
- for ($i=0; $i < strlen($str); $i++)
- $hex .= dechex(ord($str[$i]));
- return $hex;
- }
-
- /**
* HTML-safe DN string encoding
*
* @param string $str DN string
@@ -2247,130 +1949,4 @@ class rcube_ldap extends rcube_addressbook
return base64_decode($str);
}
- /**
- * Wrapper for ldap_add()
- */
- protected function ldap_add($dn, $entry)
- {
- $this->_debug("C: Add [dn: $dn]: ".print_r($entry, true));
-
- $res = ldap_add($this->conn, $dn, $entry);
- if ($res === false) {
- $this->_debug("S: ".ldap_error($this->conn));
- return false;
- }
-
- $this->_debug("S: OK");
- return true;
- }
-
- /**
- * Wrapper for ldap_delete()
- */
- protected function ldap_delete($dn)
- {
- $this->_debug("C: Delete [dn: $dn]");
-
- $res = ldap_delete($this->conn, $dn);
- if ($res === false) {
- $this->_debug("S: ".ldap_error($this->conn));
- return false;
- }
-
- $this->_debug("S: OK");
- return true;
- }
-
- /**
- * Wrapper for ldap_mod_replace()
- */
- protected function ldap_mod_replace($dn, $entry)
- {
- $this->_debug("C: Replace [dn: $dn]: ".print_r($entry, true));
-
- if (!ldap_mod_replace($this->conn, $dn, $entry)) {
- $this->_debug("S: ".ldap_error($this->conn));
- return false;
- }
-
- $this->_debug("S: OK");
- return true;
- }
-
- /**
- * Wrapper for ldap_mod_add()
- */
- protected function ldap_mod_add($dn, $entry)
- {
- $this->_debug("C: Add [dn: $dn]: ".print_r($entry, true));
-
- if (!ldap_mod_add($this->conn, $dn, $entry)) {
- $this->_debug("S: ".ldap_error($this->conn));
- return false;
- }
-
- $this->_debug("S: OK");
- return true;
- }
-
- /**
- * Wrapper for ldap_mod_del()
- */
- protected function ldap_mod_del($dn, $entry)
- {
- $this->_debug("C: Delete [dn: $dn]: ".print_r($entry, true));
-
- if (!ldap_mod_del($this->conn, $dn, $entry)) {
- $this->_debug("S: ".ldap_error($this->conn));
- return false;
- }
-
- $this->_debug("S: OK");
- return true;
- }
-
- /**
- * Wrapper for ldap_rename()
- */
- protected function ldap_rename($dn, $newrdn, $newparent = null, $deleteoldrdn = true)
- {
- $this->_debug("C: Rename [dn: $dn] [dn: $newrdn]");
-
- if (!ldap_rename($this->conn, $dn, $newrdn, $newparent, $deleteoldrdn)) {
- $this->_debug("S: ".ldap_error($this->conn));
- return false;
- }
-
- $this->_debug("S: OK");
- return true;
- }
-
- /**
- * Wrapper for ldap_list()
- */
- protected function ldap_list($dn, $filter, $attrs = array(''))
- {
- $list = array();
- $this->_debug("C: List [dn: $dn] [{$filter}]");
-
- if ($result = ldap_list($this->conn, $dn, $filter, $attrs)) {
- $list = ldap_get_entries($this->conn, $result);
-
- if ($list === false) {
- $this->_debug("S: ".ldap_error($this->conn));
- return array();
- }
-
- $count = $list['count'];
- unset($list['count']);
-
- $this->_debug("S: $count record(s)");
- }
- else {
- $this->_debug("S: ".ldap_error($this->conn));
- }
-
- return $list;
- }
-
}
diff --git a/program/lib/Roundcube/rcube_ldap_generic.php b/program/lib/Roundcube/rcube_ldap_generic.php
new file mode 100644
index 000000000..88378dc22
--- /dev/null
+++ b/program/lib/Roundcube/rcube_ldap_generic.php
@@ -0,0 +1,1049 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | Roundcube/rcube_ldap_generic.php |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2006-2013, The Roundcube Dev Team |
+ | Copyright (C) 2012-2013, Kolab Systems AG |
+ | |
+ | 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: |
+ | Provide basic functionality for accessing LDAP directories |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Aleksander Machniak <machniak@kolabsys.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+/*
+ LDAP connection properties
+ --------------------------
+
+ $prop = array(
+ 'host' => '<ldap-server-address>',
+ // or
+ 'hosts' => array('directory.verisign.com'),
+ 'port' => 389,
+ 'use_tls' => true|false,
+ 'ldap_version' => 3, // using LDAPv3
+ 'auth_method' => '', // SASL authentication method (for proxy auth), e.g. DIGEST-MD5
+ 'attributes' => array('dn'), // List of attributes to read from the server
+ 'vlv' => false, // Enable Virtual List View to more efficiently fetch paginated data (if server supports it)
+ 'config_root_dn' => 'cn=config', // Root DN to read config (e.g. vlv indexes) from
+ 'numsub_filter' => '(objectClass=organizationalUnit)', // with VLV, we also use numSubOrdinates to query the total number of records. Set this filter to get all numSubOrdinates attributes for counting
+ 'sizelimit' => '0', // Enables you to limit the count of entries fetched. Setting this to 0 means no limit.
+ 'timelimit' => '0', // Sets the number of seconds how long is spend on the search. Setting this to 0 means no limit.
+ 'network_timeout' => 10, // The timeout (in seconds) for connect + bind arrempts. This is only supported in PHP >= 5.3.0 with OpenLDAP 2.x
+ 'referrals' => true|false, // Sets the LDAP_OPT_REFERRALS option. Mostly used in multi-domain Active Directory setups
+ );
+*/
+
+/**
+ * Model class to access an LDAP directories
+ *
+ * @package Framework
+ * @subpackage LDAP
+ */
+class rcube_ldap_generic
+{
+ const UPDATE_MOD_ADD = 1;
+ const UPDATE_MOD_DELETE = 2;
+ const UPDATE_MOD_REPLACE = 4;
+ const UPDATE_MOD_FULL = 7;
+
+ public $conn;
+ public $vlv_active = false;
+
+ /** private properties */
+ protected $cache = null;
+ protected $config = array();
+ protected $attributes = array('dn');
+ protected $entries = null;
+ protected $result = null;
+ protected $debug = false;
+ protected $list_page = 1;
+ protected $page_size = 10;
+ protected $vlv_config = null;
+
+
+ /**
+ * Object constructor
+ *
+ * @param array $p LDAP connection properties
+ */
+ function __construct($p)
+ {
+ $this->config = $p;
+
+ if (is_array($p['attributes']))
+ $this->attributes = $p['attributes'];
+
+ if (!is_array($p['hosts']) && !empty($p['host']))
+ $this->config['hosts'] = array($p['host']);
+ }
+
+ /**
+ * Activate/deactivate debug mode
+ *
+ * @param boolean $dbg True if LDAP commands should be logged
+ */
+ public function set_debug($dbg = true)
+ {
+ $this->debug = $dbg;
+ }
+
+ /**
+ * Set connection options
+ *
+ * @param mixed $opt Option name as string or hash array with multiple options
+ * @param mixed $val Option value
+ */
+ public function set_config($opt, $val = null)
+ {
+ if (is_array($opt))
+ $this->config = array_merge($this->config, $opt);
+ else
+ $this->config[$opt] = $value;
+ }
+
+ /**
+ * Enable caching by passing an instance of rcube_cache to be used by this object
+ *
+ * @param object rcube_cache Instance or False to disable caching
+ */
+ public function set_cache($cache_engine)
+ {
+ $this->cache = $cache_engine;
+ }
+
+ /**
+ * Set properties for VLV-based paging
+ *
+ * @param number $page Page number to list (starting at 1)
+ * @param number $size Number of entries to display on one page
+ */
+ public function set_vlv_page($page, $size = 10)
+ {
+ $this->list_page = $page;
+ $this->page_size = $size;
+ }
+
+ /**
+ * Establish a connection to the LDAP server
+ */
+ public function connect($host = null)
+ {
+ if (!function_exists('ldap_connect')) {
+ rcube::raise_error(array('code' => 100, 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "No ldap support in this installation of PHP"),
+ true);
+ return false;
+ }
+
+ if (is_resource($this->conn) && $this->config['host'] == $host)
+ return true;
+
+ if (empty($this->config['ldap_version']))
+ $this->config['ldap_version'] = 3;
+
+ // iterate over hosts if none specified
+ if (!$host) {
+ if (!is_array($this->config['hosts']))
+ $this->config['hosts'] = array($this->config['hosts']);
+
+ foreach ($this->config['hosts'] as $host) {
+ if ($this->connect($host)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ // open connection to the given $host
+ $host = rcube_utils::idn_to_ascii(rcube_utils::parse_host($host));
+ $hostname = $host . ($this->config['port'] ? ':'.$this->config['port'] : '');
+
+ $this->_debug("C: Connect to $hostname [{$this->config['name']}]");
+
+ if ($lc = @ldap_connect($host, $this->config['port'])) {
+ if ($this->config['use_tls'] === true)
+ if (!ldap_start_tls($lc))
+ continue;
+
+ $this->_debug("S: OK");
+
+ ldap_set_option($lc, LDAP_OPT_PROTOCOL_VERSION, $this->config['ldap_version']);
+ $this->config['host'] = $host;
+ $this->conn = $lc;
+
+ if (!empty($this->config['network_timeout']))
+ ldap_set_option($lc, LDAP_OPT_NETWORK_TIMEOUT, $this->config['network_timeout']);
+
+ if (isset($this->config['referrals']))
+ ldap_set_option($lc, LDAP_OPT_REFERRALS, $this->config['referrals']);
+ }
+ else {
+ $this->_debug("S: NOT OK");
+ }
+
+ if (!is_resource($this->conn)) {
+ rcube::raise_error(array('code' => 100, 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Could not connect to any LDAP server, last tried $hostname"),
+ true);
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Bind connection with (SASL-) user and password
+ *
+ * @param string $authc Authentication user
+ * @param string $pass Bind password
+ * @param string $authz Autorization user
+ *
+ * @return boolean True on success, False on error
+ */
+ public function sasl_bind($authc, $pass, $authz=null)
+ {
+ if (!$this->conn) {
+ return false;
+ }
+
+ if (!function_exists('ldap_sasl_bind')) {
+ rcube::raise_error(array('code' => 100, 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Unable to bind: ldap_sasl_bind() not exists"),
+ true);
+ return false;
+ }
+
+ if (!empty($authz)) {
+ $authz = 'u:' . $authz;
+ }
+
+ if (!empty($this->config['auth_method'])) {
+ $method = $this->config['auth_method'];
+ }
+ else {
+ $method = 'DIGEST-MD5';
+ }
+
+ $this->_debug("C: SASL Bind [mech: $method, authc: $authc, authz: $authz, pass: $pass]");
+
+ if (ldap_sasl_bind($this->conn, NULL, $pass, $method, NULL, $authc, $authz)) {
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ $this->_debug("S: ".ldap_error($this->conn));
+
+ rcube::raise_error(array(
+ 'code' => ldap_errno($this->conn), 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "SASL Bind failed for authcid=$authc ".ldap_error($this->conn)),
+ true);
+ return false;
+ }
+
+ /**
+ * Bind connection with DN and password
+ *
+ * @param string $dn Bind DN
+ * @param string $pass Bind password
+ *
+ * @return boolean True on success, False on error
+ */
+ public function bind($dn, $pass)
+ {
+ if (!$this->conn) {
+ return false;
+ }
+
+ $this->_debug("C: Bind $dn [pass: $pass]");
+
+ if (@ldap_bind($this->conn, $dn, $pass)) {
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ $this->_debug("S: ".ldap_error($this->conn));
+
+ rcube::raise_error(array(
+ 'code' => ldap_errno($this->conn), 'type' => 'ldap',
+ 'file' => __FILE__, 'line' => __LINE__,
+ 'message' => "Bind failed for dn=$dn: ".ldap_error($this->conn)),
+ true);
+
+ return false;
+ }
+
+ /**
+ * Close connection to LDAP server
+ */
+ public function close()
+ {
+ if ($this->conn) {
+ $this->_debug("C: Close");
+ ldap_unbind($this->conn);
+ $this->conn = null;
+ }
+ }
+
+ /**
+ * Return the last result set
+ *
+ * @return object rcube_ldap_result Result object
+ */
+ function get_result()
+ {
+ return $this->result;
+ }
+
+ /**
+ * Get a specific LDAP entry, identified by its DN
+ *
+ * @param string $dn Record identifier
+ * @return array Hash array
+ */
+ function get_entry($dn)
+ {
+ $rec = null;
+
+ if ($this->conn && $dn) {
+ $this->_debug("C: Read $dn [(objectclass=*)]");
+
+ if ($ldap_result = @ldap_read($this->conn, $dn, '(objectclass=*)', $this->attributes)) {
+ $this->_debug("S: OK");
+
+ if ($entry = ldap_first_entry($this->conn, $ldap_result)) {
+ $rec = ldap_get_attributes($this->conn, $entry);
+ }
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ }
+
+ if (!empty($rec)) {
+ $rec['dn'] = $dn; // Add in the dn for the entry.
+ }
+ }
+
+ return $rec;
+ }
+
+ /**
+ * Execute the LDAP search based on the stored credentials
+ *
+ * @param string $base_dn The base DN to query
+ * @param string $filter The LDAP filter for search
+ * @param string $scope The LDAP scope (list|sub|base)
+ * @param array $attrs List of entry attributes to read
+ * @param array $prop Hash array with query configuration properties:
+ * - sort: array of sort attributes (has to be in sync with the VLV index)
+ * - search: search string used for VLV controls
+ * @param boolean $count_only Set to true if only entry count is requested
+ *
+ * @return mixed rcube_ldap_result object or number of entries (if count_only=true) or false on error
+ */
+ public function search($base_dn, $filter = '', $scope = 'sub', $attrs = array('dn'), $prop = array(), $count_only = false)
+ {
+ if (!$this->conn) {
+ return false;
+ }
+
+ if (empty($filter)) {
+ $filter = '(objectclass=*)';
+ }
+
+ $this->_debug("C: Search $base_dn for $filter");
+
+ $function = self::scope2func($scope, $ns_function);
+
+ // find available VLV index for this query
+ if (!$count_only && ($vlv_sort = $this->_find_vlv($base_dn, $filter, $scope, $prop['sort']))) {
+ // when using VLV, we get the total count by...
+ // ...either reading numSubOrdinates attribute
+ if (($sub_filter = $this->config['numsub_filter']) &&
+ ($result_count = @$ns_function($this->conn, $base_dn, $sub_filter, array('numSubOrdinates'), 0, 0, 0))
+ ) {
+ $counts = ldap_get_entries($this->conn, $result_count);
+ for ($vlv_count = $j = 0; $j < $counts['count']; $j++)
+ $vlv_count += $counts[$j]['numsubordinates'][0];
+ $this->_debug("D: total numsubordinates = " . $vlv_count);
+ }
+ // ...or by fetching all records dn and count them
+ else if (!function_exists('ldap_parse_virtuallist_control')) {
+ $vlv_count = $this->search($base_dn, $filter, $scope, array('dn'), $prop, true);
+ }
+
+ $this->vlv_active = $this->_vlv_set_controls($vlv_sort, $this->list_page, $this->page_size, $prop['search']);
+ }
+ else {
+ $this->vlv_active = false;
+ }
+
+ // only fetch dn for count (should keep the payload low)
+ if ($ldap_result = @$function($this->conn, $base_dn, $filter,
+ $attrs, 0, (int)$this->config['sizelimit'], (int)$this->config['timelimit'])
+ ) {
+ // when running on a patched PHP we can use the extended functions
+ // to retrieve the total count from the LDAP search result
+ if ($this->vlv_active && function_exists('ldap_parse_virtuallist_control')) {
+ if (ldap_parse_result($this->conn, $ldap_result, $errcode, $matcheddn, $errmsg, $referrals, $serverctrls)) {
+ ldap_parse_virtuallist_control($this->conn, $serverctrls, $last_offset, $vlv_count, $vresult);
+ $this->_debug("S: VLV result: last_offset=$last_offset; content_count=$vlv_count");
+ }
+ else {
+ $this->_debug("S: ".($errmsg ? $errmsg : ldap_error($this->conn)));
+ }
+ }
+ else if ($this->debug) {
+ $this->_debug("S: ".ldap_count_entries($this->conn, $ldap_result)." record(s) found");
+ }
+
+ $this->result = new rcube_ldap_result($this->conn, $ldap_result, $base_dn, $filter, $vlv_count);
+
+ return $count_only ? $this->result->count() : $this->result;
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ }
+
+ return false;
+ }
+
+ /**
+ * Modify an LDAP entry on the server
+ *
+ * @param string $dn Entry DN
+ * @param array $params Hash array of entry attributes
+ * @param int $mode Update mode (UPDATE_MOD_ADD | UPDATE_MOD_DELETE | UPDATE_MOD_REPLACE)
+ */
+ public function modify($dn, $parms, $mode = 255)
+ {
+ // TODO: implement this
+
+ return false;
+ }
+
+ /**
+ * Wrapper for ldap_add()
+ *
+ * @see ldap_add()
+ */
+ public function add($dn, $entry)
+ {
+ $this->_debug("C: Add $dn: ".print_r($entry, true));
+
+ $res = ldap_add($this->conn, $dn, $entry);
+ if ($res === false) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_delete()
+ *
+ * @see ldap_delete()
+ */
+ public function delete($dn)
+ {
+ $this->_debug("C: Delete $dn");
+
+ $res = ldap_delete($this->conn, $dn);
+ if ($res === false) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_mod_replace()
+ *
+ * @see ldap_mod_replace()
+ */
+ public function mod_replace($dn, $entry)
+ {
+ $this->_debug("C: Replace $dn: ".print_r($entry, true));
+
+ if (!ldap_mod_replace($this->conn, $dn, $entry)) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_mod_add()
+ *
+ * @see ldap_mod_add()
+ */
+ public function mod_add($dn, $entry)
+ {
+ $this->_debug("C: Add $dn: ".print_r($entry, true));
+
+ if (!ldap_mod_add($this->conn, $dn, $entry)) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_mod_del()
+ *
+ * @see ldap_mod_del()
+ */
+ public function mod_del($dn, $entry)
+ {
+ $this->_debug("C: Delete $dn: ".print_r($entry, true));
+
+ if (!ldap_mod_del($this->conn, $dn, $entry)) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_rename()
+ *
+ * @see ldap_rename()
+ */
+ public function rename($dn, $newrdn, $newparent = null, $deleteoldrdn = true)
+ {
+ $this->_debug("C: Rename $dn to $newrdn");
+
+ if (!ldap_rename($this->conn, $dn, $newrdn, $newparent, $deleteoldrdn)) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return true;
+ }
+
+ /**
+ * Wrapper for ldap_list() + ldap_get_entries()
+ *
+ * @see ldap_list()
+ * @see ldap_get_entries()
+ */
+ public function list_entries($dn, $filter, $attributes = array('dn'))
+ {
+ $list = array();
+ $this->_debug("C: List $dn [{$filter}]");
+
+ if ($result = ldap_list($this->conn, $dn, $filter, $attributes)) {
+ $list = ldap_get_entries($this->conn, $result);
+
+ if ($list === false) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return array();
+ }
+
+ $count = $list['count'];
+ unset($list['count']);
+
+ $this->_debug("S: $count record(s)");
+ }
+ else {
+ $this->_debug("S: ".ldap_error($this->conn));
+ }
+
+ return $list;
+ }
+
+ /**
+ * Wrapper for ldap_read() + ldap_get_entries()
+ *
+ * @see ldap_read()
+ * @see ldap_get_entries()
+ */
+ public function read_entries($dn, $filter, $attributes = null)
+ {
+ $this->_debug("C: Read $dn [{$filter}]");
+
+ if ($this->conn && $dn) {
+ if (!$attributes)
+ $attributes = $this->attributes;
+
+ $result = @ldap_read($this->conn, $dn, $filter, $attributes, 0, (int)$this->config['sizelimit'], (int)$this->config['timelimit']);
+ if ($result === false) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ return false;
+ }
+
+ $this->_debug("S: OK");
+ return ldap_get_entries($this->conn, $result);
+ }
+
+ return false;
+ }
+
+ /**
+ * Choose the right PHP function according to scope property
+ *
+ * @param string $scope The LDAP scope (sub|base|list)
+ * @param string $ns_function Function to be used for numSubOrdinates queries
+ * @return string PHP function to be used to query directory
+ */
+ public static function scope2func($scope, &$ns_function = null)
+ {
+ switch ($scope) {
+ case 'sub':
+ $function = $ns_function = 'ldap_search';
+ break;
+ case 'base':
+ $function = $ns_function = 'ldap_read';
+ break;
+ default:
+ $function = 'ldap_list';
+ $ns_function = 'ldap_read';
+ break;
+ }
+
+ return $function;
+ }
+
+ /**
+ * Convert the given scope integer value to a string representation
+ */
+ public static function scopeint2str($scope)
+ {
+ switch ($scope) {
+ case 2: return 'sub';
+ case 1: return 'one';
+ case 0: return 'base';
+ default: $this->_debug("Scope $scope is not a valid scope integer");
+ }
+
+ return '';
+ }
+
+ /**
+ * Escapes the given value according to RFC 2254 so that it can be safely used in LDAP filters.
+ *
+ * @param string $val Value to quote
+ * @return string The escaped value
+ */
+ public static function escape_value($val)
+ {
+ return strtr($str, array('*'=>'\2a', '('=>'\28', ')'=>'\29',
+ '\\'=>'\5c', '/'=>'\2f'));
+ }
+
+ /**
+ * Escapes a DN value according to RFC 2253
+ *
+ * @param string $dn DN value o quote
+ * @return string The escaped value
+ */
+ public static function escape_dn($dn)
+ {
+ return strtr($str, array(','=>'\2c', '='=>'\3d', '+'=>'\2b',
+ '<'=>'\3c', '>'=>'\3e', ';'=>'\3b', '\\'=>'\5c',
+ '"'=>'\22', '#'=>'\23'));
+ }
+
+ /**
+ * Normalize a LDAP result by converting entry attributes arrays into single values
+ *
+ * @param array $result LDAP result set fetched with ldap_get_entries()
+ * @return array Hash array with normalized entries, indexed by their DNs
+ */
+ public static function normalize_result($result)
+ {
+ if (!is_array($result)) {
+ return array();
+ }
+
+ $entries = array();
+ for ($i = 0; $i < $result['count']; $i++) {
+ $key = $result[$i]['dn'] ? $result[$i]['dn'] : $i;
+ $entries[$key] = self::normalize_entry($result[$i]);
+ }
+
+ return $entries;
+ }
+
+ /**
+ * Turn an LDAP entry into a regular PHP array with attributes as keys.
+ *
+ * @param array $entry Attributes array as retrieved from ldap_get_attributes() or ldap_get_entries()
+ * @return array Hash array with attributes as keys
+ */
+ public static function normalize_entry($entry)
+ {
+ $rec = array();
+ for ($i=0; $i < $entry['count']; $i++) {
+ $attr = $entry[$i];
+ if ($entry[$attr]['count'] == 1) {
+ switch ($attr) {
+ case 'objectclass':
+ $rec[$attr] = array(strtolower($entry[$attr][0]));
+ break;
+ default:
+ $rec[$attr] = $entry[$attr][0];
+ break;
+ }
+ }
+ else {
+ for ($j=0; $j < $entry[$attr]['count']; $j++) {
+ $rec[$attr][$j] = $entry[$attr][$j];
+ }
+ }
+ }
+
+ return $rec;
+ }
+
+ /**
+ * Set server controls for Virtual List View (paginated listing)
+ */
+ private function _vlv_set_controls($sort, $list_page, $page_size, $search = null)
+ {
+ $sort_ctrl = array('oid' => "1.2.840.113556.1.4.473", 'value' => self::_sort_ber_encode((array)$sort));
+ $vlv_ctrl = array('oid' => "2.16.840.1.113730.3.4.9", 'value' => self::_vlv_ber_encode(($offset = ($list_page-1) * $page_size + 1), $page_size, $search), 'iscritical' => true);
+
+ $this->_debug("C: Set controls sort=" . join(' ', unpack('H'.(strlen($sort_ctrl['value'])*2), $sort_ctrl['value'])) . " ($sort[0]);"
+ . " vlv=" . join(' ', (unpack('H'.(strlen($vlv_ctrl['value'])*2), $vlv_ctrl['value']))) . " ($offset/$page_size; $search)");
+
+ if (!ldap_set_option($this->conn, LDAP_OPT_SERVER_CONTROLS, array($sort_ctrl, $vlv_ctrl))) {
+ $this->_debug("S: ".ldap_error($this->conn));
+ $this->set_error(self::ERROR_SEARCH, 'vlvnotsupported');
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Returns unified attribute name (resolving aliases)
+ */
+ private static function _attr_name($namev)
+ {
+ // list of known attribute aliases
+ static $aliases = array(
+ 'gn' => 'givenname',
+ 'rfc822mailbox' => 'email',
+ 'userid' => 'uid',
+ 'emailaddress' => 'email',
+ 'pkcs9email' => 'email',
+ );
+
+ list($name, $limit) = explode(':', $namev, 2);
+ $suffix = $limit ? ':'.$limit : '';
+
+ return (isset($aliases[$name]) ? $aliases[$name] : $name) . $suffix;
+ }
+
+ /**
+ * Quotes attribute value string
+ *
+ * @param string $str Attribute value
+ * @param bool $dn True if the attribute is a DN
+ *
+ * @return string Quoted string
+ */
+ public static function quote_string($str, $dn=false)
+ {
+ // take firt entry if array given
+ if (is_array($str))
+ $str = reset($str);
+
+ if ($dn)
+ $replace = array(','=>'\2c', '='=>'\3d', '+'=>'\2b', '<'=>'\3c',
+ '>'=>'\3e', ';'=>'\3b', '\\'=>'\5c', '"'=>'\22', '#'=>'\23');
+ else
+ $replace = array('*'=>'\2a', '('=>'\28', ')'=>'\29', '\\'=>'\5c',
+ '/'=>'\2f');
+
+ return strtr($str, $replace);
+ }
+
+ /**
+ * Prints debug info to the log
+ */
+ private function _debug($str)
+ {
+ if ($this->debug && class_exists('rcube')) {
+ rcube::write_log('ldap', $str);
+ }
+ }
+
+
+ /***************** Virtual List View (VLV) related utility functions **************** */
+
+ /**
+ * Return the search string value to be used in VLV controls
+ */
+ private function _vlv_search($sort, $search)
+ {
+ foreach ($search as $attr => $value) {
+ if (!in_array(strtolower($attr), $sort)) {
+ $this->_debug("d: Cannot use VLV search using attribute not indexed: $attr (not in " . var_export($sort, true) . ")");
+ return null;
+ } else {
+ return $value;
+ }
+ }
+ }
+
+ /**
+ * Find a VLV index matching the given query attributes
+ *
+ * @return string Sort attribute or False if no match
+ */
+ private function _find_vlv($base_dn, $filter, $scope, $sort_attrs = null)
+ {
+ if (!$this->config['vlv'] || $scope == 'base') {
+ return false;
+ }
+
+ // get vlv config
+ $vlv_config = $this->_read_vlv_config();
+
+ if ($vlv = $vlv_config[$base_dn]) {
+ $this->_debug("D: Found a VLV for $base_dn");
+
+ if ($vlv['filter'] == strtolower($filter) || stripos($filter, '(&'.$vlv['filter'].'(') === 0) {
+ $this->_debug("D: Filter matches");
+ if ($vlv['scope'] == $scope) {
+ // Not passing any sort attributes means you don't care
+ if (empty($sort_attrs) || in_array($sort_attrs, $vlv['sort'])) {
+ return $vlv['sort'][0];
+ }
+ }
+ else {
+ $this->_debug("D: Scope does not match");
+ }
+ }
+ else {
+ $this->_debug("D: Filter does not match");
+ }
+ }
+ else {
+ $this->_debug("D: No VLV for $base_dn");
+ }
+
+ return false;
+ }
+
+ /**
+ * Return VLV indexes and searches including necessary configuration
+ * details.
+ */
+ private function _read_vlv_config()
+ {
+ if (empty($this->config['vlv']) || empty($this->config['config_root_dn'])) {
+ return array();
+ }
+ // return hard-coded VLV config
+ else if (is_array($this->config['vlv'])) {
+ return $this->config['vlv'];
+ }
+
+ // return cached result
+ if (is_array($this->vlv_config)) {
+ return $this->vlv_config;
+ }
+
+ if ($this->cache && ($cached_config = $this->cache->get('vlvconfig'))) {
+ $this->vlv_config = $cached_config;
+ return $this->vlv_config;
+ }
+
+ $this->vlv_config = array();
+
+ $ldap_result = ldap_search($this->conn, $this->config['config_root_dn'], '(objectclass=vlvsearch)', array('*'), 0, 0, 0);
+ $vlv_searches = new rcube_ldap_result($this->conn, $ldap_result, $this->config['config_root_dn'], '(objectclass=vlvsearch)');
+
+ if ($vlv_searches->count() < 1) {
+ $this->_debug("D: Empty result from search for '(objectclass=vlvsearch)' on '$config_root_dn'");
+ return array();
+ }
+
+ foreach ($vlv_searches->entries(true) as $vlv_search_dn => $vlv_search_attrs) {
+ // Multiple indexes may exist
+ $ldap_result = ldap_search($this->conn, $vlv_search_dn, '(objectclass=vlvindex)', array('*'), 0, 0, 0);
+ $vlv_indexes = new rcube_ldap_result($this->conn, $ldap_result, $vlv_search_dn, '(objectclass=vlvindex)');
+
+ // Reset this one for each VLV search.
+ $_vlv_sort = array();
+ foreach ($vlv_indexes->entries(true) as $vlv_index_dn => $vlv_index_attrs) {
+ $_vlv_sort[] = explode(' ', $vlv_index_attrs['vlvsort']);
+ }
+
+ $this->vlv_config[$vlv_search_attrs['vlvbase']] = array(
+ 'scope' => self::scopeint2str($vlv_search_attrs['vlvscope']),
+ 'filter' => strtolower($vlv_search_attrs['vlvfilter']),
+ 'sort' => $_vlv_sort,
+ );
+ }
+
+ // cache this
+ if ($this->cache)
+ $this->cache->set('vlvconfig', $this->vlv_config);
+
+ $this->_debug("D: Refreshed VLV config: " . var_export($this->vlv_config, true));
+
+ return $this->vlv_config;
+ }
+
+ /**
+ * Generate BER encoded string for Virtual List View option
+ *
+ * @param integer List offset (first record)
+ * @param integer Records per page
+ *
+ * @return string BER encoded option value
+ */
+ private static function _vlv_ber_encode($offset, $rpp, $search = '')
+ {
+ /*
+ this string is ber-encoded, php will prefix this value with:
+ 04 (octet string) and 10 (length of 16 bytes)
+ the code behind this string is broken down as follows:
+ 30 = ber sequence with a length of 0e (14) bytes following
+ 02 = type integer (in two's complement form) with 2 bytes following (beforeCount): 01 00 (ie 0)
+ 02 = type integer (in two's complement form) with 2 bytes following (afterCount): 01 18 (ie 25-1=24)
+ a0 = type context-specific/constructed with a length of 06 (6) bytes following
+ 02 = type integer with 2 bytes following (offset): 01 01 (ie 1)
+ 02 = type integer with 2 bytes following (contentCount): 01 00
+
+ with a search string present:
+ 81 = type context-specific/constructed with a length of 04 (4) bytes following (the length will change here)
+ 81 indicates a user string is present where as a a0 indicates just a offset search
+ 81 = type context-specific/constructed with a length of 06 (6) bytes following
+
+ The following info was taken from the ISO/IEC 8825-1:2003 x.690 standard re: the
+ encoding of integer values (note: these values are in
+ two-complement form so since offset will never be negative bit 8 of the
+ leftmost octet should never by set to 1):
+ 8.3.2: If the contents octets of an integer value encoding consist
+ of more than one octet, then the bits of the first octet (rightmost)
+ and bit 8 of the second (to the left of first octet) octet:
+ a) shall not all be ones; and
+ b) shall not all be zero
+ */
+
+ if ($search) {
+ $search = preg_replace('/[^-[:alpha:] ,.()0-9]+/', '', $search);
+ $ber_val = self::_string2hex($search);
+ $str = self::_ber_addseq($ber_val, '81');
+ }
+ else {
+ // construct the string from right to left
+ $str = "020100"; # contentCount
+
+ $ber_val = self::_ber_encode_int($offset); // returns encoded integer value in hex format
+
+ // calculate octet length of $ber_val
+ $str = self::_ber_addseq($ber_val, '02') . $str;
+
+ // now compute length over $str
+ $str = self::_ber_addseq($str, 'a0');
+ }
+
+ // now tack on records per page
+ $str = "020100" . self::_ber_addseq(self::_ber_encode_int($rpp-1), '02') . $str;
+
+ // now tack on sequence identifier and length
+ $str = self::_ber_addseq($str, '30');
+
+ return pack('H'.strlen($str), $str);
+ }
+
+ /**
+ * create ber encoding for sort control
+ *
+ * @param array List of cols to sort by
+ * @return string BER encoded option value
+ */
+ private static function _sort_ber_encode($sortcols)
+ {
+ $str = '';
+ foreach (array_reverse((array)$sortcols) as $col) {
+ $ber_val = self::_string2hex($col);
+
+ // 30 = ber sequence with a length of octet value
+ // 04 = octet string with a length of the ascii value
+ $oct = self::_ber_addseq($ber_val, '04');
+ $str = self::_ber_addseq($oct, '30') . $str;
+ }
+
+ // now tack on sequence identifier and length
+ $str = self::_ber_addseq($str, '30');
+
+ return pack('H'.strlen($str), $str);
+ }
+
+ /**
+ * Add BER sequence with correct length and the given identifier
+ */
+ private static function _ber_addseq($str, $identifier)
+ {
+ $len = dechex(strlen($str)/2);
+ if (strlen($len) % 2 != 0)
+ $len = '0'.$len;
+
+ return $identifier . $len . $str;
+ }
+
+ /**
+ * Returns BER encoded integer value in hex format
+ */
+ private static function _ber_encode_int($offset)
+ {
+ $val = dechex($offset);
+ $prefix = '';
+
+ // check if bit 8 of high byte is 1
+ if (preg_match('/^[89abcdef]/', $val))
+ $prefix = '00';
+
+ if (strlen($val)%2 != 0)
+ $prefix .= '0';
+
+ return $prefix . $val;
+ }
+
+ /**
+ * Returns ascii string encoded in hex
+ */
+ private static function _string2hex($str)
+ {
+ $hex = '';
+ for ($i=0; $i < strlen($str); $i++) {
+ $hex .= dechex(ord($str[$i]));
+ }
+ return $hex;
+ }
+
+}
diff --git a/program/lib/Roundcube/rcube_ldap_result.php b/program/lib/Roundcube/rcube_ldap_result.php
new file mode 100644
index 000000000..efc3331bc
--- /dev/null
+++ b/program/lib/Roundcube/rcube_ldap_result.php
@@ -0,0 +1,130 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | Roundcube/rcube_ldap_result.php |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | Copyright (C) 2006-2013, The Roundcube Dev Team |
+ | Copyright (C) 2013, Kolab Systems AG |
+ | |
+ | 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: |
+ | Model class that represents an LDAP search result |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+
+/**
+ * Model class representing an LDAP search result
+ *
+ * @package Framework
+ * @subpackage LDAP
+ */
+class rcube_ldap_result implements Iterator
+{
+ public $conn;
+ public $ldap;
+ public $base_dn;
+ public $filter;
+
+ private $count = null;
+ private $current = null;
+ private $iteratorkey = 0;
+
+ /**
+ * Default constructor
+ *
+ * @param resource $conn LDAP link identifier
+ * @param resource $ldap LDAP result entry identifier
+ * @param string $base_dn Base DN used to get this result
+ * @param string $filter Filter query used to get this result
+ * @param integer $count Record count value (pre-calculated)
+ */
+ function __construct($conn, $ldap, $base_dn, $filter, $count = null)
+ {
+ $this->conn = $conn;
+ $this->ldap = $ldap;
+ $this->base_dn = $base_dn;
+ $this->filter = $filter;
+ $this->count = $count;
+ }
+
+ /**
+ * Wrapper for ldap_sort()
+ */
+ public function sort($attr)
+ {
+ return ldap_sort($this->conn, $this->ldap, $attr);
+ }
+
+ /**
+ * Get entries count
+ */
+ public function count()
+ {
+ if (!isset($this->count))
+ $this->count = ldap_count_entries($this->conn, $this->ldap);
+
+ return $this->count;
+ }
+
+ /**
+ * Wrapper for ldap_get_entries()
+ *
+ * @param boolean $normalize Optionally normalize the entries to a list of hash arrays
+ * @return array List of LDAP entries
+ */
+ public function entries($normalize = false)
+ {
+ $entries = ldap_get_entries($this->conn, $this->ldap);
+ return $normalize ? rcube_ldap_generic::normalize_result($entries) : $entries;
+ }
+
+ /**
+ * Wrapper for ldap_get_dn() using the current entry pointer
+ */
+ public function get_dn()
+ {
+ return $this->current ? ldap_get_dn($this->conn, $this->current) : null;
+ }
+
+
+ /*** Implements the PHP 5 Iterator interface to make foreach work ***/
+
+ function current()
+ {
+ $attrib = ldap_get_attributes($this->conn, $this->current);
+ $attrib['dn'] = ldap_get_dn($this->conn, $this->current);
+ return $attrib;
+ }
+
+ function key()
+ {
+ return $this->iteratorkey;
+ }
+
+ function rewind()
+ {
+ $this->iteratorkey = 0;
+ $this->current = ldap_first_entry($this->conn, $this->ldap);
+ }
+
+ function next()
+ {
+ $this->iteratorkey++;
+ $this->current = ldap_next_entry($this->conn, $this->current);
+ }
+
+ function valid()
+ {
+ return (bool)$this->current;
+ }
+
+}
diff --git a/program/lib/Roundcube/rcube_session.php b/program/lib/Roundcube/rcube_session.php
index 4e0682749..615ec6f0e 100644
--- a/program/lib/Roundcube/rcube_session.php
+++ b/program/lib/Roundcube/rcube_session.php
@@ -32,6 +32,7 @@ class rcube_session
private $ip;
private $start;
private $changed;
+ private $time_diff = 0;
private $reloaded = false;
private $unsets = array();
private $gc_handlers = array();
@@ -93,7 +94,7 @@ class rcube_session
array($this, 'db_read'),
array($this, 'db_write'),
array($this, 'db_destroy'),
- array($this, 'db_gc'));
+ array($this, 'gc'));
}
}
@@ -148,6 +149,11 @@ class rcube_session
}
session_write_close();
+
+ // write_close() is called on script shutdown, see rcube::shutdown()
+ // execute cleanup functionality if enabled by session gc handler
+ // we do this after closing the session for better performance
+ $this->gc_shutdown();
}
@@ -161,14 +167,16 @@ class rcube_session
public function db_read($key)
{
$sql_result = $this->db->query(
- "SELECT vars, ip, changed FROM ".$this->db->table_name('session')
- ." WHERE sess_id = ?", $key);
+ "SELECT vars, ip, changed, " . $this->db->now() . " AS ts"
+ . " FROM " . $this->db->table_name('session')
+ . " WHERE sess_id = ?", $key);
if ($sql_result && ($sql_arr = $this->db->fetch_assoc($sql_result))) {
- $this->changed = strtotime($sql_arr['changed']);
- $this->ip = $sql_arr['ip'];
- $this->vars = base64_decode($sql_arr['vars']);
- $this->key = $key;
+ $this->time_diff = time() - strtotime($sql_arr['ts']);
+ $this->changed = strtotime($sql_arr['changed']);
+ $this->ip = $sql_arr['ip'];
+ $this->vars = base64_decode($sql_arr['vars']);
+ $this->key = $key;
return !empty($this->vars) ? (string) $this->vars : '';
}
@@ -188,8 +196,9 @@ class rcube_session
*/
public function db_write($key, $vars)
{
- $ts = microtime(true);
- $now = $this->db->fromunixtime((int)$ts);
+ $now = $this->db->now();
+ $table = $this->db->table_name('session');
+ $ts = microtime(true);
// no session row in DB (db_read() returns false)
if (!$this->key) {
@@ -207,22 +216,19 @@ class rcube_session
$newvars = $this->_fixvars($vars, $oldvars);
if ($newvars !== $oldvars) {
- $this->db->query(
- sprintf("UPDATE %s SET vars=?, changed=%s WHERE sess_id=?",
- $this->db->table_name('session'), $now),
- base64_encode($newvars), $key);
+ $this->db->query("UPDATE $table "
+ . "SET changed = $now, vars = ? WHERE sess_id = ?",
+ base64_encode($newvars), $key);
}
- else if ($ts - $this->changed > $this->lifetime / 2) {
- $this->db->query("UPDATE ".$this->db->table_name('session')
- ." SET changed=$now WHERE sess_id=?", $key);
+ else if ($ts - $this->changed + $this->time_diff > $this->lifetime / 2) {
+ $this->db->query("UPDATE $table SET changed = $now"
+ . " WHERE sess_id = ?", $key);
}
}
else {
- $this->db->query(
- sprintf("INSERT INTO %s (sess_id, vars, ip, created, changed) ".
- "VALUES (?, ?, ?, %s, %s)",
- $this->db->table_name('session'), $now, $now),
- $key, base64_encode($vars), (string)$this->ip);
+ $this->db->query("INSERT INTO $table (sess_id, vars, ip, created, changed)"
+ . " VALUES (?, ?, ?, $now, $now)",
+ $key, base64_encode($vars), (string)$this->ip);
}
return true;
@@ -282,25 +288,6 @@ class rcube_session
/**
- * Garbage collecting function
- *
- * @param string Session lifetime in seconds
- * @return boolean True on success
- */
- public function db_gc($maxlifetime)
- {
- // just delete all expired sessions
- $this->db->query(
- sprintf("DELETE FROM %s WHERE changed < %s",
- $this->db->table_name('session'), $this->db->fromunixtime(time() - $maxlifetime)));
-
- $this->gc();
-
- return true;
- }
-
-
- /**
* Read session data from memcache
*
* @param string Session ID
@@ -376,11 +363,11 @@ class rcube_session
/**
* Execute registered garbage collector routines
*/
- public function gc()
+ public function gc($maxlifetime)
{
- foreach ($this->gc_handlers as $fct) {
- call_user_func($fct);
- }
+ // move gc execution to the script shutdown function
+ // see rcube::shutdown() and rcube_session::write_close()
+ return $this->gc_enabled = $maxlifetime;
}
@@ -402,6 +389,25 @@ class rcube_session
/**
+ * Garbage collector handler to run on script shutdown
+ */
+ protected function gc_shutdown()
+ {
+ if ($this->gc_enabled) {
+ // just delete all expired sessions
+ if ($this->storage == 'db') {
+ $this->db->query("DELETE FROM " . $this->db->table_name('session')
+ . " WHERE changed < " . $this->db->now(-$this->gc_enabled));
+ }
+
+ foreach ($this->gc_handlers as $fct) {
+ call_user_func($fct);
+ }
+ }
+ }
+
+
+ /**
* Generate and set new session id
*
* @param boolean $destroy If enabled the current session will be destroyed
diff --git a/program/lib/Roundcube/rcube_spellchecker.php b/program/lib/Roundcube/rcube_spellchecker.php
index 60aec500f..df4365223 100644
--- a/program/lib/Roundcube/rcube_spellchecker.php
+++ b/program/lib/Roundcube/rcube_spellchecker.php
@@ -84,6 +84,9 @@ class rcube_spellchecker
if ($this->engine == 'pspell') {
$this->matches = $this->_pspell_check($this->content);
}
+ else if ($this->engine == 'enchant') {
+ $this->matches = $this->_enchant_check($this->content);
+ }
else {
$this->matches = $this->_googie_check($this->content);
}
@@ -115,6 +118,9 @@ class rcube_spellchecker
if ($this->engine == 'pspell') {
return $this->_pspell_suggestions($word);
}
+ else if ($this->engine == 'enchant') {
+ return $this->_enchant_suggestions($word);
+ }
return $this->_googie_suggestions($word);
}
@@ -133,6 +139,9 @@ class rcube_spellchecker
if ($this->engine == 'pspell') {
return $this->_pspell_words($text, $is_html);
}
+ else if ($this->engine == 'enchant') {
+ return $this->_enchant_words($text, $is_html);
+ }
return $this->_googie_words($text, $is_html);
}
@@ -326,6 +335,141 @@ class rcube_spellchecker
}
+ /**
+ * Checks the text using enchant
+ *
+ * @param string $text Text content for spellchecking
+ */
+ private function _enchant_check($text)
+ {
+ // init spellchecker
+ $this->_enchant_init();
+
+ if (!$this->enchant_dictionary) {
+ return array();
+ }
+
+ // tokenize
+ $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+
+ $diff = 0;
+ $matches = array();
+
+ foreach ($text as $w) {
+ $word = trim($w[0]);
+ $pos = $w[1] - $diff;
+ $len = mb_strlen($word);
+
+ // skip exceptions
+ if ($this->is_exception($word)) {
+ }
+ else if (!enchant_dict_check($this->enchant_dictionary, $word)) {
+ $suggestions = enchant_dict_suggest($this->enchant_dictionary, $word);
+
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS) {
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+ }
+
+ $matches[] = array($word, $pos, $len, null, $suggestions);
+ }
+
+ $diff += (strlen($word) - $len);
+ }
+
+ return $matches;
+ }
+
+
+ /**
+ * Returns the misspelled words
+ */
+ private function _enchant_words($text = null, $is_html=false)
+ {
+ $result = array();
+
+ if ($text) {
+ // init spellchecker
+ $this->_enchant_init();
+
+ if (!$this->enchant_dictionary) {
+ return array();
+ }
+
+ // With Enchant we don't need to get suggestions to return misspelled words
+ if ($is_html) {
+ $text = $this->html2text($text);
+ }
+
+ $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+
+ foreach ($text as $w) {
+ $word = trim($w[0]);
+
+ // skip exceptions
+ if ($this->is_exception($word)) {
+ continue;
+ }
+
+ if (!enchant_dict_check($this->enchant_dictionary, $word)) {
+ $result[] = $word;
+ }
+ }
+
+ return $result;
+ }
+
+ foreach ($this->matches as $m) {
+ $result[] = $m[0];
+ }
+
+ return $result;
+ }
+
+
+ /**
+ * Returns suggestions for misspelled word
+ */
+ private function _enchant_suggestions($word)
+ {
+ // init spellchecker
+ $this->_enchant_init();
+
+ if (!$this->enchant_dictionary) {
+ return array();
+ }
+
+ $suggestions = enchant_dict_suggest($this->enchant_dictionary, $word);
+
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS)
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+
+ return is_array($suggestions) ? $suggestions : array();
+ }
+
+
+ /**
+ * Initializes PSpell dictionary
+ */
+ private function _enchant_init()
+ {
+ if (!$this->enchant_broker) {
+ if (!extension_loaded('enchant')) {
+ $this->error = "Enchant extension not available";
+ return;
+ }
+
+ $this->enchant_broker = enchant_broker_init();
+ }
+
+ if (!enchant_broker_dict_exists($this->enchant_broker, $this->lang)) {
+ $this->error = "Unable to load dictionary for selected language using Enchant";
+ return;
+ }
+
+ $this->enchant_dictionary = enchant_broker_request_dict($this->enchant_broker, $this->lang);
+ }
+
+
private function _googie_check($text)
{
// spell check uri is configured
@@ -377,7 +521,7 @@ class rcube_spellchecker
if (!$store) {
$this->error = "Empty result from spelling engine";
}
- else if (preg_match('/<spellresult error="([^"]+)"/', $store, $m)) {
+ else if (preg_match('/<spellresult error="([^"]+)"/', $store, $m) && $m[1]) {
$this->error = "Error code $m[1] returned";
}
diff --git a/program/lib/Roundcube/rcube_storage.php b/program/lib/Roundcube/rcube_storage.php
index b17291bdf..4b336f210 100644
--- a/program/lib/Roundcube/rcube_storage.php
+++ b/program/lib/Roundcube/rcube_storage.php
@@ -540,12 +540,13 @@ abstract class rcube_storage
/**
* Append a mail message (source) to a specific folder.
*
- * @param string $folder Target folder
- * @param string $message The message source string or filename
- * @param string $headers Headers string if $message contains only the body
- * @param boolean $is_file True if $message is a filename
- * @param array $flags Message flags
- * @param mixed $date Message internal date
+ * @param string $folder Target folder
+ * @param string|array $message The message source string or filename
+ * or array (of strings and file pointers)
+ * @param string $headers Headers string if $message contains only the body
+ * @param boolean $is_file True if $message is a filename
+ * @param array $flags Message flags
+ * @param mixed $date Message internal date
*
* @return int|bool Appended message UID or True on success, False on error
*/
diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
index 29baa82f3..6c3bd2143 100644
--- a/program/lib/Roundcube/rcube_utils.php
+++ b/program/lib/Roundcube/rcube_utils.php
@@ -360,12 +360,8 @@ class rcube_utils
return $value;
}
- // strip single quotes if magic_quotes_sybase is enabled
- if (ini_get('magic_quotes_sybase')) {
- $value = str_replace("''", "'", $value);
- }
// strip slashes if magic_quotes enabled
- else if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) {
+ if (get_magic_quotes_gpc() || get_magic_quotes_runtime()) {
$value = stripslashes($value);
}
diff --git a/program/lib/Roundcube/rcube_vcard.php b/program/lib/Roundcube/rcube_vcard.php
index 90acb2110..a71305c4b 100644
--- a/program/lib/Roundcube/rcube_vcard.php
+++ b/program/lib/Roundcube/rcube_vcard.php
@@ -714,9 +714,15 @@ class rcube_vcard
$value[] = $attrvalues;
}
else if (is_bool($attrvalues)) {
- // true means just tag, not tag=value, as in PHOTO;BASE64:...
+ // true means just a tag, not tag=value, as in PHOTO;BASE64:...
if ($attrvalues) {
- $attr .= strtoupper(";$attrname");
+ // vCard v3 uses ENCODING=B (#1489183)
+ if ($attrname == 'base64') {
+ $attr .= ";ENCODING=B";
+ }
+ else {
+ $attr .= strtoupper(";$attrname");
+ }
}
}
else {
diff --git a/program/localization/ar_SA/labels.inc b/program/localization/ar_SA/labels.inc
index af08cc301..bc1764b0f 100644
--- a/program/localization/ar_SA/labels.inc
+++ b/program/localization/ar_SA/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'المسودات';
$labels['sent'] = 'المرسل';
$labels['trash'] = 'المهملات';
$labels['junk'] = 'غير المرغوب';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'الموضوع';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'وضع طريقة السرد';
$labels['folderactions'] = 'إجراءات المجلد...';
$labels['compact'] = 'ضغط';
$labels['empty'] = 'تÙريغ';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'المساحة المستخدمة';
$labels['unknown'] = 'مجهول';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'استعادة البحث للاÙتراضي';
$labels['searchmod'] = 'أماكن البحث';
$labels['msgtext'] = 'كامل الرسالة';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'اÙتح ÙÙŠ ناÙذة جديدة';
$labels['emlsave'] = 'تنزيل (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'عرض المجموعة الأخيرة';
$labels['group'] = 'مجموعة';
$labels['groups'] = 'المجموعات';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'العناوين الشخصية';
$labels['searchsave'] = 'Ø­Ùظ البحث';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'تجاهل الكلمات التي تحتوي
$labels['spellcheckignorecaps'] = 'تجاهل الكلمات التي بها أحر٠كبيرة';
$labels['addtodict'] = 'إضاÙØ© إلى القامس';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ast/labels.inc b/program/localization/ast/labels.inc
index 49f85689b..8c1985eef 100644
--- a/program/localization/ast/labels.inc
+++ b/program/localization/ast/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Borradores';
$labels['sent'] = 'Unviaos';
$labels['trash'] = 'Papelera';
$labels['junk'] = 'Puxarra';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Asuntu';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compautar';
$labels['empty'] = 'Vaciar';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Espaciu en discu';
$labels['unknown'] = 'desconocíu';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Anovar la búsqueda';
$labels['searchmod'] = 'Guetar modificadores';
$labels['msgtext'] = 'Mensax completu';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir en una ventana nueva';
$labels['emlsave'] = 'Baxar (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Amosar l\'últimu grupu';
$labels['group'] = 'Group';
$labels['groups'] = 'Grupos';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Direiciones personales';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/az_AZ/labels.inc b/program/localization/az_AZ/labels.inc
index 0cb4b3e82..129315ec0 100644
--- a/program/localization/az_AZ/labels.inc
+++ b/program/localization/az_AZ/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Qaralamalar';
$labels['sent'] = 'Göndərilənlər';
$labels['trash'] = 'Səbət';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Mövzu';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Görünüş rejimi';
$labels['folderactions'] = 'Qovluq işləri...';
$labels['compact'] = 'Sıx';
$labels['empty'] = 'BoÅŸalt';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk istifadəsi';
$labels['unknown'] = 'naməlum';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Axtarışı yenilə';
$labels['searchmod'] = 'Axtarış variantları';
$labels['msgtext'] = 'Bütün məktub';
$labels['body'] = 'Mətn';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Yeni pəncərədə aç';
$labels['emlsave'] = 'Saxla (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Sonuncunu göstər';
$labels['group'] = 'Qrup';
$labels['groups'] = 'Qruplar';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Şəxsi ünvanlar';
$labels['searchsave'] = 'SorÄŸunu saxla';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Rəqəmlər ilə sözləri keç';
$labels['spellcheckignorecaps'] = 'Böyük hərfləri olan sözlərdən keç';
$labels['addtodict'] = 'Lüğətə əlavə et';
$labels['mailtoprotohandler'] = 'mailto: keçid üçün protokol qeyd et';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Məktubların yönəldilməsi';
$labels['inline'] = 'mətndə';
$labels['asattachment'] = 'fayl kimi';
diff --git a/program/localization/be_BE/labels.inc b/program/localization/be_BE/labels.inc
index a5489a454..56339a926 100644
--- a/program/localization/be_BE/labels.inc
+++ b/program/localization/be_BE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Чарнавікі';
$labels['sent'] = 'ДаÑланыÑ';
$labels['trash'] = 'Сметніца';
$labels['junk'] = 'Спам';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ТÑма';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/bg_BG/labels.inc b/program/localization/bg_BG/labels.inc
index 6542cfc53..dd5be6e64 100644
--- a/program/localization/bg_BG/labels.inc
+++ b/program/localization/bg_BG/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Чернови';
$labels['sent'] = 'Изпратени';
$labels['trash'] = 'Кошче';
$labels['junk'] = 'Спам';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Заглавие';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Кратък ÑпиÑък';
$labels['folderactions'] = 'ДейÑÑ‚Ð²Ð¸Ñ Ð·Ð° папки...';
$labels['compact'] = 'Свиване';
$labels['empty'] = 'Изпразни';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Използвано мÑÑто';
$labels['unknown'] = 'нÑма информациÑ';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'ИзчиÑти Ñ‚ÑŠÑ€Ñенето и покажи вÑ
$labels['searchmod'] = 'ТърÑене във';
$labels['msgtext'] = 'ЦÑлото Ñъобщение';
$labels['body'] = 'ОÑновен текÑÑ‚';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Отвори в нов прозорец';
$labels['emlsave'] = 'Изтегли като .eml';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'ПоÑледна Ñтраница';
$labels['group'] = 'Група';
$labels['groups'] = 'Групи';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Лични адреÑи';
$labels['searchsave'] = 'Запази Ñ‚ÑŠÑ€Ñенето';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Игнорирай думи ÑъдържащÐ
$labels['spellcheckignorecaps'] = 'Игнорирай думи Ñъдържащи единÑтвено главни букви';
$labels['addtodict'] = 'Добави в речника';
$labels['mailtoprotohandler'] = 'РегиÑтриран протокол за mailto: връзките';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Препращане на ÑъобщениÑ';
$labels['inline'] = 'вградено';
$labels['asattachment'] = 'като прикачен файл';
diff --git a/program/localization/bn_BD/labels.inc b/program/localization/bn_BD/labels.inc
index a0866a3a7..1273ef192 100644
--- a/program/localization/bn_BD/labels.inc
+++ b/program/localization/bn_BD/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'খসড়া';
$labels['sent'] = 'পà§à¦°à§‡à¦°à¦¿à¦¤(পাঠানো মেইল)';
$labels['trash'] = 'ডাসà§à¦Ÿà¦¬à¦¿à¦¨';
$labels['junk'] = 'আজেবাজে মেইল';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'বিষয়';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'টাইটকরà§à¦¨';
$labels['empty'] = 'খালিকরà§à¦¨';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ডিসà§à¦• ঠখালি যায়গা';
$labels['unknown'] = 'অজানা';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'নতà§à¦¨à¦•à¦°à§‡ খà§à¦œà§à¦¨';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'নতà§à¦¨ উইনà§à¦¡à§‹ তে দেখà§à¦¨';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'শেষের গà§à¦²à§‹ দেখান';
$labels['group'] = 'Group';
$labels['groups'] = 'গà§à¦°à§à¦ª';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'নিজের ঠিকানা';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/br/labels.inc b/program/localization/br/labels.inc
index 537a887df..c88fd92a6 100644
--- a/program/localization/br/labels.inc
+++ b/program/localization/br/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Brouilhedoù';
$labels['sent'] = 'Kaset';
$labels['trash'] = 'Pod-lastez';
$labels['junk'] = 'Stroboù';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Sujed';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Stummaat';
$labels['empty'] = 'Skarzhañ';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Implijadur pladenn';
$labels['unknown'] = 'Dianav';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Aderaouekaat ar glask';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Gwelout ar bajenn diwezhañ';
$labels['group'] = 'Group';
$labels['groups'] = 'Strolladoù';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Chomlec\'h personel';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/bs_BA/labels.inc b/program/localization/bs_BA/labels.inc
index 5afdcad1f..61989e6b3 100644
--- a/program/localization/bs_BA/labels.inc
+++ b/program/localization/bs_BA/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Skice';
$labels['sent'] = 'Poslano';
$labels['trash'] = 'Smeće';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Prikaži prava imena specijalnih foldera';
// message listing
$labels['subject'] = 'Naslov';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'NaÄin prikaza liste';
$labels['folderactions'] = 'Akcije za foldere...';
$labels['compact'] = 'Optimiziraj';
$labels['empty'] = 'Isprazni';
+$labels['importmessages'] = 'Uvezi poruke';
$labels['quota'] = 'Zauzeće diska';
$labels['unknown'] = 'nepoznato';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Resetuj pretragu';
$labels['searchmod'] = 'Modifikacija pretrage';
$labels['msgtext'] = 'Cijela poruka';
$labels['body'] = 'Tijelo';
+$labels['type'] = 'Vrsta';
$labels['openinextwin'] = 'Otvori u novom prozoru';
$labels['emlsave'] = 'Preuzmi (.eml)';
@@ -223,7 +226,7 @@ $labels['mailreplyintro'] = '$date, $sender je napisao/la:';
$labels['originalmessage'] = 'Originalna poruka';
$labels['editidents'] = 'Uredi identitete';
-$labels['spellcheck'] = 'Spelovanje';
+$labels['spellcheck'] = 'Pravopis';
$labels['checkspelling'] = 'Provjera pravopisa';
$labels['resumeediting'] = 'Nastavi uređivanje';
$labels['revertto'] = 'Vrati na';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Prikaži zadnju stranicu';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupe';
+$labels['listgroup'] = 'Izlistaj Älanove grupe';
$labels['personaladrbook'] = 'LiÄne adrese';
$labels['searchsave'] = 'SaÄuvaj pretragu';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Zanemari rijeÄi sa brojevima';
$labels['spellcheckignorecaps'] = 'Zanemari rijeÄi napisane velikim slovima';
$labels['addtodict'] = 'Dodaj u rjeÄnik';
$labels['mailtoprotohandler'] = 'Registruj upravljaÄ protokola za mailto: linkovi';
+$labels['standardwindows'] = 'Tretiraj popup-ove kao standardne prozore';
$labels['forwardmode'] = 'Prosljeđivanje poruka';
$labels['inline'] = 'u istom redu';
$labels['asattachment'] = 'kao prilog';
diff --git a/program/localization/ca_ES/labels.inc b/program/localization/ca_ES/labels.inc
index 3be753b68..ca0129de4 100644
--- a/program/localization/ca_ES/labels.inc
+++ b/program/localization/ca_ES/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Esborranys';
$labels['sent'] = 'Enviats';
$labels['trash'] = 'Paperera';
$labels['junk'] = 'Correu brossa';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Assumpte';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Mode de vista de llista';
$labels['folderactions'] = 'Accions de carpeta';
$labels['compact'] = 'Compacta';
$labels['empty'] = 'Buida';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Ús del disc';
$labels['unknown'] = 'desconegut';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Neteja cerca';
$labels['searchmod'] = 'Cerca modificadors';
$labels['msgtext'] = 'Missatge sencer';
$labels['body'] = 'Cos';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Obre a una nova finestra';
$labels['emlsave'] = 'Descarrega (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Mostra la darrera pàgina';
$labels['group'] = 'Grup';
$labels['groups'] = 'Grups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Llibreta d\'adreces';
$labels['searchsave'] = 'Desa la cerca';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignora paraules amb números';
$labels['spellcheckignorecaps'] = 'Ignora paraules amb lletres capitalitzades';
$labels['addtodict'] = 'Afegeix al diccionari';
$labels['mailtoprotohandler'] = 'Registra controlador de protocol pels enllaços mailto:';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Reenviament de missatges';
$labels['inline'] = 'en línia';
$labels['asattachment'] = 'com adjunt';
diff --git a/program/localization/cs_CZ/labels.inc b/program/localization/cs_CZ/labels.inc
index 8fb7ffade..b5cc093d8 100644
--- a/program/localization/cs_CZ/labels.inc
+++ b/program/localization/cs_CZ/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Rozepsané';
$labels['sent'] = 'Odeslané';
$labels['trash'] = 'Koš';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Zobrazit skuteÄná jména speciálních složek';
// message listing
$labels['subject'] = 'Předmět';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Režim zobrazení seznamu';
$labels['folderactions'] = 'Akce se složkou...';
$labels['compact'] = 'Zmenšit';
$labels['empty'] = 'Vymazat';
+$labels['importmessages'] = 'Import zpráv';
$labels['quota'] = 'Využití schránky';
$labels['unknown'] = 'neznámý';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Zrušit vyhledávání';
$labels['searchmod'] = 'Parametry hledání';
$labels['msgtext'] = 'Celá zpráva';
$labels['body'] = 'Tělo';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Otevřít v novém okně';
$labels['emlsave'] = 'Stáhnout (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Zobrazit poslední zprávy';
$labels['group'] = 'Skupina';
$labels['groups'] = 'Skupiny';
+$labels['listgroup'] = ' Seznam Älenů skupiny';
$labels['personaladrbook'] = 'Osobní kontakty';
$labels['searchsave'] = 'Uložit hledání';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'Vytvářet HTML zprávy';
$labels['htmlonreply'] = 'jen při odpovědi na HTML zprávy';
$labels['htmlonreplyandforward'] = 'při přeposlání nebo odpovědi na HTML zprávu';
$labels['htmlsignature'] = 'HTML podpis';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Zobrazit e-mailovou adresu se skuteÄným jménem';
$labels['previewpane'] = 'Zobrazit panel náhledu';
$labels['skin'] = 'Vzhled';
$labels['logoutclear'] = 'Vyprázdnit koš při odhlášení';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorovat slova obsahující Äísla';
$labels['spellcheckignorecaps'] = 'Ignorovat slova psaná velkými písmeny';
$labels['addtodict'] = 'Přidat do slovníku';
$labels['mailtoprotohandler'] = 'Zaregistrovat handler pro odkazy „mailto:“';
+$labels['standardwindows'] = 'Zacházet s vyskakovacími okny jako se standardními okny';
$labels['forwardmode'] = 'Přeposlat zprávu';
$labels['inline'] = 'vloženě';
$labels['asattachment'] = 'jako přílohu';
diff --git a/program/localization/cs_CZ/messages.inc b/program/localization/cs_CZ/messages.inc
index 9800b2412..59b2c6bd6 100644
--- a/program/localization/cs_CZ/messages.inc
+++ b/program/localization/cs_CZ/messages.inc
@@ -24,7 +24,7 @@ $messages['sessionerror'] = 'Vaše přihlášení je neplatné nebo vypršelo';
$messages['storageerror'] = 'Připojení na IMAP server selhalo';
$messages['servererror'] = 'Chyba serveru!';
$messages['servererrormsg'] = 'Chyba serveru: $msg';
-$messages['dberror'] = 'Chyba v databázi!';
+$messages['dberror'] = 'Chyba databáze!';
$messages['requesttimedout'] = 'Došlo k vypršení požadavku';
$messages['errorreadonly'] = 'Příkaz nelze provést, složka je urÄena jen ke Ätení.';
$messages['errornoperm'] = 'Příkaz nelze provést, nemáte oprávnění.';
@@ -33,7 +33,7 @@ $messages['erroroverquotadelete'] = 'Není volné místo na disku. Použijte SHI
$messages['invalidrequest'] = 'Nesprávný požadavek. Data nebyla uložena.';
$messages['invalidhost'] = 'Špatné jméno serveru.';
$messages['nomessagesfound'] = 'Ve schránce nebyla nalezena žádná zpráva';
-$messages['loggedout'] = 'Byli jste úspěšně odhlášeni. Nashledanou!';
+$messages['loggedout'] = 'Byli jste úspěšně odhlášeni. Na shledanou!';
$messages['mailboxempty'] = 'Schránka je prázdná';
$messages['refreshing'] = 'Obnovuji...';
$messages['loading'] = 'NaÄítám...';
@@ -126,6 +126,8 @@ $messages['importwait'] = 'Importuji, prosím Äekejte...';
$messages['importformaterror'] = 'Import se nezdařil! Typ souboru není podporován.';
$messages['importconfirm'] = 'ÚspěšnÄ› naimportováno $inserted kontaktů, $skipped existujících záznamů pÅ™eskoÄeno: $names';
$messages['importconfirmskipped'] = '<b>PÅ™eskoÄeno $skipped existujících položek</b>';
+$messages['importmessagesuccess'] = 'Úspěšně naimportováno $nr zpráv';
+$messages['importmessageerror'] = 'Import se nezdařil! Nahraný soubor není platnou zprávou nebo souborem mailboxu';
$messages['opnotpermitted'] = 'Operace není povolena!';
$messages['nofromaddress'] = 'ChybÄ›jící e-mailová adresa v oznaÄeném profilu';
$messages['editorwarning'] = 'PÅ™epnutím do režimu prostého textu ztratíte veÅ¡keré formátování. Chcete pokraÄovat?';
diff --git a/program/localization/cy_GB/labels.inc b/program/localization/cy_GB/labels.inc
index 3e4f136bc..ca1f17426 100644
--- a/program/localization/cy_GB/labels.inc
+++ b/program/localization/cy_GB/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Drafftiau';
$labels['sent'] = 'Danfonwyd';
$labels['trash'] = 'Sbwriel';
$labels['junk'] = 'Sothach';
+$labels['show_real_foldernames'] = 'Dangos enwau go-iawn ar gyfer ffolderi arbennig';
// message listing
$labels['subject'] = 'Pwnc';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Golwg rhestr';
$labels['folderactions'] = 'Gweithredoedd ffolder...';
$labels['compact'] = 'Crynhoi';
$labels['empty'] = 'Gwagio';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Defnydd';
$labels['unknown'] = 'anhysbys';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Ail-osod chwiliad';
$labels['searchmod'] = 'Addasyddion chwilio';
$labels['msgtext'] = 'Y neges yn llawn';
$labels['body'] = 'Corff';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Agor mewn ffenest newydd';
$labels['emlsave'] = 'Llwytho lawr (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Dangos y set olaf';
$labels['group'] = 'Grŵp';
$labels['groups'] = 'Grwpiau';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Cyfeiriadau Personol';
$labels['searchsave'] = 'Cadw chwiliad';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'Ysgrifennu negeseuon HTML';
$labels['htmlonreply'] = 'wrth ateb i neges HTML yn unig';
$labels['htmlonreplyandforward'] = 'wrth ddanfon ymlaen neu ymateb i neges HTML';
$labels['htmlsignature'] = 'Llofnod HTML';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Dangos cyfeiriad ebost gyda\'r enw gweledig';
$labels['previewpane'] = 'Dangos ffenest rhagolwg';
$labels['skin'] = 'Croen rhyngwyneb';
$labels['logoutclear'] = 'Clirio\'r Sbwriel wrth allgofnodi';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Anwybyddu geiriau gyda rhifau';
$labels['spellcheckignorecaps'] = 'Anwybyddu geiriau sy\'n briflythrennau yn gyfangwbl';
$labels['addtodict'] = 'Ychwanegu i\'r geiriadur';
$labels['mailtoprotohandler'] = 'Cofrestru trafodwr protocol ar gyfer dolenni mailto:';
+$labels['standardwindows'] = 'Trin ffenestri naid fel ffenestri arferol';
$labels['forwardmode'] = 'Danfon neges ymlaen';
$labels['inline'] = 'mewnlin';
$labels['asattachment'] = 'fel atodiad';
diff --git a/program/localization/da_DK/labels.inc b/program/localization/da_DK/labels.inc
index 02d7dd9e3..a5b9b3bc8 100644
--- a/program/localization/da_DK/labels.inc
+++ b/program/localization/da_DK/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Kladder';
$labels['sent'] = 'Sendt post';
$labels['trash'] = 'Papirkurv';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Emne';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Listevisningsmode';
$labels['folderactions'] = 'Mappehandlinger...';
$labels['compact'] = 'Ryd op';
$labels['empty'] = 'Tøm';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Diskforbrug';
$labels['unknown'] = 'ukendt';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Nulstil søgning';
$labels['searchmod'] = 'Søgeparametre';
$labels['msgtext'] = 'Hele beskeden';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ã…bn i nyt vindue';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Vis sidste side';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Grupper';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personlige adresser';
$labels['searchsave'] = 'Gem søgning';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'Skriv HTML-besked';
$labels['htmlonreply'] = 'kun når jeg besvarer HTML-beskeder';
$labels['htmlonreplyandforward'] = 'ved videresendelse eller besvarelse af HTML beskeder';
$labels['htmlsignature'] = 'HTML-signatur';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Vis email-adresse med vist navn';
$labels['previewpane'] = 'Forhåndsvisning';
$labels['skin'] = 'Brugerflade';
$labels['logoutclear'] = 'Tøm Papirkurv når jeg logger af';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorer ord med tal';
$labels['spellcheckignorecaps'] = 'Ignorer ord hvor alle bogstaver er versaler';
$labels['addtodict'] = 'Tilføj til ordbog';
$labels['mailtoprotohandler'] = 'Registrer håndtering af \'mailto:\' links';
+$labels['standardwindows'] = 'Behandl popups som standardvinduer';
$labels['forwardmode'] = 'Videresendelse af besked';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'som vedhæftning';
diff --git a/program/localization/de_CH/labels.inc b/program/localization/de_CH/labels.inc
index e64859d2c..67d42bb05 100644
--- a/program/localization/de_CH/labels.inc
+++ b/program/localization/de_CH/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Entwürfe';
$labels['sent'] = 'Gesendet';
$labels['trash'] = 'Gelöscht';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Spezialordner nicht übersetzen';
// message listing
$labels['subject'] = 'Betreff';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Anzeigemodus';
$labels['folderactions'] = 'Ordneraktionen...';
$labels['compact'] = 'Packen';
$labels['empty'] = 'Leeren';
+$labels['importmessages'] = 'Nachrichten importieren';
$labels['quota'] = 'Verwendeter Speicherplatz';
$labels['unknown'] = 'unbekannt';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Löschen';
$labels['searchmod'] = 'Suchkriterien ändern';
$labels['msgtext'] = 'Ganze Nachricht';
$labels['body'] = 'Inhalt';
+$labels['type'] = 'Typ';
$labels['openinextwin'] = 'In neuem Fenster öffnen';
$labels['emlsave'] = 'Herunterladen (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Letzte Seite';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppen';
+$labels['listgroup'] = 'Gruppenmitglieder anzeigen';
$labels['personaladrbook'] = 'Persönliches Adressbuch';
$labels['searchsave'] = 'Suche speichern';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Wörter mit Ziffern überspringen';
$labels['spellcheckignorecaps'] = 'Wörter überspringen, die nur aus Grossbuchstaben bestehen';
$labels['addtodict'] = 'Zum Wörterbuch hinzufügen';
$labels['mailtoprotohandler'] = 'Als Empfänger für mailto: Links einrichten';
+$labels['standardwindows'] = 'Popups als normale Browserfenster öffnen';
$labels['forwardmode'] = 'Weiterleiten einer Nachricht';
$labels['inline'] = 'eingebettet';
$labels['asattachment'] = 'als Anhang';
diff --git a/program/localization/de_CH/messages.inc b/program/localization/de_CH/messages.inc
index f3697a825..27175be9e 100644
--- a/program/localization/de_CH/messages.inc
+++ b/program/localization/de_CH/messages.inc
@@ -126,6 +126,8 @@ $messages['importwait'] = 'Daten werden importiert, bitte warten...';
$messages['importformaterror'] = 'Import fehlgeschlagen! Die hochgeladene Datei enthält keines der unterstützten Datenformate.';
$messages['importconfirm'] = '<b>Es wurden $inserted Adressen erfolgreich importiert</b>';
$messages['importconfirmskipped'] = '<b>$skipped bestehende Einträge wurden übersprungen</b>';
+$messages['importmessagesuccess'] = '$nr Nachricht(n) erfolgreich importiert';
+$messages['importmessageerror'] = 'Import fehlgeschlagen! Die hochgeladene Datei ist keine E-Mail-Nachricht oder Mailbox-Datei.';
$messages['opnotpermitted'] = 'Operation nicht erlaubt!';
$messages['nofromaddress'] = 'Fehlende E-Mail-Adresse in ausgewählter Identität.';
$messages['editorwarning'] = 'Beim Wechseln in den Texteditor gehen alle Textformatierungen verloren. Möchten Sie fortfahren?';
diff --git a/program/localization/de_DE/labels.inc b/program/localization/de_DE/labels.inc
index d497a6bc6..662ad2c70 100644
--- a/program/localization/de_DE/labels.inc
+++ b/program/localization/de_DE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Entwürfe';
$labels['sent'] = 'Gesendet';
$labels['trash'] = 'Gelöscht';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Echte Namen für Spezialordner anzeigen';
// message listing
$labels['subject'] = 'Betreff';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Anzeigemodus';
$labels['folderactions'] = 'Ordneraktionen...';
$labels['compact'] = 'Packen';
$labels['empty'] = 'Leeren';
+$labels['importmessages'] = 'Nachrichten importieren';
$labels['quota'] = 'Speicherplatz';
$labels['unknown'] = 'unbekannt';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Suche zurücksetzen';
$labels['searchmod'] = 'Suchkriterien ändern';
$labels['msgtext'] = 'Nachricht';
$labels['body'] = 'Inhalt';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'In neuem Fenster öffnen';
$labels['emlsave'] = 'Lokal speichern (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Letzte Seite';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppen';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Persönliches Adressbuch';
$labels['searchsave'] = 'Suchergebnisse speichern';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'HTML-Nachrichten verfassen';
$labels['htmlonreply'] = 'nur Antworten auf HTML-Nachrichten';
$labels['htmlonreplyandforward'] = 'beim Weiterleiten und Beantworten auf HTML-Nachrichten';
$labels['htmlsignature'] = 'HTML-Signatur';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'E-Mail-Adresse mit dem Display Namen anzeigen';
$labels['previewpane'] = 'Nachrichtenvorschau anzeigen';
$labels['skin'] = 'Oberflächendesign';
$labels['logoutclear'] = 'Papierkorb beim Abmelden leeren';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Wörter mit Ziffern überspringen';
$labels['spellcheckignorecaps'] = 'Wörter überspringen, die nur aus Großbuchstaben bestehen';
$labels['addtodict'] = 'Zum Wörterbuch hinzufügen';
$labels['mailtoprotohandler'] = 'Als Empfänger für mailto: Links einrichten';
+$labels['standardwindows'] = 'Popups als Standard Windows behandeln';
$labels['forwardmode'] = 'Nachrichtenweiterleitung';
$labels['inline'] = 'eingebettet';
$labels['asattachment'] = 'als Anhang';
diff --git a/program/localization/el_GR/labels.inc b/program/localization/el_GR/labels.inc
index 9f5d81839..d3030e574 100644
--- a/program/localization/el_GR/labels.inc
+++ b/program/localization/el_GR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'ΠÏόχειÏα';
$labels['sent'] = 'Απεσταλμένα';
$labels['trash'] = 'Κάδος ΑποÏÏιμάτων';
$labels['junk'] = 'ΑνεπιθÏμητα';
+$labels['show_real_foldernames'] = 'Εμφάνιση Ï€Ïαγματικών ονομάτων για ειδικοÏÏ‚ φακέλους';
// message listing
$labels['subject'] = 'Θέμα';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'ΠÏοβολή σε λίστα';
$labels['folderactions'] = 'ΕνέÏγειες στους φακέλους';
$labels['compact'] = 'Συμπίεση';
$labels['empty'] = 'Άδειασμα';
+$labels['importmessages'] = 'Εισαγωγή μηνυμάτων';
$labels['quota'] = 'ΧÏήση δίσκου';
$labels['unknown'] = 'άγνωστο';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'ΕπαναφοÏά Αναζήτησης';
$labels['searchmod'] = 'Aλλαγή αναζήτησης';
$labels['msgtext'] = 'Σε όλο το μήνυμα';
$labels['body'] = 'Σώμα';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Άνοιγμα σε νέο παÏάθυÏο';
$labels['emlsave'] = 'Λήψη αÏχείου (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Εμφάνιση της τελευταίας σελ
$labels['group'] = 'Ομάδα';
$labels['groups'] = 'Ομάδες';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ΠÏοσωπικές ΔιυθÏνσεις';
$labels['searchsave'] = 'Αποθήκευση αναζήτησης';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Οι λέξεις που πεÏιέχουν Î
$labels['spellcheckignorecaps'] = 'Οι λέξεις γÏαμμένες με ΚΕΦΑΛΑΙΑ να αγνοοÏνται';
$labels['addtodict'] = 'ΠÏοσθήκη στο λεξικό';
$labels['mailtoprotohandler'] = 'ΚαταχώÏηση διαχείÏισης Ï€Ïωτοκόλλου δεσμών mailto:';
+$labels['standardwindows'] = 'ΧειÏιστείτε τα αναδυόμενα παÏάθυÏα ως Ï€Ïότυπο των Windows';
$labels['forwardmode'] = 'ΠÏοώθηση μηνυμάτων';
$labels['inline'] = 'με εσνωμάτωση';
$labels['asattachment'] = 'σαν επισÏναψη';
diff --git a/program/localization/en_GB/labels.inc b/program/localization/en_GB/labels.inc
index 88e4cfd9c..f903b0cf5 100644
--- a/program/localization/en_GB/labels.inc
+++ b/program/localization/en_GB/labels.inc
@@ -194,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@@ -204,6 +205,7 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -355,6 +357,7 @@ $labels['lastpage'] = 'Show last set';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -473,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalised';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index d8e517387..1865bcb3d 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -194,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@@ -204,6 +205,8 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
+$labels['namex'] = 'Name';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -355,6 +358,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
diff --git a/program/localization/en_US/messages.inc b/program/localization/en_US/messages.inc
index f9b5e00a6..47b0f797d 100644
--- a/program/localization/en_US/messages.inc
+++ b/program/localization/en_US/messages.inc
@@ -101,13 +101,16 @@ $messages['converting'] = 'Removing formatting...';
$messages['messageopenerror'] = 'Could not load message from server.';
$messages['fileuploaderror'] = 'File upload failed.';
$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
-$messages['copysuccess'] = 'Successfully copied $nr addresses.';
-$messages['copyerror'] = 'Could not copy any addresses.';
+$messages['copysuccess'] = 'Successfully copied $nr contacts.';
+$messages['movesuccess'] = 'Successfully moved $nr contacts.';
+$messages['copyerror'] = 'Could not copy any contacts.';
+$messages['moveerror'] = 'Could not move any contacts.';
$messages['sourceisreadonly'] = 'This address source is read only.';
$messages['errorsavingcontact'] = 'Could not save the contact address.';
$messages['movingmessage'] = 'Moving message(s)...';
$messages['copyingmessage'] = 'Copying message(s)...';
$messages['copyingcontact'] = 'Copying contact(s)...';
+$messages['movingcontact'] = 'Moving contact(s)...';
$messages['deletingmessage'] = 'Deleting message(s)...';
$messages['markingmessage'] = 'Marking message(s)...';
$messages['addingmember'] = 'Adding contact(s) to the group...';
@@ -126,6 +129,8 @@ $messages['importwait'] = 'Importing, please wait...';
$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
+$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
+$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
$messages['opnotpermitted'] = 'Operation not permitted!';
$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
diff --git a/program/localization/eo/labels.inc b/program/localization/eo/labels.inc
index c088fc50e..3c2930c89 100644
--- a/program/localization/eo/labels.inc
+++ b/program/localization/eo/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Malnetujo';
$labels['sent'] = 'Senditujo';
$labels['trash'] = 'Rubujo';
$labels['junk'] = 'Spamujo';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Temo';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Dosierujo-agoj';
$labels['compact'] = 'Kompakta';
$labels['empty'] = 'Malplena';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Diskuzo';
$labels['unknown'] = 'nekonata';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Vakigu serĉon';
$labels['searchmod'] = 'Serĉ-opcioj';
$labels['msgtext'] = 'Tuta mesaÄo';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Malfermu en nova fenestro';
$labels['emlsave'] = 'ElÅutu (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Montru lastan';
$labels['group'] = 'Group';
$labels['groups'] = 'Grupoj';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Persona Adresoj';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/es_AR/labels.inc b/program/localization/es_AR/labels.inc
index d9a83be75..5bc53f7f0 100644
--- a/program/localization/es_AR/labels.inc
+++ b/program/localization/es_AR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Borradores';
$labels['sent'] = 'Enviados';
$labels['trash'] = 'Papelera';
$labels['junk'] = 'Basura';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Asunto';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Acciones de carpeta...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Vaciar';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'desconocido';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Reajustar la búsqueda';
$labels['searchmod'] = 'Opciones de búsqueda';
$labels['msgtext'] = 'Mensaje completo';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir en ventana nueva';
$labels['emlsave'] = 'Guardar (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Mostrar último grupo';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Direcciones personales';
$labels['searchsave'] = 'Guardar búsqueda';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/es_ES/labels.inc b/program/localization/es_ES/labels.inc
index 03f6b489a..11d14fa08 100644
--- a/program/localization/es_ES/labels.inc
+++ b/program/localization/es_ES/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Borradores';
$labels['sent'] = 'Enviados';
$labels['trash'] = 'Papelera';
$labels['junk'] = 'SPAM';
+$labels['show_real_foldernames'] = 'Mostrar nombres reales para carpetas especiales';
// message listing
$labels['subject'] = 'Asunto';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Modo de vista de lista';
$labels['folderactions'] = 'Acciones de bandeja...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Vaciar';
+$labels['importmessages'] = 'Importar mensajes';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'desconocido';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Reiniciar la búsqueda';
$labels['searchmod'] = 'Opciones de búsqueda';
$labels['msgtext'] = 'Mensaje completo';
$labels['body'] = 'Cuerpo';
+$labels['type'] = 'Tipo';
$labels['openinextwin'] = 'Abrir en nueva ventana';
$labels['emlsave'] = 'Descargar (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Mostrar último grupo';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
+$labels['listgroup'] = 'Listar miembros del grupo';
$labels['personaladrbook'] = 'Direcciones personales';
$labels['searchsave'] = 'Guardar búsqueda';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'Componer mensaje en HTML';
$labels['htmlonreply'] = 'sólo en respuesta a un mensaje HTML';
$labels['htmlonreplyandforward'] = 'en reenvío o respuesta al mensaje HTML';
$labels['htmlsignature'] = 'Firma HTML';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Mostrar dirección de correo electrónico al visualizar el nombre';
$labels['previewpane'] = 'Mostrar vista preliminar';
$labels['skin'] = 'Apariencia de la interfaz';
$labels['logoutclear'] = 'Vaciar papelera al cerrar sesión';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorar palabras con números';
$labels['spellcheckignorecaps'] = 'Ignorar palabras con todo mayúsculas';
$labels['addtodict'] = 'Añadir al diccionario';
$labels['mailtoprotohandler'] = 'Registrar controlador de protocolo para enlaces mailto:';
+$labels['standardwindows'] = 'Gestionar ventanas emergentes como ventanas estándar';
$labels['forwardmode'] = 'Reenvío de mensajes';
$labels['inline'] = 'en línea';
$labels['asattachment'] = 'como adjunto';
diff --git a/program/localization/es_ES/messages.inc b/program/localization/es_ES/messages.inc
index 6c031df29..d4bd81402 100644
--- a/program/localization/es_ES/messages.inc
+++ b/program/localization/es_ES/messages.inc
@@ -126,6 +126,8 @@ $messages['importwait'] = 'Importando, espere...';
$messages['importformaterror'] = '¡La importación falló! El fichero enviado no es un fichero válido de importación de datos';
$messages['importconfirm'] = '<b>Se han importado $inserted contactos correctamente</b>';
$messages['importconfirmskipped'] = '<b>Ignoradas $skipped entradas existentes</b>';
+$messages['importmessagesuccess'] = '$nr mensajes importados con éxito';
+$messages['importmessageerror'] = '¡Ha fallado la importación! El fichero subido no es un fichero válido de mensaje o buzón de correo';
$messages['opnotpermitted'] = '¡Operación no permitida!';
$messages['nofromaddress'] = 'El contacto seleccionado no tiene dirección de e-mail';
$messages['editorwarning'] = 'Cambiando a texto plano perderá el formato del mensaje. ¿Desea continuar?';
diff --git a/program/localization/et_EE/labels.inc b/program/localization/et_EE/labels.inc
index c3b3aa954..a8bc28403 100644
--- a/program/localization/et_EE/labels.inc
+++ b/program/localization/et_EE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Mustandid';
$labels['sent'] = 'Saadetud';
$labels['trash'] = 'Prügikast';
$labels['junk'] = 'Rämps';
+$labels['show_real_foldernames'] = 'Näita eriliste kaustade päris nimesid';
// message listing
$labels['subject'] = 'Pealkiri';
@@ -64,7 +65,7 @@ $labels['copy'] = 'Kopeeri';
$labels['move'] = 'Liiguta';
$labels['moveto'] = 'liiguta kausta...';
$labels['download'] = 'laadi arvutisse';
-$labels['open'] = 'Open';
+$labels['open'] = 'Ava';
$labels['showattachment'] = 'Näita';
$labels['showanyway'] = 'Näita ikka';
@@ -162,7 +163,7 @@ $labels['currpage'] = 'Praegune leht';
$labels['unread'] = 'Lugemata';
$labels['flagged'] = 'Märgistatud';
$labels['unanswered'] = 'Vastamata';
-$labels['withattachment'] = 'With attachment';
+$labels['withattachment'] = 'Koos manusega';
$labels['deleted'] = 'Kustutatud';
$labels['undeleted'] = 'Pole kustutatud';
$labels['invert'] = 'Vaheta';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Nimekirja vaatamise režiim';
$labels['folderactions'] = 'Kausta tegevused...';
$labels['compact'] = 'Tihenda';
$labels['empty'] = 'Tühjenda';
+$labels['importmessages'] = 'Impordi kirju';
$labels['quota'] = 'Kettakasutus';
$labels['unknown'] = 'teadmata';
@@ -203,11 +205,12 @@ $labels['resetsearch'] = 'Lähtesta otsing';
$labels['searchmod'] = 'Otsingu laiendid';
$labels['msgtext'] = 'Kogu kirjast';
$labels['body'] = 'Keha';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ava uues aknas';
$labels['emlsave'] = 'Salvesta (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Näita lihttekstina';
+$labels['changeformathtml'] = 'Näita HTMLis';
// message compose
$labels['editasnew'] = 'Kasuta uue kirja põhjana';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Näita viimast komplekti';
$labels['group'] = 'Grupp';
$labels['groups'] = 'Grupid';
+$labels['listgroup'] = 'Näita grupi liikmeid';
$labels['personaladrbook'] = 'Isiklikud aadressid';
$labels['searchsave'] = 'Salvesta otsing';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'Kasuta HTML redaktorit';
$labels['htmlonreply'] = 'vaid HTML-vormingus kirjale vastamisel';
$labels['htmlonreplyandforward'] = 'edastamisel või HTML kirjale vastates';
$labels['htmlsignature'] = 'HTML allkiri';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Näita nime juures e-posti aadressi';
$labels['previewpane'] = 'Näita eelvaate akent';
$labels['skin'] = 'Kliendi välimus';
$labels['logoutclear'] = 'Tühjenda väljumisel prügikast';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignoreeri sõnu, milles on numbreid';
$labels['spellcheckignorecaps'] = 'Ignoreeri suurte tähtedega kirjutatud sõnu';
$labels['addtodict'] = 'Lisa sõnastikku';
$labels['mailtoprotohandler'] = 'Kasuta mailto: linkide avamisel';
+$labels['standardwindows'] = 'Käsitle hüpikaknaid tavaliste akendena';
$labels['forwardmode'] = 'Kirja edastamine';
$labels['inline'] = 'kirja sees';
$labels['asattachment'] = 'manusena';
diff --git a/program/localization/et_EE/messages.inc b/program/localization/et_EE/messages.inc
index 0064eaf9d..4d58b0a75 100644
--- a/program/localization/et_EE/messages.inc
+++ b/program/localization/et_EE/messages.inc
@@ -28,8 +28,8 @@ $messages['dberror'] = 'Andmebaasi tõrge!';
$messages['requesttimedout'] = 'Päring aegus';
$messages['errorreadonly'] = 'Operatsioon nurjus. Kaustale on vaid lugemisõigus';
$messages['errornoperm'] = 'Operatsioon nurjus. Ligipääsu õigused puuduvad';
-$messages['erroroverquota'] = 'Unable to perform operation. No free disk space.';
-$messages['erroroverquotadelete'] = 'No free disk space. Use SHIFT+DEL to delete a message.';
+$messages['erroroverquota'] = 'Operatsioon nurjus. Ketas on täis.';
+$messages['erroroverquotadelete'] = 'Ketas on täis. Kirja kustutamiseks vajuta SHIFT+DEL.';
$messages['invalidrequest'] = 'Lubamatu päring! Andmeid ei salvestatud.';
$messages['invalidhost'] = 'Lubamatu serveri nimi.';
$messages['nomessagesfound'] = 'Postkast paistab tühi olevat';
@@ -126,6 +126,8 @@ $messages['importwait'] = 'Impordin, palun oota...';
$messages['importformaterror'] = 'Import nurjus! Laaditud fail ei sisalda sobilikke andmeid.';
$messages['importconfirm'] = '<b>Edukalt imporditud $inserted kontakti, $skipped olemasolevat sissekannet vahele jäetud</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b> $skipped olemasolevat kirjet jäeti vahele</b>';
+$messages['importmessagesuccess'] = '$nr kirja edukalt imporditud';
+$messages['importmessageerror'] = 'Import nurjus! Laaditud fail ei ole kirja ega postkasti fail';
$messages['opnotpermitted'] = 'Tegevus pole lubatud!';
$messages['nofromaddress'] = 'Valitud identiteedil puudub e-posti aadress';
$messages['editorwarning'] = 'Klaarteksti redaktorile lülitamine kaotab kogu teksti vorminduse. Soovid jätkata?';
diff --git a/program/localization/eu_ES/labels.inc b/program/localization/eu_ES/labels.inc
index 8052d69e8..fedce7de5 100644
--- a/program/localization/eu_ES/labels.inc
+++ b/program/localization/eu_ES/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Zirriborroak';
$labels['sent'] = 'Bidalitakoak';
$labels['trash'] = 'Zakarrontzia';
$labels['junk'] = 'Zabor-posta';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Gaia';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Trinkotu';
$labels['empty'] = 'Hustu';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disko erabilera';
$labels['unknown'] = 'ezezaguna';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Bilaketa berrabiarazi';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Lehio berrian ireki';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Azken sorta ikusi';
$labels['group'] = 'Group';
$labels['groups'] = 'Taldeak';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Helbide pertsonalak';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/fa_AF/labels.inc b/program/localization/fa_AF/labels.inc
index 70113bc49..38154c23c 100644
--- a/program/localization/fa_AF/labels.inc
+++ b/program/localization/fa_AF/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'نامه های ناتکمیل';
$labels['sent'] = 'ارسال شده';
$labels['trash'] = 'اشغال دانی';
$labels['junk'] = 'بیکاره';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'مضمون';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'خلاصه';
$labels['empty'] = 'خالي';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = '‌طريقه استعمال ديسک';
$labels['unknown'] = 'نامعلوم';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'بازنشاندن جستجو';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'در پینجره ای جدید باز کنید';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'بسته اخير را نشان دهيد';
$labels['group'] = 'Group';
$labels['groups'] = 'گروه ها';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ادرس های شخصي';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/fa_IR/labels.inc b/program/localization/fa_IR/labels.inc
index 221e4b891..79bfbbe9d 100644
--- a/program/localization/fa_IR/labels.inc
+++ b/program/localization/fa_IR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'پیش‌نویس‌ها';
$labels['sent'] = 'Ùرستاده شده';
$labels['trash'] = 'سطل آشغال';
$labels['junk'] = 'بنجل';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'موضوع';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'نوع مشاهده Ùهرست';
$labels['folderactions'] = 'اعمال پوشه...';
$labels['compact'] = 'Ùشرده';
$labels['empty'] = 'خالی';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Ùضای استÙاده شده';
$labels['unknown'] = 'ناشناخته';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'جستجوی دوباره';
$labels['searchmod'] = 'اصلاحات جستجو';
$labels['msgtext'] = 'کل پیغام';
$labels['body'] = 'بدنه';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'باز کردن در پنجره‌ی جدید';
$labels['emlsave'] = 'بارگیری (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'نمایش صÙحه آخر';
$labels['group'] = 'گروه';
$labels['groups'] = 'گروه‌ها';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'نشانی‌های شخصی';
$labels['searchsave'] = 'ذخیره جستجو';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'نادیده گرÙتن کلمات دارای
$labels['spellcheckignorecaps'] = 'نادیده گرÙتن کلمات با حرو٠بزرگ';
$labels['addtodict'] = 'اضاÙÙ‡ کردن به واژه‌نامه';
$labels['mailtoprotohandler'] = 'ثبت نگه‌دارنده پروتوکل برای mailto: پیوندها';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'بازگردانی پیغام';
$labels['inline'] = 'خطی';
$labels['asattachment'] = 'به عنوان پیوست';
diff --git a/program/localization/fi_FI/labels.inc b/program/localization/fi_FI/labels.inc
index 006f62947..ef0f0bff0 100644
--- a/program/localization/fi_FI/labels.inc
+++ b/program/localization/fi_FI/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Luonnokset';
$labels['sent'] = 'Lähetetyt';
$labels['trash'] = 'Roskakori';
$labels['junk'] = 'Roskaposti';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Aihe';
@@ -162,7 +163,7 @@ $labels['currpage'] = 'Nykyinen sivu';
$labels['unread'] = 'Lukemattomat';
$labels['flagged'] = 'Korostettu';
$labels['unanswered'] = 'Vastaamaton';
-$labels['withattachment'] = 'With attachment';
+$labels['withattachment'] = 'Liitteen kera';
$labels['deleted'] = 'Poistettu';
$labels['undeleted'] = 'Ei poistettu';
$labels['invert'] = 'Käännä';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Listausnäkymä';
$labels['folderactions'] = 'Kansiotoiminnot...';
$labels['compact'] = 'Tiivistä';
$labels['empty'] = 'Tyhjennä';
+$labels['importmessages'] = 'Tuo viestejä';
$labels['quota'] = 'Levytila';
$labels['unknown'] = 'tuntematon';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Nollaa haku';
$labels['searchmod'] = 'Hakukriteerit';
$labels['msgtext'] = 'Koko viesti';
$labels['body'] = 'Runko';
+$labels['type'] = 'Tyyppi';
$labels['openinextwin'] = 'Avaa uudessa ikkunassa';
$labels['emlsave'] = 'Tallenna (.eml)';
@@ -245,9 +248,9 @@ $labels['nosubject'] = '(ei otsikkoa)';
$labels['showimages'] = 'Näytä kuvat';
$labels['alwaysshow'] = 'Näytä aina lähettäjältä $sender saapuneet kuvat';
$labels['isdraft'] = 'Tämä on luonnosviesti.';
-$labels['andnmore'] = '$nr more...';
+$labels['andnmore'] = '$nr lisää...';
$labels['togglemoreheaders'] = 'Näytä lisää viestiotsakkeita';
-$labels['togglefullheaders'] = 'Toggle raw message headers';
+$labels['togglefullheaders'] = 'Viestin otsakkeet päällä/pois';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Tavallinen teksti';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Näytä viimeinen luettelo';
$labels['group'] = 'Ryhmä';
$labels['groups'] = 'Ryhmät';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Henkilökohtaiset osoitteet';
$labels['searchsave'] = 'Tallenna haku';
@@ -400,7 +404,7 @@ $labels['showinextwin'] = 'Avaa viesti uudessa ikkunassa';
$labels['composeextwin'] = 'Lähetä viesti uudessa ikkunassa';
$labels['htmleditor'] = 'Kirjoita HTML-muodossa';
$labels['htmlonreply'] = 'Vain vastatessa HTML-viesteihin';
-$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
+$labels['htmlonreplyandforward'] = 'välittäessä tai vastatessa HTML-viestiin';
$labels['htmlsignature'] = 'HTML-allekirjoitus';
$labels['showemail'] = 'Näytä sähköpostiosoite näyttönimen kanssa';
$labels['previewpane'] = 'Näytä esikatselulehti';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Jätä huomiotta sanat, joissa on numeroita';
$labels['spellcheckignorecaps'] = 'Jätä huomiotta sanat, joissa kaikki kirjaimet on isoja';
$labels['addtodict'] = 'Lisää sanakirjaan';
$labels['mailtoprotohandler'] = 'Rekisteröi mailto:-linkkien protokollakäsitteljä';
+$labels['standardwindows'] = 'Käsittele popup-ikkunoita tavallisina ikkunoina';
$labels['forwardmode'] = 'Viestin välitys';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'liitteenä';
diff --git a/program/localization/fr_FR/labels.inc b/program/localization/fr_FR/labels.inc
index 6731ecc3f..2a4f3a169 100644
--- a/program/localization/fr_FR/labels.inc
+++ b/program/localization/fr_FR/labels.inc
@@ -26,9 +26,9 @@ $labels['server'] = 'Serveur';
$labels['login'] = 'Connexion';
// taskbar
-$labels['logout'] = 'Quitter';
+$labels['logout'] = 'Déconnexion';
$labels['mail'] = 'Courriel';
-$labels['settings'] = 'Préférences';
+$labels['settings'] = 'Paramètres';
$labels['addressbook'] = 'Carnet d\'adresses';
// mailbox names
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Brouillons';
$labels['sent'] = 'Messages envoyés';
$labels['trash'] = 'Corbeille';
$labels['junk'] = 'Indésirables';
+$labels['show_real_foldernames'] = 'Montrer les noms réels pour les dossiers spéciaux';
// message listing
$labels['subject'] = 'Objet';
@@ -127,7 +128,7 @@ $labels['checkmail'] = 'Vérification des nouveaux messages';
$labels['compose'] = 'Composer un nouveau message';
$labels['writenewmessage'] = 'Écrire un nouveau message';
$labels['reply'] = 'Répondre';
-$labels['replytomessage'] = 'Répondre au message';
+$labels['replytomessage'] = 'Répondre à l\'expéditeur';
$labels['replytoallmessage'] = 'Répondre à tous';
$labels['replyall'] = 'Répondre à tous';
$labels['replylist'] = 'Répondre à la liste';
@@ -146,10 +147,10 @@ $labels['backtolist'] = 'Retourner à la liste des messages';
$labels['viewsource'] = 'Voir la source';
$labels['mark'] = 'Marquer';
$labels['markmessages'] = 'Marquer les messages';
-$labels['markread'] = 'Comme lus';
-$labels['markunread'] = 'Comme non lus';
-$labels['markflagged'] = 'Comme suivi';
-$labels['markunflagged'] = 'Comme non-suivi';
+$labels['markread'] = 'Comme lu(s)';
+$labels['markunread'] = 'Comme non lu(s)';
+$labels['markflagged'] = 'Comme suivi(s)';
+$labels['markunflagged'] = 'Comme non-suivi(s)';
$labels['moreactions'] = 'Plus d\'actions...';
$labels['more'] = 'Plus';
$labels['back'] = 'Retour';
@@ -159,19 +160,19 @@ $labels['select'] = 'Sélectionner';
$labels['all'] = 'Tous';
$labels['none'] = 'Aucun';
$labels['currpage'] = 'Page courante';
-$labels['unread'] = 'Non lus';
-$labels['flagged'] = 'Marqué';
-$labels['unanswered'] = 'Non répondu';
+$labels['unread'] = 'Non lu(s)';
+$labels['flagged'] = 'Marqué(s)';
+$labels['unanswered'] = 'Non répondu(s)';
$labels['withattachment'] = 'Avec pièce jointe';
-$labels['deleted'] = 'Supprimé';
-$labels['undeleted'] = 'Non supprimé';
+$labels['deleted'] = 'Supprimé(s)';
+$labels['undeleted'] = 'Non supprimé(s)';
$labels['invert'] = 'Inverser';
$labels['filter'] = 'Filtre';
$labels['list'] = 'Lister';
$labels['threads'] = 'Sujets';
-$labels['expand-all'] = 'Afficher Tous';
-$labels['expand-unread'] = 'Afficher Non-lus';
-$labels['collapse-all'] = 'Fermer Tous';
+$labels['expand-all'] = 'Tout afficher';
+$labels['expand-unread'] = 'Afficher non-lu(s)';
+$labels['collapse-all'] = 'Fermer tous';
$labels['threaded'] = 'Par sujet';
$labels['autoexpand_threads'] = 'Développer les sujets';
@@ -190,9 +191,10 @@ $labels['listsorting'] = 'Colonne de tri';
$labels['listorder'] = 'Ordre de tri';
$labels['listmode'] = 'Mode d\'affichage de la liste';
-$labels['folderactions'] = 'Actions du dossier';
+$labels['folderactions'] = 'Actions du dossier...';
$labels['compact'] = 'Compacter';
$labels['empty'] = 'Vider';
+$labels['importmessages'] = 'Importer des messages';
$labels['quota'] = 'Occupation disque';
$labels['unknown'] = 'inconnue';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Réinitialiser la recherche';
$labels['searchmod'] = 'Portée de la recherche';
$labels['msgtext'] = 'Message entier';
$labels['body'] = 'Corps';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ouvrir dans une nouvelle fenêtre';
$labels['emlsave'] = 'Télécharger (.eml)';
@@ -212,8 +215,8 @@ $labels['changeformathtml'] = 'Afficher au format HTML';
// message compose
$labels['editasnew'] = 'Éditer en tant que nouveau message';
$labels['send'] = 'Envoyer';
-$labels['sendmessage'] = 'Envoyer';
-$labels['savemessage'] = 'Enregistrer';
+$labels['sendmessage'] = 'Envoyer un message';
+$labels['savemessage'] = 'Sauvegarder comme brouillon';
$labels['addattachment'] = 'Joindre un fichier';
$labels['charset'] = 'Encodage';
$labels['editortype'] = 'Type d\'éditeur';
@@ -223,14 +226,14 @@ $labels['mailreplyintro'] = 'Le $date, $sender a écrit :';
$labels['originalmessage'] = 'Message original';
$labels['editidents'] = 'Modifier les identités';
-$labels['spellcheck'] = 'Vérifier l\'orthographe';
+$labels['spellcheck'] = 'Orthographe';
$labels['checkspelling'] = 'Vérifier l\'orthographe';
$labels['resumeediting'] = 'Retourner à l\'édition';
$labels['revertto'] = 'Revenir à';
$labels['attach'] = 'Joindre';
$labels['attachments'] = 'Fichiers joints';
-$labels['upload'] = 'Joindre';
+$labels['upload'] = 'Transférer';
$labels['uploadprogress'] = '$percent ($current sur $total)';
$labels['close'] = 'Fermer';
$labels['messageoptions'] = 'Options du message';
@@ -250,7 +253,7 @@ $labels['togglemoreheaders'] = 'Afficher plus d\'en-têtes du message';
$labels['togglefullheaders'] = 'Afficher/Cacher l\'entête du message';
$labels['htmltoggle'] = 'HTML';
-$labels['plaintoggle'] = 'texte brut';
+$labels['plaintoggle'] = 'Texte brut';
$labels['savesentmessagein'] = 'Enregistrer le message envoyé dans';
$labels['dontsave'] = 'ne pas enregistrer';
$labels['maxuploadsize'] = 'La taille maximum autorisée pour un fichier est $size';
@@ -264,7 +267,7 @@ $labels['addfollowupto'] = 'Ajouter Faire suivre à';
$labels['mdnrequest'] = 'L\'expéditeur de ce message a demandé d\'être prévenu quand vous lirez ce message. Souhaitez-vous prévenir l\'expéditeur ?';
$labels['receiptread'] = 'Accusé de réception (lu)';
$labels['yourmessage'] = 'Ceci est un accusé de réception pour votre message';
-$labels['receiptnote'] = 'Note : Cet accusé de réception indique seulement que le message a été affiché sur l\'ordinateur du destinataire. Il n\'y a aucune garantie que le destinataire a lu ou compris le contenu du message.';
+$labels['receiptnote'] = 'Note : Cet accusé de réception indique seulement que le message a été affiché sur l\'ordinateur du destinataire. Il n\'y a aucune garantie que le destinataire ait lu ou compris le contenu du message.';
// address boook
$labels['name'] = 'Nom à afficher';
@@ -275,9 +278,9 @@ $labels['nameprefix'] = 'Préfixe';
$labels['namesuffix'] = 'Suffixe';
$labels['nickname'] = 'Surnom';
$labels['jobtitle'] = 'Fonction';
-$labels['department'] = 'Département';
+$labels['department'] = 'Service';
$labels['gender'] = 'Sexe';
-$labels['maidenname'] = 'Nom de naissance';
+$labels['maidenname'] = 'Nom de jeune fille';
$labels['email'] = 'Courriel';
$labels['phone'] = 'Téléphone';
$labels['address'] = 'Adresse';
@@ -318,7 +321,7 @@ $labels['typeblog'] = 'Blog';
$labels['typeprofile'] = 'Profil';
$labels['addfield'] = 'Ajouter un champ...';
-$labels['addcontact'] = 'Ajouter le contact sélectionné à votre Carnet d\'adresses';
+$labels['addcontact'] = 'Ajouter le contact sélectionné à votre carnet d\'adresses';
$labels['editcontact'] = 'Modifier le contact';
$labels['contacts'] = 'Contacts';
$labels['contactproperties'] = 'Propriétés du contact';
@@ -331,7 +334,7 @@ $labels['delete'] = 'Supprimer';
$labels['rename'] = 'Renommer';
$labels['addphoto'] = 'Ajouter';
$labels['replacephoto'] = 'Remplacer';
-$labels['uploadphoto'] = 'Envoyer une photo';
+$labels['uploadphoto'] = 'Transférer une photo';
$labels['newcontact'] = 'Créer un nouveau contact';
$labels['deletecontact'] = 'Supprimer les contacts sélectionnés';
@@ -345,7 +348,7 @@ $labels['exportvcards'] = 'Exporter les contacts au format vCard';
$labels['newcontactgroup'] = 'Créer un nouveau groupe de contacts';
$labels['grouprename'] = 'Renommer le groupe';
$labels['groupdelete'] = 'Supprimer le groupe';
-$labels['groupremoveselected'] = 'Retiré les contacts sélectionnés du groupe';
+$labels['groupremoveselected'] = 'Retirer les contacts sélectionnés du groupe';
$labels['previouspage'] = 'Montrer page précédente';
$labels['firstpage'] = 'Voir la première page';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Voir la dernière page';
$labels['group'] = 'Groupe';
$labels['groups'] = 'Groupes';
+$labels['listgroup'] = 'Liste des membres du groupe';
$labels['personaladrbook'] = 'Adresses personnelles';
$labels['searchsave'] = 'Enregistrer la recherche';
@@ -362,9 +366,9 @@ $labels['searchdelete'] = 'Supprimer la recherche';
$labels['import'] = 'Importer';
$labels['importcontacts'] = 'Importer les contacts';
$labels['importfromfile'] = 'Importer depuis un fichier :';
-$labels['importtarget'] = 'Ajouter de nouveaux contact au carnet d’adresse :';
-$labels['importreplace'] = 'Remplacer le carnet d\'adresse entier';
-$labels['importdesc'] = 'Vous pouvez télécharger des contacts à partir d\'un carnet d\'adresses existant.<br/>Nous supportons actuellement l\'importation d\'adresses à partir des format de données <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> ou CSV (comma -séparés).';
+$labels['importtarget'] = 'Ajouter de nouveaux contact au carnet d’adresses :';
+$labels['importreplace'] = 'Remplacer le carnet d\'adresses entier';
+$labels['importdesc'] = 'Vous pouvez transférer des contacts à partir d\'un carnet d\'adresses existant.<br/>Nous supportons actuellement l\'importation d\'adresses à partir des format de données <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> ou CSV (champs séparés par une virgule).';
$labels['done'] = 'Terminé';
// settings
@@ -402,13 +406,13 @@ $labels['htmleditor'] = 'Composer un message au format HTML';
$labels['htmlonreply'] = 'en réponse aux messages HTML uniquement';
$labels['htmlonreplyandforward'] = 'Transférer ou répondre au message HTML';
$labels['htmlsignature'] = 'Signature HTML';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Montrer l\'adresse de courriel avec le nom complet';
$labels['previewpane'] = 'Afficher le panneau d\'aperçu';
$labels['skin'] = 'Thème de l\'interface';
$labels['logoutclear'] = 'Vider la corbeille à la déconnexion';
$labels['logoutcompact'] = 'Compacter la boite de réception à la déconnexion';
$labels['uisettings'] = 'Interface utilisateur';
-$labels['serversettings'] = 'Préférences du serveur';
+$labels['serversettings'] = 'Paramètres du serveur';
$labels['mailboxview'] = 'Vue du courrier';
$labels['mdnrequests'] = 'Notifications à l\'expéditeur';
$labels['askuser'] = 'demander à l\'utilisateur';
@@ -452,7 +456,7 @@ $labels['whenreplying'] = 'En répondant';
$labels['replyempty'] = 'Ne pas citer le message original';
$labels['replytopposting'] = 'commencer le nouveau message au-dessus de l\'original';
$labels['replybottomposting'] = 'commencer le nouveau message en-dessous de l\'original';
-$labels['replyremovesignature'] = 'En répondant, supprimer la signature d\'origine du message';
+$labels['replyremovesignature'] = 'Supprimer la signature d\'origine du message lors de la réponse';
$labels['autoaddsignature'] = 'Ajouter la signature automatiquement';
$labels['newmessageonly'] = 'nouveau message uniquement';
$labels['replyandforwardonly'] = 'réponses et transferts uniquement';
@@ -462,16 +466,17 @@ $labels['afternseconds'] = 'après $n secondes';
$labels['reqmdn'] = 'Toujours demander un avis de réception';
$labels['reqdsn'] = 'Toujours demander une notification d\'état de distribution';
$labels['replysamefolder'] = 'Placer les réponses dans le dossier du message auquel il est répondu';
-$labels['defaultabook'] = 'Carnet d\'adresse par défaut';
-$labels['autocompletesingle'] = 'Ne pas tenir compte des adresses emails alternatives dans l\'autoremplissage';
+$labels['defaultabook'] = 'Carnet d\'adresses par défaut';
+$labels['autocompletesingle'] = 'Ne pas tenir compte des adresses de courriel alternatives dans l\'autoremplissage';
$labels['listnamedisplay'] = 'Lister les contacts comme';
-$labels['spellcheckbeforesend'] = 'Vérifier l’orthographe avant l’envoie d’un message';
+$labels['spellcheckbeforesend'] = 'Vérifier l’orthographe avant l’envoi d’un message';
$labels['spellcheckoptions'] = 'Options du vérificateur d\'orthographe';
$labels['spellcheckignoresyms'] = 'Ignorer les mots avec des symboles';
$labels['spellcheckignorenums'] = 'Ignorer les mots avec des nombres';
$labels['spellcheckignorecaps'] = 'Ignorer les mots entièrement en majuscule';
$labels['addtodict'] = 'Ajouter au dictionnaire';
$labels['mailtoprotohandler'] = 'Enregistrer le gestionnaire de protocole pour les liens mailto:';
+$labels['standardwindows'] = 'Manipuler les menus surgissants comme des fenêtres standards';
$labels['forwardmode'] = 'Transfert des messages';
$labels['inline'] = 'dans le corps';
$labels['asattachment'] = 'en pièce jointe';
@@ -507,7 +512,7 @@ $labels['plugin'] = 'Plugin';
$labels['version'] = 'Version';
$labels['source'] = 'Source';
$labels['license'] = 'Licence';
-$labels['support'] = 'Support';
+$labels['support'] = 'Obtenir un support technique';
// units
$labels['B'] = 'o';
diff --git a/program/localization/fy_NL/labels.inc b/program/localization/fy_NL/labels.inc
index 891371f58..5ffd906eb 100644
--- a/program/localization/fy_NL/labels.inc
+++ b/program/localization/fy_NL/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Konsepten';
$labels['sent'] = 'Stjoerd';
$labels['trash'] = 'Jiskefet';
$labels['junk'] = 'Junk';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Ûnderwerp';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Compact';
$labels['empty'] = 'Empty';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'unknown';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/fy_NL/messages.inc b/program/localization/fy_NL/messages.inc
index 1dacf4adc..16f4c67bf 100644
--- a/program/localization/fy_NL/messages.inc
+++ b/program/localization/fy_NL/messages.inc
@@ -2,15 +2,172 @@
/*
+-----------------------------------------------------------------------+
- | localization/fy_NL/messages.inc |
+ | localization/<lang>/messages.inc |
| |
- | Language file of the Roundcube Webmail client |
- | Copyright (C) 2012, The Roundcube Dev Team |
- | Licensed under the GNU General Public License |
+ | Localization file 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. |
| |
+-----------------------------------------------------------------------+
- | Author: unknown |
- +-----------------------------------------------------------------------+
+
+ For translation see https://www.transifex.com/projects/p/roundcube-webmail/resource/messages/
*/
-$messages = array(); \ No newline at end of file
+$messages = array();
+$messages['errortitle'] = 'An error occurred!';
+$messages['loginfailed'] = 'Login failed.';
+$messages['cookiesdisabled'] = 'Your browser does not accept cookies.';
+$messages['sessionerror'] = 'Your session is invalid or expired.';
+$messages['storageerror'] = 'Connection to storage server failed.';
+$messages['servererror'] = 'Server Error!';
+$messages['servererrormsg'] = 'Server Error: $msg';
+$messages['dberror'] = 'Database Error!';
+$messages['requesttimedout'] = 'Request timed out';
+$messages['errorreadonly'] = 'Unable to perform operation. Folder is read-only.';
+$messages['errornoperm'] = 'Unable to perform operation. Permission denied.';
+$messages['erroroverquota'] = 'Unable to perform operation. No free disk space.';
+$messages['erroroverquotadelete'] = 'No free disk space. Use SHIFT+DEL to delete a message.';
+$messages['invalidrequest'] = 'Invalid request! No data was saved.';
+$messages['invalidhost'] = 'Invalid server name.';
+$messages['nomessagesfound'] = 'No messages found in this mailbox.';
+$messages['loggedout'] = 'You have successfully terminated the session. Good bye!';
+$messages['mailboxempty'] = 'Mailbox is empty.';
+$messages['refreshing'] = 'Refreshing...';
+$messages['loading'] = 'Loading...';
+$messages['uploading'] = 'Uploading file...';
+$messages['uploadingmany'] = 'Uploading files...';
+$messages['loadingdata'] = 'Loading data...';
+$messages['checkingmail'] = 'Checking for new messages...';
+$messages['sendingmessage'] = 'Sending message...';
+$messages['messagesent'] = 'Message sent successfully.';
+$messages['savingmessage'] = 'Saving message...';
+$messages['messagesaved'] = 'Message saved to Drafts.';
+$messages['successfullysaved'] = 'Successfully saved.';
+$messages['addedsuccessfully'] = 'Contact added successfully to address book.';
+$messages['contactexists'] = 'A contact with the same e-mail address already exists.';
+$messages['contactnameexists'] = 'A contact with the same name already exists.';
+$messages['blockedimages'] = 'To protect your privacy, remote images are blocked in this message.';
+$messages['encryptedmessage'] = 'This is an encrypted message and can not be displayed. Sorry!';
+$messages['nocontactsfound'] = 'No contacts found.';
+$messages['contactnotfound'] = 'The requested contact was not found.';
+$messages['contactsearchonly'] = 'Enter some search terms to find contacts';
+$messages['sendingfailed'] = 'Failed to send message.';
+$messages['senttooquickly'] = 'Please wait $sec sec(s). before sending this message.';
+$messages['errorsavingsent'] = 'An error occured while saving sent message.';
+$messages['errorsaving'] = 'An error occured while saving.';
+$messages['errormoving'] = 'Could not move the message(s).';
+$messages['errorcopying'] = 'Could not copy the message(s).';
+$messages['errordeleting'] = 'Could not delete the message(s).';
+$messages['errormarking'] = 'Could not mark the message(s).';
+$messages['deletecontactconfirm'] = 'Do you really want to delete selected contact(s)?';
+$messages['deletegroupconfirm'] = 'Do you really want to delete selected group?';
+$messages['deletemessagesconfirm'] = 'Do you really want to delete selected message(s)?';
+$messages['deletefolderconfirm'] = 'Do you really want to delete this folder?';
+$messages['purgefolderconfirm'] = 'Do you really want to delete all messages in this folder?';
+$messages['contactdeleting'] = 'Deleting contact(s)...';
+$messages['groupdeleting'] = 'Deleting group...';
+$messages['folderdeleting'] = 'Deleting folder...';
+$messages['foldermoving'] = 'Moving folder...';
+$messages['foldersubscribing'] = 'Subscribing folder...';
+$messages['folderunsubscribing'] = 'Unsubscribing folder...';
+$messages['formincomplete'] = 'The form was not completely filled out.';
+$messages['noemailwarning'] = 'Please enter a valid email address.';
+$messages['nonamewarning'] = 'Please enter a name.';
+$messages['nopagesizewarning'] = 'Please enter a page size.';
+$messages['nosenderwarning'] = 'Please enter sender e-mail address.';
+$messages['norecipientwarning'] = 'Please enter at least one recipient.';
+$messages['nosubjectwarning'] = 'The "Subject" field is empty. Would you like to enter one now?';
+$messages['nobodywarning'] = 'Send this message without text?';
+$messages['notsentwarning'] = 'Message has not been sent. Do you want to discard your message?';
+$messages['noldapserver'] = 'Please select an ldap server to search.';
+$messages['nosearchname'] = 'Please enter a contact name or email address.';
+$messages['notuploadedwarning'] = 'Not all attachments have been uploaded yet. Please wait or cancel the upload.';
+$messages['searchsuccessful'] = '$nr messages found.';
+$messages['contactsearchsuccessful'] = '$nr contacts found.';
+$messages['searchnomatch'] = 'Search returned no matches.';
+$messages['searching'] = 'Searching...';
+$messages['checking'] = 'Checking...';
+$messages['nospellerrors'] = 'No spelling errors found.';
+$messages['folderdeleted'] = 'Folder successfully deleted.';
+$messages['foldersubscribed'] = 'Folder successfully subscribed.';
+$messages['folderunsubscribed'] = 'Folder successfully unsubscribed.';
+$messages['folderpurged'] = 'Folder has successfully been emptied.';
+$messages['folderexpunged'] = 'Folder has successfully been compacted.';
+$messages['deletedsuccessfully'] = 'Successfully deleted.';
+$messages['converting'] = 'Removing formatting...';
+$messages['messageopenerror'] = 'Could not load message from server.';
+$messages['fileuploaderror'] = 'File upload failed.';
+$messages['filesizeerror'] = 'The uploaded file exceeds the maximum size of $size.';
+$messages['copysuccess'] = 'Successfully copied $nr addresses.';
+$messages['copyerror'] = 'Could not copy any addresses.';
+$messages['sourceisreadonly'] = 'This address source is read only.';
+$messages['errorsavingcontact'] = 'Could not save the contact address.';
+$messages['movingmessage'] = 'Moving message(s)...';
+$messages['copyingmessage'] = 'Copying message(s)...';
+$messages['copyingcontact'] = 'Copying contact(s)...';
+$messages['deletingmessage'] = 'Deleting message(s)...';
+$messages['markingmessage'] = 'Marking message(s)...';
+$messages['addingmember'] = 'Adding contact(s) to the group...';
+$messages['removingmember'] = 'Removing contact(s) from the group...';
+$messages['receiptsent'] = 'Successfully sent a read receipt.';
+$messages['errorsendingreceipt'] = 'Could not send the receipt.';
+$messages['deleteidentityconfirm'] = 'Do you really want to delete this identity?';
+$messages['nodeletelastidentity'] = 'You cannot delete this identity, it\'s your last one.';
+$messages['forbiddencharacter'] = 'Folder name contains a forbidden character.';
+$messages['selectimportfile'] = 'Please select a file to upload.';
+$messages['addresswriterror'] = 'The selected address book is not writeable.';
+$messages['contactaddedtogroup'] = 'Successfully added the contacts to this group.';
+$messages['contactremovedfromgroup'] = 'Successfully removed contacts from this group.';
+$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
+$messages['importwait'] = 'Importing, please wait...';
+$messages['importformaterror'] = 'Import failed! The uploaded file is not a valid import data file.';
+$messages['importconfirm'] = '<b>Successfully imported $inserted contacts</b>';
+$messages['importconfirmskipped'] = '<b>Skipped $skipped existing entries</b>';
+$messages['importmessagesuccess'] = 'Successfully imported $nr messages';
+$messages['importmessageerror'] = 'Import failed! The uploaded file is not a valid message or mailbox file';
+$messages['opnotpermitted'] = 'Operation not permitted!';
+$messages['nofromaddress'] = 'Missing e-mail address in selected identity.';
+$messages['editorwarning'] = 'Switching to the plain text editor will cause all text formatting to be lost. Do you wish to continue?';
+$messages['httpreceivedencrypterror'] = 'A fatal configuration error occurred. Contact your administrator immediately. <b>Your message can not be sent.</b>';
+$messages['smtpconnerror'] = 'SMTP Error ($code): Connection to server failed.';
+$messages['smtpautherror'] = 'SMTP Error ($code): Authentication failed.';
+$messages['smtpfromerror'] = 'SMTP Error ($code): Failed to set sender "$from" ($msg).';
+$messages['smtptoerror'] = 'SMTP Error ($code): Failed to add recipient "$to" ($msg).';
+$messages['smtprecipientserror'] = 'SMTP Error: Unable to parse recipients list.';
+$messages['smtperror'] = 'SMTP Error: $msg';
+$messages['emailformaterror'] = 'Invalid e-mail address: $email';
+$messages['toomanyrecipients'] = 'Too many recipients. Reduce the number of recipients to $max.';
+$messages['maxgroupmembersreached'] = 'The number of group members exceeds the maximum of $max.';
+$messages['internalerror'] = 'An internal error occured. Please try again.';
+$messages['contactdelerror'] = 'Could not delete contact(s).';
+$messages['contactdeleted'] = 'Contact(s) deleted successfully.';
+$messages['contactrestoreerror'] = 'Could not restore deleted contact(s).';
+$messages['contactrestored'] = 'Contact(s) restored successfully.';
+$messages['groupdeleted'] = 'Group deleted successfully.';
+$messages['grouprenamed'] = 'Group renamed successfully.';
+$messages['groupcreated'] = 'Group created successfully.';
+$messages['savedsearchdeleted'] = 'Saved search deleted successfully.';
+$messages['savedsearchdeleteerror'] = 'Could not delete saved search.';
+$messages['savedsearchcreated'] = 'Saved search created successfully.';
+$messages['savedsearchcreateerror'] = 'Could not create saved search.';
+$messages['messagedeleted'] = 'Message(s) deleted successfully.';
+$messages['messagemoved'] = 'Message(s) moved successfully.';
+$messages['messagecopied'] = 'Message(s) copied successfully.';
+$messages['messagemarked'] = 'Message(s) marked successfully.';
+$messages['autocompletechars'] = 'Enter at least $min characters for autocompletion.';
+$messages['autocompletemore'] = 'More matching entries found. Please type more characters.';
+$messages['namecannotbeempty'] = 'Name cannot be empty.';
+$messages['nametoolong'] = 'Name is too long.';
+$messages['folderupdated'] = 'Folder updated successfully.';
+$messages['foldercreated'] = 'Folder created successfully.';
+$messages['invalidimageformat'] = 'Not a valid image format.';
+$messages['mispellingsfound'] = 'Spelling errors detected in the message.';
+$messages['parentnotwritable'] = 'Unable to create/move folder into selected parent folder. No access rights.';
+$messages['messagetoobig'] = 'The message part is too big to process it.';
+$messages['attachmentvalidationerror'] = 'WARNING! This attachment is suspicious because its type doesn\'t match the type declared in the message. If you do not trust the sender, you shouldn\'t open it in the browser because it may contain malicious contents.<br/><br/><em>Expected: $expected; found: $detected</em>';
+$messages['noscriptwarning'] = 'Warning: This webmail service requires Javascript! In order to use it please enable Javascript in your browser\'s settings.';
+
+?>
diff --git a/program/localization/ga_IE/labels.inc b/program/localization/ga_IE/labels.inc
index 9f0da6550..9fffaf42a 100755
--- a/program/localization/ga_IE/labels.inc
+++ b/program/localization/ga_IE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Dréachtaí';
$labels['sent'] = 'Amach';
$labels['trash'] = 'Bosca bruscair';
$labels['junk'] = 'Dramhaíl';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Ãbhair';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Comhbhrúigh';
$labels['empty'] = 'Folmhaigh';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Toilleadh diosca atá athláimhe';
$labels['unknown'] = 'gan aithne';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Athshocraigh an cuardach';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Taispeáin an foireann deireanach';
$labels['group'] = 'Group';
$labels['groups'] = 'Grúpaí';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Seoltaí Pearsanta';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/gl_ES/labels.inc b/program/localization/gl_ES/labels.inc
index 5905ea4b9..c624c462e 100644
--- a/program/localization/gl_ES/labels.inc
+++ b/program/localization/gl_ES/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Borradores';
$labels['sent'] = 'Enviados';
$labels['trash'] = 'Cubo do lixo';
$labels['junk'] = 'Correo lixo';
+$labels['show_real_foldernames'] = 'Amosar nomes reáis para cartafois especiáis';
// message listing
$labels['subject'] = 'Asunto';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Modo de vista da lista';
$labels['folderactions'] = 'Accións cos cartafoles';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Baleirar';
+$labels['importmessages'] = 'Importar mensaxes';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'descoñecido';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Restablecer a busca';
$labels['searchmod'] = 'Modificadores de busca';
$labels['msgtext'] = 'Mensaxe enteira';
$labels['body'] = 'Corpo';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir nunha nova fiestra';
$labels['emlsave'] = 'Gardar (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Amosar o último grupo';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Enderezos persoais';
$labels['searchsave'] = 'Gardar procura';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'Redactar mensaxes HTML';
$labels['htmlonreply'] = 'só cando se resposte a unha mensaxe HTML';
$labels['htmlonreplyandforward'] = 'ao reenviar ou respostar a unha mensaxe HTML';
$labels['htmlsignature'] = 'Sinatura HTML';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Amosar enderezo de correo co nome en pantalla';
$labels['previewpane'] = 'Amosar previsualización';
$labels['skin'] = 'Aspecto da interface';
$labels['logoutclear'] = 'Baleirar o cubo do lixo ao saír';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorar as palabras con números';
$labels['spellcheckignorecaps'] = 'Ignorar as palabras escritas en maiúsculas';
$labels['addtodict'] = 'Engadir ao diccionario';
$labels['mailtoprotohandler'] = 'Rexistrar o manexador de protocolo para as ligazóns "mailto:"';
+$labels['standardwindows'] = 'Manexar avisos emerxentes como xanelas estándar';
$labels['forwardmode'] = 'Reenvio de mensaxes';
$labels['inline'] = 'inserido';
$labels['asattachment'] = 'coma anexo';
diff --git a/program/localization/gl_ES/messages.inc b/program/localization/gl_ES/messages.inc
index 207a016a1..8fc2cb424 100644
--- a/program/localization/gl_ES/messages.inc
+++ b/program/localization/gl_ES/messages.inc
@@ -126,6 +126,8 @@ $messages['importwait'] = 'A importar. Por favor, agarde...';
$messages['importformaterror'] = 'Fallou a importación! O ficheiro cargado non contén datos válidos.';
$messages['importconfirm'] = '<b>Importáronse correctamente $inserted contactos. Ignoráronse $skipped contactos que xa existían</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>Ignoráronse $skipped existing entradas</b>';
+$messages['importmessagesuccess'] = 'Importados $nr mensaxes con éxito';
+$messages['importmessageerror'] = 'Fallou a importación! O arquivo subido non é unha mensaxe válida ou un ficheiro de caixa de correo';
$messages['opnotpermitted'] = 'Operación non permitida!';
$messages['nofromaddress'] = 'Falta o enderezo de correo electrónico na identidade que escolleu.';
$messages['editorwarning'] = 'Se troca neste intre ao editor de texto plano, vai perder todo o formato do texto. Quere continuar?';
diff --git a/program/localization/he_IL/labels.inc b/program/localization/he_IL/labels.inc
index bfb9e2fef..7ad04ab4a 100644
--- a/program/localization/he_IL/labels.inc
+++ b/program/localization/he_IL/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'טיוטות';
$labels['sent'] = 'נשלח';
$labels['trash'] = '×שפה';
$labels['junk'] = 'זבל';
+$labels['show_real_foldernames'] = 'הצגת שמות ××ž×™×ª×™×™× ×©×œ תיקיות מיוחדות';
// message listing
$labels['subject'] = 'נוש×';
@@ -193,6 +194,7 @@ $labels['listmode'] = '×ופן הצגת רשימה';
$labels['folderactions'] = 'פעולות על תיקי×';
$labels['compact'] = 'פינוי שטח ×œ× ×ž× ×•×¦×œ';
$labels['empty'] = 'ריקון';
+$labels['importmessages'] = '×™×™×‘×•× ×”×•×“×¢×•×ª';
$labels['quota'] = 'ניצול קיבולת';
$labels['unknown'] = '×œ× ×™×“×•×¢';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'ניקוי תיבת החיפוש';
$labels['searchmod'] = 'מ×פייני חיפוש';
$labels['msgtext'] = 'כל ההודעה';
$labels['body'] = 'גוף ההודעה';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'פתיחה בחלון חדש';
$labels['emlsave'] = 'הורדת הודעה בפורמט EML';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'הצגת הקבוצה ×”×חרונה';
$labels['group'] = 'קבוצה';
$labels['groups'] = 'קבוצות';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'כתובות פרטיות';
$labels['searchsave'] = 'שמירת החיפוש';
@@ -474,6 +478,7 @@ $labels['spellcheckignorenums'] = 'התעלמות ×ž×ž×™×œ×™× ×”×ž×›×™×œ×•×ª מ
$labels['spellcheckignorecaps'] = 'התעלמות ×ž×ž×™×œ×™× ×¢× ×ותציות ר×שיות';
$labels['addtodict'] = 'הוספה למילון';
$labels['mailtoprotohandler'] = 'קביעת הפרוטוקול לטיפול בקישור מסוג mailto:links';
+$labels['standardwindows'] = 'חלונות ×§×•×¤×¦×™× ×™×˜×•×¤×œ×• כחלונות רגילי×';
$labels['forwardmode'] = 'הפנית הודעות';
$labels['inline'] = 'חלק מההודעה';
$labels['asattachment'] = 'כצרופה';
diff --git a/program/localization/he_IL/messages.inc b/program/localization/he_IL/messages.inc
index 7d9b87c06..37ebcea01 100644
--- a/program/localization/he_IL/messages.inc
+++ b/program/localization/he_IL/messages.inc
@@ -126,6 +126,8 @@ $messages['importwait'] = 'ייבו×, × × ×œ×”×ž×ª×™×Ÿ..';
$messages['importformaterror'] = '×”×™×‘×•× × ×›×©×œ ! הקובץ שהועלה ×ינו מת××™×.';
$messages['importconfirm'] = '<b>יוב×ו $inserted ×נשי קשר, $skipped היו ×§×™×™×ž×™× </b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b> דילוג של $skipped × ×ª×•× ×™× ×§×™×™×ž×™× <b>';
+$messages['importmessagesuccess'] = 'יוב×ו בהצלחה $nr הודעות ';
+$messages['importmessageerror'] = '×”×™×‘×•× × ×›×©×œ ! הקובץ שהועלה ×ינו הודעה ×ו קובץ הודעות במבנה מת××™×';
$messages['opnotpermitted'] = 'פעולה ×סורה!';
$messages['nofromaddress'] = 'לזהות שנבחרה חסרה כתובת דו×ר';
$messages['editorwarning'] = 'המעבר לעורך רגיל ×™×’×¨×•× ×œ×יבוד ×ת העריכה הקיימת. ×”×× ×œ×”×ž×©×™×š?';
diff --git a/program/localization/hi_IN/labels.inc b/program/localization/hi_IN/labels.inc
index 3b8279f71..303e0b5fb 100644
--- a/program/localization/hi_IN/labels.inc
+++ b/program/localization/hi_IN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'डà¥à¤°à¤¾à¤«à¤¼à¤Ÿ';
$labels['sent'] = 'भेजा गया';
$labels['trash'] = 'रदà¥à¤¦à¥€';
$labels['junk'] = 'सà¥à¤ªà¥ˆà¤®';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विशय';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'छोटा करें';
$labels['empty'] = 'मेल रदà¥à¤¦à¥€ में डालें';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤• उपयोग';
$labels['unknown'] = 'अजà¥à¤žà¤¾à¤¤';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'खोज खाली करें';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'आखिरी बनà¥à¤¡à¤² दिखाà¤à¤‚'
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/hr_HR/labels.inc b/program/localization/hr_HR/labels.inc
index 506d50f1f..4578fed2b 100644
--- a/program/localization/hr_HR/labels.inc
+++ b/program/localization/hr_HR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Predlošci';
$labels['sent'] = 'Poslano';
$labels['trash'] = 'Smeće';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Naslov';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Model pregleda listi';
$labels['folderactions'] = 'Akcije mapa';
$labels['compact'] = 'Kompresiranje';
$labels['empty'] = 'Isprazni';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Kvota';
$labels['unknown'] = 'nepoznato';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Prikaži sve poruke';
$labels['searchmod'] = 'Postavke pretrage';
$labels['msgtext'] = 'Cijela poruka';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Otvori u novom prozoru';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Zadnja strana';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupe';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Privatna adresa';
$labels['searchsave'] = 'Pohrani pretragu';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignoriraj rijeÄi koje sadrže brojeve';
$labels['spellcheckignorecaps'] = 'Ignoriraj rijeÄi sa sa svim velikim slovima';
$labels['addtodict'] = 'Dodaj u rjeÄnik';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/hu_HU/labels.inc b/program/localization/hu_HU/labels.inc
index 3cc5da1aa..abdc7e891 100644
--- a/program/localization/hu_HU/labels.inc
+++ b/program/localization/hu_HU/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Piszkozatok';
$labels['sent'] = 'Küldött levelek';
$labels['trash'] = 'Törölt elemek';
$labels['junk'] = 'Kéretlen levelek';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Tárgy';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Megjelenítési mód';
$labels['folderactions'] = 'Mappaműveletek...';
$labels['compact'] = 'Tömörítés';
$labels['empty'] = 'Kiürítés';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Helyfoglalás';
$labels['unknown'] = 'ismeretlen';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Alapállapot';
$labels['searchmod'] = 'Keresési opciók';
$labels['msgtext'] = 'Teljes üzenet';
$labels['body'] = 'Törzs';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Megnyitás új ablakban';
$labels['emlsave'] = 'Letöltés (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Utolsó oldal';
$labels['group'] = 'Csoport';
$labels['groups'] = 'Csoportok';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Személyes címjegyzék';
$labels['searchsave'] = 'Keresés mentése';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Számot tartalmazó szavak kihagyása';
$labels['spellcheckignorecaps'] = 'Csak nagybetűt tartalmazó szavak kihagyása';
$labels['addtodict'] = 'Hozzáadás a szótárhoz';
$labels['mailtoprotohandler'] = 'Beállítás a mailto: linkek kezelőjeként';
+$labels['standardwindows'] = 'A felugró ablakok használata szokásos ablakként';
$labels['forwardmode'] = 'Üzenet továbbítás';
$labels['inline'] = 'beágyazott';
$labels['asattachment'] = 'csatolmányként';
diff --git a/program/localization/hy_AM/labels.inc b/program/localization/hy_AM/labels.inc
index 99cee4ab9..8ee9316c4 100644
--- a/program/localization/hy_AM/labels.inc
+++ b/program/localization/hy_AM/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'ÕÖ‡Õ¡Õ£Ö€Õ¥Ö€';
$labels['sent'] = 'ÕˆÖ‚Õ²Õ¡Ö€Õ¯Õ¾Õ¡Õ®';
$labels['trash'] = 'Ô±Õ²Õ¢Õ¡Ö€Õ¯Õ²';
$labels['junk'] = 'Ô¹Õ¡ÖƒÕ¸Õ¶';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÕŽÕ¥Ö€Õ¶Õ¡Õ£Õ«Ö€';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Õ‘Õ¸Ö‚ÖÕ¡Õ¯Õ¸Õ¾ Õ¿Õ¥Õ½Ö„Õ« Õ¿Õ¡Ö€Õ¢Õ¥Ö€Õ¡Õ¯Õ¨';
$labels['folderactions'] = 'Պանակի գործողություններ…';
$labels['compact'] = 'ÕÕ¥Õ²Õ´Õ¥Õ¬';
$labels['empty'] = 'Ô´Õ¡Õ¿Õ¡Ö€Õ¯Õ¥Õ¬';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Ô´Õ«Õ½Õ¯Õ¡ÕµÕ«Õ¶ Õ¿Õ¡Ö€Õ¡Õ®Ö„';
$labels['unknown'] = 'Õ¡Õ¶Õ°Õ¡ÕµÕ¿';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'ÕŽÕ¥Ö€Õ½Õ¯Õ½Õ¥Õ¬ Õ¸Ö€Õ¸Õ¶Õ¸Ö‚Õ´Õ¨';
$labels['searchmod'] = 'ÕˆÖ€Õ¸Õ¶Õ´Õ¡Õ¶ ÖƒÕ¸ÖƒÕ¸Õ­Õ«Õ¹Õ¶Õ¥Ö€';
$labels['msgtext'] = 'ÕˆÕ²Õ» Õ°Õ¡Õ²Õ¸Ö€Õ¤Õ¡Õ£Ö€Õ¸Ö‚Õ©ÕµÕ¸Ö‚Õ¶Õ¨';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ô²Õ¡ÖÕ¥Õ¬ Õ¶Õ¸Ö€ ÕºÕ¡Õ¿Õ¸Ö‚Õ°Õ¡Õ¶Õ¸Ö‚Õ´';
$labels['emlsave'] = 'Õ†Õ¥Ö€Õ¢Õ¥Õ¼Õ¶Õ¥Õ¬ (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Õ‘Õ¸Ö‚ÖÕ¡Õ¤Ö€Õ¥Õ¬ Õ¾Õ¥Ö€Õ»Õ«Õ¶ Õ§Õ»Õ¨';
$labels['group'] = 'Ô½Õ¸Ö‚Õ´Õ¢';
$labels['groups'] = 'Ô½Õ´Õ¢Õ¥Ö€';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Ô±Õ¶Õ±Õ¶Õ¡Õ¯Õ¡Õ¶ Õ°Õ¡Õ½ÖÕ¥Õ¶Õ¥Ö€';
$labels['searchsave'] = 'ÕŠÕ¡Õ°ÕºÕ¡Õ¶Õ¥Õ¬ Õ¸Ö€Õ¸Õ¶Õ¸Ö‚Õ´Õ¨';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ô±Õ¶Õ¿Õ¥Õ½Õ¥Õ¬ Õ©Õ¾Õ¥Ö€Õ¸Õ¾ Õ¢Õ¡Õ¼Õ¥Ö€Õ¨';
$labels['spellcheckignorecaps'] = 'Ô±Õ¶Õ¿Õ¥Õ½Õ¥Õ¬ Õ¬Ö€Õ«Õ¾ Õ´Õ¥Õ®Õ¡Õ¿Õ¡Õ¼ Õ¢Õ¡Õ¼Õ¥Ö€Õ¨';
$labels['addtodict'] = 'Ô±Õ¾Õ¥Õ¬Õ¡ÖÕ¶Õ¥Õ¬ Õ¢Õ¡Õ¼Õ¡Ö€Õ¡Õ¶Õ¸Ö‚Õ´';
$labels['mailtoprotohandler'] = 'mailto: Õ°Õ²Õ¸Ö‚Õ´Õ¶Õ¥Ö€Õ« Õ½ÕºÕ¡Õ½Õ¡Ö€Õ¯Õ¸Õ²';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ia/labels.inc b/program/localization/ia/labels.inc
index 2a9501168..1cd614d35 100644
--- a/program/localization/ia/labels.inc
+++ b/program/localization/ia/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Drafts';
$labels['sent'] = 'Inviate';
$labels['trash'] = 'Trash';
$labels['junk'] = 'Junk';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Subjecto';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Actiones de dossier...';
$labels['compact'] = 'Compacte';
$labels['empty'] = 'Vacue';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'incognite';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Reinitialisar cerca';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Message complete';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Aperir in nove fenestra';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Gruppo';
$labels['groups'] = 'Gruppos';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Adresses personal';
$labels['searchsave'] = 'Salveguardar cerca';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Adder al dictionario';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/id_ID/labels.inc b/program/localization/id_ID/labels.inc
index eea3132cd..73bb0156d 100644
--- a/program/localization/id_ID/labels.inc
+++ b/program/localization/id_ID/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Daftar tunggu';
$labels['sent'] = 'Terkirim';
$labels['trash'] = 'Surat Terhapus';
$labels['junk'] = 'Sampah';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Judul';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Perlihatkan mode tinjauan';
$labels['folderactions'] = 'Tindakan pada folder...';
$labels['compact'] = 'Rampingkan';
$labels['empty'] = 'Kosong';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Penggunaan ruang';
$labels['unknown'] = 'Tidak dikenal';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Atur ulang pencarian';
$labels['searchmod'] = 'Peubah pencarian';
$labels['msgtext'] = 'Seluruh pesan';
$labels['body'] = 'Badan';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Buka dalam jendela baru';
$labels['emlsave'] = 'Unduh (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Perlihatkan himpunan terakhir';
$labels['group'] = 'Kelompok';
$labels['groups'] = 'Kelompok';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Alamat pribadi';
$labels['searchsave'] = 'Simpan pencarian';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Abaikan kata-kata yang bernomor';
$labels['spellcheckignorecaps'] = 'Abaikan kata-kata dengan huruf besar semua';
$labels['addtodict'] = 'Tambahkan ke kamus';
$labels['mailtoprotohandler'] = 'Daftarkan pengampu protokol untuk link mailto:';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Meneruskan pesan';
$labels['inline'] = 'dalam surat';
$labels['asattachment'] = 'sebagai sisipan';
diff --git a/program/localization/is_IS/labels.inc b/program/localization/is_IS/labels.inc
index 80443dd3a..c2859ce75 100644
--- a/program/localization/is_IS/labels.inc
+++ b/program/localization/is_IS/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Drög';
$labels['sent'] = 'Sent';
$labels['trash'] = 'Rusl';
$labels['junk'] = 'Ruslpóstur';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Titill';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Listayfirlit';
$labels['folderactions'] = 'Möppuaðgerðir...';
$labels['compact'] = 'Pakka';
$labels['empty'] = 'Tæma';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Gagnamagn';
$labels['unknown'] = 'óþekkt';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Tæma leit';
$labels['searchmod'] = 'Leitarskilyrði';
$labels['msgtext'] = 'Allt skeytið';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Opna í nýjum glugga';
$labels['emlsave'] = 'Niðurhlaða (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Sýna síðustu síðu';
$labels['group'] = 'Hópur';
$labels['groups'] = 'Hópar';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Persónuleg heimilisföng';
$labels['searchsave'] = 'Vista leit';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Hunsa orð með tölum';
$labels['spellcheckignorecaps'] = 'Hunsa orð sem eru í hástöfum';
$labels['addtodict'] = 'Bæta við orðalista';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/it_IT/labels.inc b/program/localization/it_IT/labels.inc
index 75a24c5fd..55cd432f7 100644
--- a/program/localization/it_IT/labels.inc
+++ b/program/localization/it_IT/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Bozze';
$labels['sent'] = 'Inviata';
$labels['trash'] = 'Cestino';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Oggetto';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Modalità di visualizzazione';
$labels['folderactions'] = 'Operazioni cartella';
$labels['compact'] = 'Compatta';
$labels['empty'] = 'Svuota';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Spazio utilizzato';
$labels['unknown'] = 'sconosciuto';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Annulla ricerca';
$labels['searchmod'] = 'Ambito di ricerca';
$labels['msgtext'] = 'Intero messaggio';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Apri in una nuova finestra';
$labels['emlsave'] = 'Scarica (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Ultima pagina';
$labels['group'] = 'Gruppo';
$labels['groups'] = 'Gruppi';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Rubrica Personale';
$labels['searchsave'] = 'Salva ricerca';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignora le parole contenenti numeri';
$labels['spellcheckignorecaps'] = 'Ignora le parole con tutte le lettere maiuscole';
$labels['addtodict'] = 'Aggiungi al dizionario';
$labels['mailtoprotohandler'] = 'Registra gestore per mailto:';
+$labels['standardwindows'] = 'Gestisci i popup come finestre standard';
$labels['forwardmode'] = 'Inoltro messaggi';
$labels['inline'] = 'In linea';
$labels['asattachment'] = 'come allegato';
diff --git a/program/localization/ja_JP/labels.inc b/program/localization/ja_JP/labels.inc
index 6998f0623..767aff23a 100644
--- a/program/localization/ja_JP/labels.inc
+++ b/program/localization/ja_JP/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = '下書ã';
$labels['sent'] = 'é€ä¿¡æ¸ˆã¿';
$labels['trash'] = 'ã”ã¿ç®±';
$labels['junk'] = '迷惑メール';
+$labels['show_real_foldernames'] = '特殊フォルダーã®å®Ÿéš›ã®åå‰ã‚’表示';
// message listing
$labels['subject'] = '件å';
@@ -193,6 +194,7 @@ $labels['listmode'] = '一覧表示モード';
$labels['folderactions'] = 'フォルダーã®æ“作...';
$labels['compact'] = '圧縮';
$labels['empty'] = '空';
+$labels['importmessages'] = 'メッセージをインãƒãƒ¼ãƒˆ';
$labels['quota'] = 'ディスクã®ä½¿ç”¨çŠ¶æ³';
$labels['unknown'] = 'ä¸æ˜Ž';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = '検索を解除';
$labels['searchmod'] = '検索ã®æ¡ä»¶';
$labels['msgtext'] = 'メッセージ全体';
$labels['body'] = '本文';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'æ–°ã—ã„ウィンドウã§é–‹ã';
$labels['emlsave'] = 'ダウンロード(.emlå½¢å¼)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = '最後ã®ãƒšãƒ¼ã‚¸ã‚’表示';
$labels['group'] = 'グループ';
$labels['groups'] = 'グループ';
+$labels['listgroup'] = 'グループã®ãƒ¡ãƒ³ãƒãƒ¼ã‚’一覧';
$labels['personaladrbook'] = '個人ã®ä½æ‰€';
$labels['searchsave'] = '検索情報をä¿å­˜';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'æ•°å­—ã‚’å«ã‚€å˜èªžã‚’無視';
$labels['spellcheckignorecaps'] = 'ã™ã¹ã¦å¤§æ–‡å­—ã®å˜èªžã‚’無視';
$labels['addtodict'] = '辞書ã«è¿½åŠ ';
$labels['mailtoprotohandler'] = 'mailto: ã®ãƒªãƒ³ã‚¯ã‚’扱ã†ãƒ—ロトコル処ç†ã®ç™»éŒ²';
+$labels['standardwindows'] = 'ãƒãƒƒãƒ—アップを通常ã®ã‚¦ã‚£ãƒ³ãƒ‰ã‚¦ã¨ã—ã¦å‡¦ç†';
$labels['forwardmode'] = 'メッセージã®è»¢é€å½¢å¼';
$labels['inline'] = 'インライン';
$labels['asattachment'] = '添付ファイル';
diff --git a/program/localization/ka_GE/labels.inc b/program/localization/ka_GE/labels.inc
index 3ab3b6e63..b0126c44e 100755
--- a/program/localization/ka_GE/labels.inc
+++ b/program/localization/ka_GE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'დრáƒáƒ”ბითი';
$labels['sent'] = 'გáƒáƒ’ზáƒáƒ•áƒœáƒ˜áƒšáƒ˜';
$labels['trash'] = 'წáƒáƒ¨áƒšáƒ˜áƒšáƒ˜';
$labels['junk'] = 'სპáƒáƒ›áƒ˜';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'სáƒáƒ—áƒáƒ£áƒ áƒ˜';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'შეკუმშვáƒ';
$labels['empty'] = 'გáƒáƒªáƒáƒ áƒ˜áƒ”ლებáƒ';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'შეზღუდვáƒ';
$labels['unknown'] = 'უცნáƒáƒ‘ი';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'ძიების გáƒáƒ¡áƒ£áƒ¤áƒ—áƒáƒ•áƒ”ბáƒ'
$labels['searchmod'] = 'ძებნის ვáƒáƒ áƒ˜áƒáƒœáƒ¢áƒ”ბი';
$labels['msgtext'] = 'ყველრშეტყáƒáƒ‘ინებáƒ';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'გáƒáƒ®áƒ¡áƒœáƒ áƒáƒ®áƒáƒš ფáƒáƒœáƒ¯áƒáƒ áƒáƒ¨áƒ˜';
$labels['emlsave'] = 'გáƒáƒ“მáƒáƒ¬áƒ”რრ(.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'ბáƒáƒšáƒáƒ¡ ჩვენებáƒ';
$labels['group'] = 'ჯგუფი';
$labels['groups'] = 'ჯგუფები';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'პერსáƒáƒœáƒáƒšáƒ£áƒ áƒ˜ მისáƒáƒ›áƒáƒ áƒ—ები';
$labels['searchsave'] = 'ძებნის შენáƒáƒ®áƒ•áƒ';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'ლექსიკáƒáƒœáƒ¨áƒ˜ დáƒáƒ›áƒáƒ¢áƒ”ბáƒ';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/km_KH/labels.inc b/program/localization/km_KH/labels.inc
index 7b10b5f7f..bc2836a53 100644
--- a/program/localization/km_KH/labels.inc
+++ b/program/localization/km_KH/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'សំបុážáŸ’រពង្រៀង';
$labels['sent'] = 'សំបុážáŸ’រដែលបានបញ្ជូន';
$labels['trash'] = 'ធុងសំរាម';
$labels['junk'] = 'សំបុážáŸ’រមិនល្អ';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ចំណងជើង';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'បង្ហាញជាážáž¶ážšáž¶áž„';
$labels['folderactions'] = 'មុážáž„ារážáž';
$labels['compact'] = 'បង្រួម';
$labels['empty'] = 'áž‘áž‘áŸážš';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ទំហំសំបុážáŸ’រទាំងអស់ដែលមាន';
$labels['unknown'] = 'មិនស្គាល់';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'កំណážáŸ‹áž›áž€áŸ’ážážáŸážŽáŸ’ឌស្វáŸ
$labels['searchmod'] = 'កែសំរួលលក្ážážáŸážŽáŸ’ឌស្វែងរក';
$labels['msgtext'] = 'សំបុážáŸ’រទាំងមូល';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'បើកក្នុងវីនដូវážáŸ’មី';
$labels['emlsave'] = 'រក្សាទុកទិន្ននáŸáž™áž‡áž¶áž¯áž€ážŸáž¶ážšáž”្រភáŸáž‘(.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'ទំពáŸážšáž…ុងក្រោយ';
$labels['group'] = 'ក្រុម';
$labels['groups'] = 'ក្រុម';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'អាសយដ្ឋានផ្ទាល់ážáŸ’លួន';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ko_KR/labels.inc b/program/localization/ko_KR/labels.inc
index 950928767..60a9275ac 100644
--- a/program/localization/ko_KR/labels.inc
+++ b/program/localization/ko_KR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = '임시 보관함';
$labels['sent'] = '보낸 편지함';
$labels['trash'] = '휴지통';
$labels['junk'] = '스팸 편지함';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '제목';
@@ -193,6 +194,7 @@ $labels['listmode'] = '화면 모드 ëª©ë¡ ë³´ê¸°';
$labels['folderactions'] = 'í´ë” 명령';
$labels['compact'] = '간단하게';
$labels['empty'] = '비어 있ìŒ';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ë””ìŠ¤í¬ ì‚¬ìš©ëŸ‰';
$labels['unknown'] = 'ì•Œ 수 ì—†ìŒ';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = '검색 재설정';
$labels['searchmod'] = 'ìˆ˜ì •ìž ê²€ìƒ‰';
$labels['msgtext'] = '전체 메시지';
$labels['body'] = '본문';
+$labels['type'] = 'Type';
$labels['openinextwin'] = '새 ì°½ì—ì„œ 열기';
$labels['emlsave'] = '다운로드(.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = '마지막 페ì´ì§€ 보기';
$labels['group'] = '그룹';
$labels['groups'] = '그룹';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ê°œì¸ ì£¼ì†Œ';
$labels['searchsave'] = '검색 저장';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = '숫ìžê°€ í¬í•¨ëœ 단어 무시';
$labels['spellcheckignorecaps'] = 'ëª¨ë‘ ëŒ€ë¬¸ìžë¡œ í‘œê¸°ëœ ë‹¨ì–´ 무시';
$labels['addtodict'] = 'ì‚¬ì „ì— ì¶”ê°€';
$labels['mailtoprotohandler'] = 'mailto: ë§í¬ì˜ 프로토콜 ì²˜ë¦¬ìž ë“±ë¡';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = '메시지 전달';
$labels['inline'] = '본문 내용으로';
$labels['asattachment'] = '첨부파ì¼ë¡œ';
diff --git a/program/localization/ku/labels.inc b/program/localization/ku/labels.inc
index a4f6cb568..6a3c16a5f 100644
--- a/program/localization/ku/labels.inc
+++ b/program/localization/ku/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Hilanînî';
$labels['sent'] = 'Şandî';
$labels['trash'] = 'Çop';
$labels['junk'] = 'Biikêrnehatî';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Mijar';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Kompakt';
$labels['empty'] = 'Vala Bike';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Bikaranîna dîskê';
$labels['unknown'] = 'nayê zanîn';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Lêgerînê reset bike';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Seta dawî nîşan bide';
$labels['group'] = 'Group';
$labels['groups'] = 'Kom';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Navnîşanên Takekesî';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/lt_LT/labels.inc b/program/localization/lt_LT/labels.inc
index 6398a3683..31cb44d27 100644
--- a/program/localization/lt_LT/labels.inc
+++ b/program/localization/lt_LT/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'JuodraÅ¡Äiai';
$labels['sent'] = 'Išsiųsti laiškai';
$labels['trash'] = 'Šiukšlinė';
$labels['junk'] = 'Brukalas';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Tema';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Sąrašo rodymo veiksena';
$labels['folderactions'] = 'Veiksmai su aplankais…';
$labels['compact'] = 'Suglaudinti';
$labels['empty'] = 'Ištuštinti';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disko naudojimas';
$labels['unknown'] = 'nežinomas';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Atšaukti paiešką';
$labels['searchmod'] = 'Paieškos modifikatoriai';
$labels['msgtext'] = 'Visas laiškas';
$labels['body'] = 'Laiško tekstas';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Atverti naujame lange';
$labels['emlsave'] = 'Parsisiųsti (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Rodyti paskutinį puslapį';
$labels['group'] = 'GrupÄ—';
$labels['groups'] = 'GrupÄ—s';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Asmeniniai adresai';
$labels['searchsave'] = 'Įrašyti kaip radinių aplanką';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Nepaisyti žodžių su skaitmenimis';
$labels['spellcheckignorecaps'] = 'Nepaisyti žodžių vien iš didžiųjų raidžių';
$labels['addtodict'] = 'Įtraukti į žodyną';
$labels['mailtoprotohandler'] = 'Užregistruoti svetainÄ™ kaip dirbanÄiÄ… su „mailto:“ saitais';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Laiškų persiuntimo būdas';
$labels['inline'] = 'kaip citatÄ…';
$labels['asattachment'] = 'kaip priedas';
diff --git a/program/localization/lv_LV/labels.inc b/program/localization/lv_LV/labels.inc
index 7d4de2564..0fe5b0faf 100644
--- a/program/localization/lv_LV/labels.inc
+++ b/program/localization/lv_LV/labels.inc
@@ -23,50 +23,51 @@ $labels['welcome'] = 'Esiet laipni lūgti $product';
$labels['username'] = 'LietotÄjvÄrds';
$labels['password'] = 'Parole';
$labels['server'] = 'Serveris';
-$labels['login'] = 'Pieslēgties';
+$labels['login'] = 'Autorizēties';
// taskbar
-$labels['logout'] = 'Atslēgties';
+$labels['logout'] = 'Iziet';
$labels['mail'] = 'E-pasts';
-$labels['settings'] = 'Personīgie iestatījumi';
+$labels['settings'] = 'Iestatījumi';
$labels['addressbook'] = 'AdreÅ¡u grÄmata';
// mailbox names
$labels['inbox'] = 'IenÄkoÅ¡Äs';
$labels['drafts'] = 'Uzmetumi';
$labels['sent'] = 'NosÅ«tÄ«tÄs';
-$labels['trash'] = 'Miskaste';
+$labels['trash'] = 'Papīrgrozs';
$labels['junk'] = 'MÄ“stules';
+$labels['show_real_foldernames'] = 'SistÄ“mas mapÄ“m rÄdÄ«t Ä«stos nosaukumus';
// message listing
$labels['subject'] = 'Temats';
$labels['from'] = 'No';
-$labels['sender'] = 'Sender';
+$labels['sender'] = 'SÅ«tÄ«tÄjs';
$labels['to'] = 'Kam';
$labels['cc'] = 'Cc';
$labels['bcc'] = 'Bcc';
-$labels['replyto'] = 'Reply-To';
-$labels['followupto'] = 'Followup-To';
+$labels['replyto'] = 'Atbildēt-Uz';
+$labels['followupto'] = 'Sekot-Uz';
$labels['date'] = 'Datums';
$labels['size'] = 'Izmērs';
$labels['priority'] = 'PrioritÄte';
$labels['organization'] = 'Uzņēmums';
$labels['readstatus'] = 'Izlasīšanas statuss';
-$labels['listoptions'] = 'List options...';
+$labels['listoptions'] = 'Vēstuļu saraksta attēlošanas iestatījumi...';
$labels['mailboxlist'] = 'Mapes';
$labels['messagesfromto'] = 'Vēstules $from līdz $to no $count';
$labels['threadsfromto'] = 'Vijumi $from līdz $to no $count';
-$labels['messagenrof'] = '$nr. vēstule no $count';
-$labels['fromtoshort'] = '$from – $to of $count';
+$labels['messagenrof'] = '$nr. vēstule no $count';
+$labels['fromtoshort'] = '$from – $to no $count';
$labels['copy'] = 'Kopēt';
$labels['move'] = 'PÄrvietot';
-$labels['moveto'] = 'pÄrvietot uz...';
+$labels['moveto'] = 'PÄrvietot uz...';
$labels['download'] = 'lejupielÄdÄ“t';
-$labels['open'] = 'Open';
-$labels['showattachment'] = 'Show';
-$labels['showanyway'] = 'Show it anyway';
+$labels['open'] = 'Atvērt';
+$labels['showattachment'] = 'RÄdÄ«t';
+$labels['showanyway'] = 'Vienalga rÄdÄ«t';
$labels['filename'] = 'Faila nosaukums';
$labels['filesize'] = 'Faila izmērs';
@@ -122,77 +123,78 @@ $labels['longdec'] = 'Decembris';
$labels['today'] = 'Å odien';
// toolbar buttons
-$labels['refresh'] = 'Refresh';
-$labels['checkmail'] = 'PÄrbaudÄ«t pastu';
+$labels['refresh'] = 'Atjaunot';
+$labels['checkmail'] = 'PÄrbaudÄ«t e-pastu';
$labels['compose'] = 'Rakstīt vēstuli';
$labels['writenewmessage'] = 'Rakstīt jaunu vēstuli';
-$labels['reply'] = 'Reply';
-$labels['replytomessage'] = 'Atbildēt';
-$labels['replytoallmessage'] = 'AtbildÄ“t sÅ«tÄ«tÄjam un visiem saņēmÄ“jiem';
+$labels['reply'] = 'Atbildēt';
+$labels['replytomessage'] = 'AtbildÄ“t sÅ«tÄ«tÄjam';
+$labels['replytoallmessage'] = 'AtbildÄ“t sÅ«tÄ«tÄjam vai listei un visiem adresÄtiem';
$labels['replyall'] = 'Atbildēt visiem';
$labels['replylist'] = 'Atbildēt listei';
-$labels['forward'] = 'Forward';
+$labels['forward'] = 'PÄrsÅ«tÄ«t';
$labels['forwardinline'] = 'PÄrsÅ«tÄ«t iekļaujot vÄ“stulÄ“';
$labels['forwardattachment'] = 'PÄrsÅ«tÄ«t kÄ pielikumu';
$labels['forwardmessage'] = 'PÄrsÅ«tÄ«t vÄ“stuli';
$labels['deletemessage'] = 'Dzēst vēstuli';
-$labels['movemessagetotrash'] = 'PÄrvietot vÄ“stuli uz miskasti';
-$labels['printmessage'] = 'izdrukÄt';
+$labels['movemessagetotrash'] = 'PÄrvietot vÄ“stuli uz papÄ«rgrozu';
+$labels['printmessage'] = 'IzdrukÄt Å¡o vÄ“stuli';
$labels['previousmessage'] = 'ParÄdÄ«t iepriekÅ¡Ä“jo vÄ“stuli';
$labels['firstmessage'] = 'ParÄdÄ«t pirmo vÄ“stuli';
$labels['nextmessage'] = 'ParÄdÄ«t nÄkamo vÄ“stuli';
$labels['lastmessage'] = 'ParÄdÄ«t pÄ“dÄ“jo vÄ“stuli';
$labels['backtolist'] = 'Atpakaļ uz vēstuļu sarakstu';
-$labels['viewsource'] = 'parÄdÄ«t pirmtekstu';
-$labels['mark'] = 'Mark';
-$labels['markmessages'] = 'MarÄ·Ä“t vÄ“stules kÄ:';
-$labels['markread'] = 'lasītas';
-$labels['markunread'] = 'nelasītas';
-$labels['markflagged'] = 'iezīmētas';
-$labels['markunflagged'] = 'neiezīmētas';
-$labels['moreactions'] = 'Citas darbības...';
-$labels['more'] = 'More';
-$labels['back'] = 'Back';
-$labels['options'] = 'Options';
-
-$labels['select'] = 'Iezīmēt';
-$labels['all'] = 'visas';
-$labels['none'] = 'Neviens';
+$labels['viewsource'] = 'ParÄdÄ«t pirmtekstu';
+$labels['mark'] = 'Atzīmēt';
+$labels['markmessages'] = 'AtzÄ«mÄ“t vÄ“stules kÄ:';
+$labels['markread'] = 'KÄ lasÄ«tas';
+$labels['markunread'] = 'KÄ nelasÄ«tas';
+$labels['markflagged'] = 'KÄ atÄ«mÄ“tas';
+$labels['markunflagged'] = 'KÄ neatzÄ«mÄ“tas';
+$labels['moreactions'] = 'Papildus darbības...';
+$labels['more'] = 'VairÄk';
+$labels['back'] = 'Atpakaļ';
+$labels['options'] = 'Opcijas';
+
+$labels['select'] = 'Atzīmēt';
+$labels['all'] = 'Visas';
+$labels['none'] = 'Nevienu';
$labels['currpage'] = 'PaÅ¡reizÄ“jÄ lapa';
-$labels['unread'] = 'nelasÄ«tÄs';
-$labels['flagged'] = 'iezÄ«mÄ“tÄs';
-$labels['unanswered'] = 'neatbildÄ“tÄs';
-$labels['withattachment'] = 'With attachment';
-$labels['deleted'] = 'dzÄ“stÄs';
-$labels['undeleted'] = 'Not deleted';
-$labels['invert'] = 'invertēt';
+$labels['unread'] = 'NelasÄ«tÄs';
+$labels['flagged'] = 'AtzÄ«mÄ“tÄs';
+$labels['unanswered'] = 'NeatbildÄ“tÄs';
+$labels['withattachment'] = 'Ar pielikumu';
+$labels['deleted'] = 'DzÄ“stÄs';
+$labels['undeleted'] = 'Nav izdzēstas';
+$labels['invert'] = 'Pretēji';
$labels['filter'] = 'Filtrēt';
-$labels['list'] = 'Saraksts';
-$labels['threads'] = 'Vijumi';
+$labels['list'] = 'RÄdÄ«t kÄ sarakstu';
+$labels['threads'] = 'RÄdÄ«t kÄ vijumus';
$labels['expand-all'] = 'Izvērst visus';
-$labels['expand-unread'] = 'Izvērst neizlasītos';
-$labels['collapse-all'] = 'Savērst visu';
-$labels['threaded'] = 'Savīts';
+$labels['expand-unread'] = 'IzvÄ“rst neizlasÄ«tÄs';
+$labels['collapse-all'] = 'Sakļaut visas';
+$labels['threaded'] = 'RÄdÄ«t vijumus';
$labels['autoexpand_threads'] = 'Izvērst vēstuļu vijumus';
-$labels['do_expand'] = 'visiem vijumiem';
-$labels['expand_only_unread'] = 'tikai tad, ja ir neizlasītas vēstules';
-$labels['fromto'] = 'SÅ«tÄ«tÄjs/SaņēmÄ“js';
-$labels['flag'] = 'Iezīmēts';
+$labels['do_expand'] = 'visus vijumus';
+$labels['expand_only_unread'] = 'tikai ar neizlasÄ«tÄm vÄ“stulÄ“m';
+$labels['fromto'] = 'No/Kam';
+$labels['flag'] = 'Atzīmēt';
$labels['attachment'] = 'Pielikums';
-$labels['nonesort'] = 'Neviens';
+$labels['nonesort'] = 'Neviena';
$labels['sentdate'] = 'Nosūtīšanas datums';
$labels['arrival'] = 'PienÄkÅ¡anas datums';
$labels['asc'] = 'augoša';
$labels['desc'] = 'dilstoša';
$labels['listcolumns'] = 'Saraksta kolonnas';
-$labels['listsorting'] = 'KÄrtot pÄ“c kolonnas';
+$labels['listsorting'] = 'KÄrtoÅ¡anas kolonnas';
$labels['listorder'] = 'KÄrtoÅ¡anas secÄ«ba';
-$labels['listmode'] = 'Saraksta režīms';
+$labels['listmode'] = 'Attēlošanas veids';
$labels['folderactions'] = 'Darbības ar mapēm...';
-$labels['compact'] = 'saspiest';
-$labels['empty'] = 'iztukšot';
+$labels['compact'] = 'Saspiest';
+$labels['empty'] = 'Iztukšot';
+$labels['importmessages'] = 'Importēt vēstules';
$labels['quota'] = 'Kvota';
$labels['unknown'] = 'nezinÄms';
@@ -200,35 +202,36 @@ $labels['unlimited'] = 'neierobežots';
$labels['quicksearch'] = 'Ä€rtÄ meklÄ“Å¡ana';
$labels['resetsearch'] = 'Atstatīt meklēšanu';
-$labels['searchmod'] = 'Meklēt laukos:';
-$labels['msgtext'] = 'VÄ“stules tekstÄ';
-$labels['body'] = 'Body';
+$labels['searchmod'] = 'Meklēšanas modifikatori:';
+$labels['msgtext'] = 'VisÄ vÄ“stulÄ“';
+$labels['body'] = 'Pamatteksts';
+$labels['type'] = 'Tips';
-$labels['openinextwin'] = 'atvÄ“rt jaunÄ logÄ';
+$labels['openinextwin'] = 'AtvÄ“rt jaunÄ logÄ';
$labels['emlsave'] = 'lejupielÄdÄ“t (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'RÄdÄ«t kÄ neformatÄ“tu tekstu';
+$labels['changeformathtml'] = 'RÄdÄ«t kÄ HTML formatÄ“tu';
// message compose
-$labels['editasnew'] = 'rediģēt kÄ jaunu';
-$labels['send'] = 'Send';
+$labels['editasnew'] = 'Rediģēt kÄ jaunu';
+$labels['send'] = 'Sūtīt';
$labels['sendmessage'] = 'Sūtīt vēstuli';
-$labels['savemessage'] = 'SaglabÄt uzmetumu';
+$labels['savemessage'] = 'SaglabÄt kÄ uzmetumu';
$labels['addattachment'] = 'Pievienot failu';
$labels['charset'] = 'Rakstzīmju kopa';
$labels['editortype'] = 'Redaktora tips';
$labels['returnreceipt'] = 'SaņemÅ¡anas apstiprinÄjums';
-$labels['dsn'] = 'Atskaite par piegÄdi';
+$labels['dsn'] = 'PiegÄdes atskaite';
$labels['mailreplyintro'] = '$sender @ $date rakstīja:';
$labels['originalmessage'] = 'SÄkotnÄ“jÄ vÄ“stule';
$labels['editidents'] = 'Rediģēt identitÄtes';
-$labels['spellcheck'] = 'Spell';
+$labels['spellcheck'] = 'IzrunÄt';
$labels['checkspelling'] = 'PÄrbaudÄ«t pareizrakstÄ«bu';
$labels['resumeediting'] = 'TurpinÄt rediģēšanu';
$labels['revertto'] = 'Atgriezt uz';
-$labels['attach'] = 'Attach';
+$labels['attach'] = 'Pievienot';
$labels['attachments'] = 'Pielikumi';
$labels['upload'] = 'AugÅ¡upielÄdÄ“t';
$labels['uploadprogress'] = '$percent ($current no $total)';
@@ -241,13 +244,13 @@ $labels['normal'] = 'NormÄla';
$labels['high'] = 'Augsta';
$labels['highest'] = 'AugstÄkÄ';
-$labels['nosubject'] = '(no subject)';
+$labels['nosubject'] = '(bez tēmas)';
$labels['showimages'] = 'RÄdÄ«t attÄ“lus';
-$labels['alwaysshow'] = 'VienmÄ“r rÄdÄ«t attÄ“lus no $sender';
+$labels['alwaysshow'] = 'VienmÄ“r rÄdÄ«t attÄ“lus vÄ“stulÄ“s, kuras sÅ«tÄ«jis $sender';
$labels['isdraft'] = 'Å is ir melnraksts.';
-$labels['andnmore'] = '$nr more...';
-$labels['togglemoreheaders'] = 'Show more message headers';
-$labels['togglefullheaders'] = 'Toggle raw message headers';
+$labels['andnmore'] = '$nr vairÄk...';
+$labels['togglemoreheaders'] = 'RÄdÄ«t galvenes papildus informÄciju';
+$labels['togglefullheaders'] = 'SlÄ“pt galvenes papildus informÄciju';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'VienkÄrÅ¡s teksts';
@@ -257,14 +260,14 @@ $labels['maxuploadsize'] = 'MaksimÄlais atļautais faila izmÄ“rs ir $size';
$labels['addcc'] = 'Pievienot Cc';
$labels['addbcc'] = 'Pievienot Bcc';
-$labels['addreplyto'] = 'Pievienot Reply-To';
+$labels['addreplyto'] = 'Pievienot Atbildēt-Uz';
$labels['addfollowupto'] = 'Pievienot Followup-To';
// mdn
-$labels['mdnrequest'] = 'Å Ä«s vÄ“stules sÅ«tÄ«tÄjs vÄ“las redzÄ“t vÄ“stules saņemÅ¡anas apstiprinÄjumu. Vai jÅ«s vÄ“laties nosÅ«tÄ«t apstiprinÄjumu?';
+$labels['mdnrequest'] = 'Å Ä«s vÄ“stules sÅ«tÄ«tÄjs vÄ“las redzÄ“t vÄ“stules saņemÅ¡anas apstiprinÄjumu. Vai JÅ«s vÄ“laties nosÅ«tÄ«t Å¡o apstiprinÄjumu?';
$labels['receiptread'] = 'SaņemÅ¡anas apstiprinÄjums';
-$labels['yourmessage'] = 'Å Ä«s ir jÅ«su vÄ“stules saņemÅ¡anas apstiprinÄjums';
-$labels['receiptnote'] = 'PiezÄ«me: Å Ä«s apsiprinÄjums nozÄ«mÄ“ tikai to, ka vÄ“stule tika parÄdÄ«ta uz saņēmÄja datora. Tas nenozÄ«mÄ“, ka saņēmÄ“js ir izlasÄ«jis vai izpratis vÄ“stules saturu.';
+$labels['yourmessage'] = 'Å is ir JÅ«su nosÅ«tÄ«tÄs vÄ“stules saņemÅ¡anas apstiprinÄjums';
+$labels['receiptnote'] = 'PiezÄ«me: Å is apsiprinÄjums nozÄ«mÄ“ tikai to, ka vÄ“stule tika parÄdÄ«ta uz saņēmÄja datora. Tas nenozÄ«mÄ“, ka saņēmÄ“js ir izlasÄ«jis vai sapratis vÄ“stules saturu.';
// address boook
$labels['name'] = 'UzrÄdÄ«tais vÄrds';
@@ -273,33 +276,33 @@ $labels['surname'] = 'UzvÄrds';
$labels['middlename'] = 'Otrais vÄrds';
$labels['nameprefix'] = 'Prefikss';
$labels['namesuffix'] = 'Sufikss';
-$labels['nickname'] = 'Iesauka (nick)';
+$labels['nickname'] = 'SegvÄrds';
$labels['jobtitle'] = 'Amats';
$labels['department'] = 'Nodaļa';
$labels['gender'] = 'Dzimums';
-$labels['maidenname'] = 'PirmslaulÄ«bu uzvÄrds';
+$labels['maidenname'] = 'PirmslaulÄ«bas uzvÄrds';
$labels['email'] = 'E-pasts';
$labels['phone'] = 'TÄlrunis';
$labels['address'] = 'Adrese';
$labels['street'] = 'Iela';
$labels['locality'] = 'Pilsēta';
-$labels['zipcode'] = 'Pasta kods';
+$labels['zipcode'] = 'Pasta indekss';
$labels['region'] = 'Novads';
$labels['country'] = 'Pilsēta';
$labels['birthday'] = 'Dzimšanas diena';
$labels['anniversary'] = 'Gadadiena';
-$labels['website'] = 'Web lapa';
+$labels['website'] = 'MÄjaslapa';
$labels['instantmessenger'] = 'IM';
$labels['notes'] = 'Piezīmes';
$labels['male'] = 'vīrietis';
$labels['female'] = 'sieviete';
$labels['manager'] = 'Menedžeris';
$labels['assistant'] = 'Asistents';
-$labels['spouse'] = 'LaulÄtais draugs';
+$labels['spouse'] = 'LaulÄtais';
$labels['allfields'] = 'Visi lauki';
$labels['search'] = 'Meklēt';
$labels['advsearch'] = 'PaplaÅ¡inÄtÄ meklÄ“Å¡ana';
-$labels['advanced'] = 'Advanced';
+$labels['advanced'] = 'PaplaÅ¡inÄtie iestatÄ«jumi';
$labels['other'] = 'Cits';
$labels['typehome'] = 'MÄjas';
@@ -307,22 +310,22 @@ $labels['typework'] = 'Darbs';
$labels['typeother'] = 'Cits';
$labels['typemobile'] = 'Mobilais tÄlrunis';
$labels['typemain'] = 'Galvenais';
-$labels['typehomefax'] = 'MÄjas Fax';
-$labels['typeworkfax'] = 'Darba Fax';
+$labels['typehomefax'] = 'Fakss mÄjÄs';
+$labels['typeworkfax'] = 'Fakss darbÄ';
$labels['typecar'] = 'Auto';
$labels['typepager'] = 'Peidžeris';
$labels['typevideo'] = 'Video';
$labels['typeassistant'] = 'Asistents';
-$labels['typehomepage'] = 'Web lapa';
+$labels['typehomepage'] = 'MÄjaslapa';
$labels['typeblog'] = 'Blogs';
$labels['typeprofile'] = 'Profils';
$labels['addfield'] = 'Pievienot lauku...';
-$labels['addcontact'] = 'Pievienot iezÄ«mÄ“to ierakstu adreÅ¡u grÄmatai';
-$labels['editcontact'] = 'Rediģēt adreÅ¡u grÄmatas ierakstu';
+$labels['addcontact'] = 'Pievienot jaunu kontaktu';
+$labels['editcontact'] = 'Rediģēt kontaktu';
$labels['contacts'] = 'Kontakti';
$labels['contactproperties'] = 'Kontakta īpašības';
-$labels['personalinfo'] = 'PersoniskÄ informÄcija';
+$labels['personalinfo'] = 'PersonÄ«gÄ informÄcija';
$labels['edit'] = 'Rediģēt';
$labels['cancel'] = 'Atcelt';
@@ -331,29 +334,30 @@ $labels['delete'] = 'Dzēst';
$labels['rename'] = 'PÄrdÄ“vÄ“t';
$labels['addphoto'] = 'Pievienot';
$labels['replacephoto'] = 'Aizvietot';
-$labels['uploadphoto'] = 'Upload photo';
+$labels['uploadphoto'] = 'AugÅ¡upielÄdÄ“t fotogrÄfiju';
-$labels['newcontact'] = 'Izveidot jaunu ierakstu';
-$labels['deletecontact'] = 'Dzēst iezīmētos ierakstus';
+$labels['newcontact'] = 'Izveidot jaunu kontaktu';
+$labels['deletecontact'] = 'Dzēst atzīmētos kontaktus';
$labels['composeto'] = 'Rakstīt vēstuli';
-$labels['contactsfromto'] = 'Ieraksti $from līdz $to no $count';
+$labels['contactsfromto'] = 'Ieraksti no $from lÄ«dz $to - kopÄ $count';
$labels['print'] = 'DrukÄt';
$labels['export'] = 'Eksportēt';
-$labels['exportall'] = 'Export all';
-$labels['exportsel'] = 'Export selected';
+$labels['exportall'] = 'Eksportēt visu';
+$labels['exportsel'] = 'Eksportēt atzīmēto';
$labels['exportvcards'] = 'EksportÄ“t kontaktus vCard formÄtÄ';
$labels['newcontactgroup'] = 'Izveidot jaunu kontaktu grupu';
$labels['grouprename'] = 'PÄrdÄ“vÄ“t grupu';
$labels['groupdelete'] = 'Izdzēst grupu';
-$labels['groupremoveselected'] = 'Remove selected contacts from group';
+$labels['groupremoveselected'] = 'Dzēst atzīmētos kontaktus no grupas';
-$labels['previouspage'] = 'ParÄdÄ«t iepriekÅ¡Ä“jo kopu';
-$labels['firstpage'] = 'ParÄdÄ«t pirmo kopu';
-$labels['nextpage'] = 'ParÄdÄ«t nÄkamo kopu';
-$labels['lastpage'] = 'ParÄdÄ«t pÄ“dÄ“jo kopu';
+$labels['previouspage'] = 'ParÄdÄ«t iepriekÅ¡Ä“jo lapu';
+$labels['firstpage'] = 'ParÄdÄ«t pirmo lapu';
+$labels['nextpage'] = 'ParÄdÄ«t nÄkamo lapu';
+$labels['lastpage'] = 'ParÄdÄ«t pÄ“dÄ“jo lapu';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupas';
+$labels['listgroup'] = 'RÄdÄ«t grupas kontaktus';
$labels['personaladrbook'] = 'PersonÄ«gÄs adreses';
$labels['searchsave'] = 'SaglabÄt meklÄ“Å¡anas pieprasÄ«jumu';
@@ -362,72 +366,72 @@ $labels['searchdelete'] = 'DzÄ“st saglabÄto meklÄ“Å¡anas pieprasÄ«jumu';
$labels['import'] = 'Importēt';
$labels['importcontacts'] = 'Importēt kontaktus';
$labels['importfromfile'] = 'Importēt no faila:';
-$labels['importtarget'] = 'Pievienot jaunus kontaktus adreÅ¡u grÄmatai';
+$labels['importtarget'] = 'Pievienot jaunus kontaktus adreÅ¡u grÄmatai:';
$labels['importreplace'] = 'Aizvietot visu adreÅ¡u grÄmatu';
-$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'] = 'JÅ«s varat ieimportÄ“t kontaktus no jau esoÅ¡as adreÅ¡u grÄmatas.<br/>Uz doto brÄ«di tiek atbalstÄ«ti <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> vai CSV (ar komatu atdalÄ«tie) datu formÄti.';
$labels['done'] = 'Pabeigts';
// settings
$labels['settingsfor'] = 'Iestatījumi';
$labels['about'] = 'Par';
$labels['preferences'] = 'Iestatījumi';
-$labels['userpreferences'] = 'LietotÄja preferences';
-$labels['editpreferences'] = 'Rediģēt lietotÄja preferences';
+$labels['userpreferences'] = 'LietotÄja iestatÄ«jumi';
+$labels['editpreferences'] = 'Rediģēt iestatījumus';
$labels['identities'] = 'IdentitÄtes';
-$labels['manageidentities'] = 'Rediģēt Å¡Ä« konta identitÄtes';
+$labels['manageidentities'] = 'Rediģēt identitÄtes';
$labels['newidentity'] = 'Jauna identitÄte';
$labels['newitem'] = 'Jauns';
$labels['edititem'] = 'Rediģēt';
-$labels['preferhtml'] = 'Dot priekÅ¡roku HTML formatÄ“tÄm vÄ“stulÄ“m';
+$labels['preferhtml'] = 'RÄdÄ«t HTML formatÄ“tÄs vÄ“stules';
$labels['defaultcharset'] = 'NoklusÄ“tÄ rakstzÄ«mju kopa';
-$labels['htmlmessage'] = 'HTML vēstule';
-$labels['messagepart'] = 'Part';
-$labels['digitalsig'] = 'Digital Signature';
+$labels['htmlmessage'] = 'HTML formatēta vēstule';
+$labels['messagepart'] = 'Daļa';
+$labels['digitalsig'] = 'DigitÄlais paraksts';
$labels['dateformat'] = 'Datuma formÄts';
$labels['timeformat'] = 'Laika formÄts';
-$labels['prettydate'] = 'Formatēt datumus';
+$labels['prettydate'] = 'RÄdÄ«t Ä«sos datumus';
$labels['setdefault'] = 'Uzlikt kÄ noklusÄ“to';
-$labels['autodetect'] = 'AutomÄtiski';
+$labels['autodetect'] = 'AutomÄtiska';
$labels['language'] = 'Valoda';
$labels['timezone'] = 'Laika zona';
$labels['pagesize'] = 'Rindas lapÄ';
$labels['signature'] = 'Paraksts';
$labels['dstactive'] = 'Vasaras/ziemas laiks';
-$labels['showinextwin'] = 'Open message in a new window';
-$labels['composeextwin'] = 'Compose in a new window';
-$labels['htmleditor'] = 'Rakstīt HTML vēstules';
+$labels['showinextwin'] = 'VÄ“stules atvÄ“rt jaunÄ logÄ';
+$labels['composeextwin'] = 'VÄ“stuli rakstÄ«t jaunÄ logÄ';
+$labels['htmleditor'] = 'Rakstīt HTML formatētas vēstules';
$labels['htmlonreply'] = 'tikai atbildot uz HTML formatÄ“tÄm vÄ“stulÄ“m';
-$labels['htmlonreplyandforward'] = 'on forward or reply to HTML message';
-$labels['htmlsignature'] = 'HTML paraksts';
-$labels['showemail'] = 'Show email address with display name';
+$labels['htmlonreplyandforward'] = 'tikai pÄrsÅ«tot vai atbildot uz HTML formatÄ“tu vÄ“stuli';
+$labels['htmlsignature'] = 'HTML formatēts paraksts';
+$labels['showemail'] = 'Pie vÄrda rÄdÄ«t arÄ« e-pasta adresi';
$labels['previewpane'] = 'RÄdÄ«t priekÅ¡skatÄ«juma paneli';
-$labels['skin'] = 'Interfeisa izskats';
-$labels['logoutclear'] = 'Izejot no sistēmas, iztīrīt miskasti';
-$labels['logoutcompact'] = 'Izejot no sistēmas, saspiest iesūtni';
+$labels['skin'] = 'Saskarnes izskats';
+$labels['logoutclear'] = 'Izejot no e-pasta, iztīrīt papīrgrozu';
+$labels['logoutcompact'] = 'Izejot no e-pasta, saspiest iesūtni';
$labels['uisettings'] = 'LietotÄja saskarne';
$labels['serversettings'] = 'Servera iestatījumi';
$labels['mailboxview'] = 'Pastkastes skats';
$labels['mdnrequests'] = 'Vēstules izlasīšanas atskaites sūtīšana';
-$labels['askuser'] = 'jautÄt lietotÄjam';
+$labels['askuser'] = 'jautÄt man vai sÅ«tÄ«t';
$labels['autosend'] = 'sÅ«tÄ«t automÄtiski';
-$labels['autosendknown'] = 'automÄtiski sÅ«tÄ«t maniem kontaktiem, par citiem jautÄt';
-$labels['autosendknownignore'] = 'automÄtiski sÅ«tÄ«t maniem kontaktiem, citiem nesÅ«tÄ«t';
-$labels['ignore'] = 'ignorēt';
-$labels['readwhendeleted'] = 'AtzÄ«mÄ“t dzÄ“stÄs vÄ“stules kÄ izlasÄ«tas';
-$labels['flagfordeletion'] = 'DzÄ“Å¡ot marÄ·Ä“t vÄ“stules kÄ dzÄ“stas, bet nedzÄ“st';
+$labels['autosendknown'] = 'automÄtiski sÅ«tÄ«t ja pieprasÄ«tÄjs ir manos kontaktos, par citiem jautÄt';
+$labels['autosendknownignore'] = 'automÄtiski sÅ«tÄ«t ja pieprasÄ«tÄjs ir manos kontaktos, citiem ignorÄ“t un nesÅ«tÄ«t';
+$labels['ignore'] = 'ignorēt un nesūtīt';
+$labels['readwhendeleted'] = 'DzÄ“Å¡ot vÄ“stules tÄs atzÄ«mÄ“t kÄ izlasÄ«tas';
+$labels['flagfordeletion'] = 'DzÄ“Å¡ot vÄ“stules tÄs nedzÄ“st, bet marÄ·Ä“t kÄ dzÄ“Å¡amas';
$labels['skipdeleted'] = 'NerÄdÄ«t dzÄ“stÄs vÄ“stules';
-$labels['deletealways'] = 'IzdzÄ“st vÄ“stules, ja tÄs neizdodas pÄrvietot uz miskasti';
-$labels['deletejunk'] = 'Directly delete messages in Junk';
-$labels['showremoteimages'] = 'RÄdÄ«t attÄ“lus, kas atrodas uz cita servera';
-$labels['fromknownsenders'] = 'no zinÄmiem sÅ«tÄ«tÄjiem';
+$labels['deletealways'] = 'IzdzÄ“st vÄ“stules, ja tÄs neizdodas pÄrvietot uz papÄ«rgrozu';
+$labels['deletejunk'] = 'AutomÄtiski dzÄ“st vÄ“stules no mÄ“stuļu mapÄ«tes';
+$labels['showremoteimages'] = 'RÄdÄ«t vÄ“stulÄ“s attÄ“lus, kuri atrodas uz cita servera';
+$labels['fromknownsenders'] = 'tikai no zinÄmiem sÅ«tÄ«tÄjiem';
$labels['always'] = 'vienmēr';
$labels['showinlineimages'] = 'RÄdÄ«t pielikuma attÄ“lus zem vÄ“stules';
-$labels['autosavedraft'] = 'AutomÄtiski saglabÄt uzmetumu';
-$labels['everynminutes'] = 'ik pa $n minūti(ēm)';
-$labels['refreshinterval'] = 'Refresh (check for new messages, etc.)';
+$labels['autosavedraft'] = 'AutomÄtiski saglabÄt vÄ“stules uzmetumu';
+$labels['everynminutes'] = 'ik pēc $n minūtes(ēm)';
+$labels['refreshinterval'] = 'PÄrbaudÄ«t jaunÄs vÄ“stules';
$labels['never'] = 'nekad';
$labels['immediately'] = 'nekavējoties';
$labels['messagesdisplaying'] = 'Vēstuļu attēlošana';
@@ -437,44 +441,45 @@ $labels['2231folding'] = 'Pilns RFC 2231 (Thunderbird)';
$labels['miscfolding'] = 'RFC 2047/2231 (MS Outlook)';
$labels['2047folding'] = 'Pilns RFC 2047 (citi)';
$labels['force7bit'] = 'Izmantot MIME kodējumu 8-bitu simboliem';
-$labels['advancedoptions'] = 'PaplaÅ¡inÄti iestatÄ«jumi';
-$labels['focusonnewmessage'] = 'UztÄdÄ«t pÄrlÅ«ka fokusu uz jaunu vÄ“stuli';
-$labels['checkallfolders'] = 'PÄrbaudÄ«t visas mapes pÄ“c jaunÄm vÄ“stulÄ“m';
-$labels['displaynext'] = 'RÄdÄ«t nÄkamo vÄ“stuli pÄ“c dzÄ“Å¡anas/pÄrvietoÅ¡anas';
-$labels['defaultfont'] = 'NoklusÄ“tais fonts vÄ“stulei HTML formÄtÄ';
+$labels['advancedoptions'] = 'PaplaÅ¡inÄtie iestatÄ«jumi';
+$labels['focusonnewmessage'] = 'UzstÄdÄ«t pÄrlÅ«ka fokusu uz jaunu vÄ“stuli';
+$labels['checkallfolders'] = 'MeklÄ“t visÄs mapÄ“s jaunÄs vÄ“stules';
+$labels['displaynext'] = 'PÄ“c vÄ“stules dzÄ“Å¡anas/pÄrvietoÅ¡anas rÄdÄ«t nÄkamo vÄ“stuli';
+$labels['defaultfont'] = 'NoklusÄ“tais fonts vÄ“stulÄ“m HTML formÄtÄ';
$labels['mainoptions'] = 'Galvenie iestatījumi';
-$labels['browseroptions'] = 'Browser Options';
-$labels['section'] = 'Kategorija';
+$labels['browseroptions'] = 'PÄrlÅ«ka iestatÄ«jumi';
+$labels['section'] = 'Sadaļa';
$labels['maintenance'] = 'Uzturēšana';
$labels['newmessage'] = 'VÄ“stuļu pienÄkÅ¡ana';
$labels['signatureoptions'] = 'Paraksta iestatījumi';
$labels['whenreplying'] = 'Atbildot';
-$labels['replyempty'] = 'do not quote the original message';
+$labels['replyempty'] = 'neiekļaut vÄ“stules sÄkotnÄ“jo tekstu';
$labels['replytopposting'] = 'sÄkt jaunu vÄ“stuli virs oriÄ£inÄla';
$labels['replybottomposting'] = 'sÄkt jaunu vÄ“stuli zem oriÄ£inÄla';
$labels['replyremovesignature'] = 'Atbildot izņemt oriÄ£inÄlo parakstu no vÄ“stules';
$labels['autoaddsignature'] = 'AutomÄtiski pievienot parakstu';
-$labels['newmessageonly'] = 'tikai jaunas vēstules';
-$labels['replyandforwardonly'] = 'tikai atbildes un pÄrsÅ«tÄ«jumi';
+$labels['newmessageonly'] = 'tikai jaunÄm vÄ“stulÄ“m';
+$labels['replyandforwardonly'] = 'tikai atbildÄ“m un pÄrsÅ«tÄ«jumiem';
$labels['insertsignature'] = 'Ievietot parakstu';
$labels['previewpanemarkread'] = 'AtzÄ«mÄ“t priekÅ¡skatÄ«tÄs vÄ“stules kÄ lasÄ«tas';
$labels['afternseconds'] = 'pēc $n sekundēm';
-$labels['reqmdn'] = 'Vienmēr pieprasīt atskati par vēstules izlasīšanu';
-$labels['reqdsn'] = 'VienmÄ“r pieprasÄ«t atskati par vÄ“stules piegÄdÄÅ¡anu saņēmÄ“ja serverim';
+$labels['reqmdn'] = 'VienmÄ“r pieprasÄ«t saņemÅ¡anas apstiprinÄjumu';
+$labels['reqdsn'] = 'VienmÄ“r pieprasÄ«t atskati par piegÄdi';
$labels['replysamefolder'] = 'GlabÄt atbildes tajÄ paÅ¡Ä mapÄ“, kurÄ ir vÄ“stule, uz kuru tika atbildÄ“ts';
-$labels['defaultabook'] = 'Default address book';
-$labels['autocompletesingle'] = 'AutomÄtiski aizpildot, izlaist alternatÄ«vÄs e-pasta adreses';
-$labels['listnamedisplay'] = 'List contacts as';
-$labels['spellcheckbeforesend'] = 'PÄrbaudÄ«t pareizrakstÄ«bu pirms vÄ“stules nosÅ«tÄ«Å¡anas';
+$labels['defaultabook'] = 'NoklusÄ“tÄ adreÅ¡u grÄmata';
+$labels['autocompletesingle'] = 'AutomÄtiski aizpildot, nerÄdÄ«t alternatÄ«vÄs e-pasta adreses';
+$labels['listnamedisplay'] = 'RÄdÄ«t kontaktus kÄ';
+$labels['spellcheckbeforesend'] = 'Pirms vÄ“stules nosÅ«tÄ«Å¡anas pÄrbaudÄ«t pareizrakstÄ«bu';
$labels['spellcheckoptions'] = 'Pareizrakstības iestatījumi';
$labels['spellcheckignoresyms'] = 'IgnorÄ“t vÄrdus, kuri satur simbolus';
$labels['spellcheckignorenums'] = 'IgnorÄ“t vÄrdus, kuri satur skaitļus';
$labels['spellcheckignorecaps'] = 'IgnorÄ“t vÄrdus, kuri rakstÄ«ti ar lielajiem burtiem';
$labels['addtodict'] = 'Pievienot vÄrdnÄ«cai';
-$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
-$labels['forwardmode'] = 'Messages forwarding';
-$labels['inline'] = 'inline';
-$labels['asattachment'] = 'as attachment';
+$labels['mailtoprotohandler'] = 'Atverot mailto: saites, lietot Å¡o e-pasta programmu';
+$labels['standardwindows'] = 'IzlÄ“coÅ¡ie logi kÄ parasti logi';
+$labels['forwardmode'] = 'VÄ“stuļu pÄrsÅ«tÄ«Å¡ana';
+$labels['inline'] = 'iekļaujot';
+$labels['asattachment'] = 'kÄ pielikumu';
$labels['folder'] = 'Mapi';
$labels['folders'] = 'Mapes';
@@ -491,8 +496,8 @@ $labels['parentfolder'] = 'Virsmape';
$labels['location'] = 'AtraÅ¡anÄs vieta';
$labels['info'] = 'InformÄcija';
$labels['getfoldersize'] = 'UzklikÅ¡Ä·iniet, lai uzzinÄtu mapes izmÄ“ru';
-$labels['changesubscription'] = 'Uzklikšķiniet, lai mainītu abonēšanu';
-$labels['foldertype'] = 'Mapes veids';
+$labels['changesubscription'] = 'Uzklikšķiniet, lai mainītu abonēšanas iestatījumus';
+$labels['foldertype'] = 'Mapes tips';
$labels['personalfolder'] = 'PrivÄta mape';
$labels['otherfolder'] = 'Cita lietotÄja mape';
$labels['sharedfolder'] = 'Publiska mape';
@@ -502,7 +507,7 @@ $labels['sortasc'] = 'KÄrtot augoÅ¡Ä secÄ«bÄ';
$labels['sortdesc'] = 'KÄrtot dilstoÅ¡Ä secÄ«bÄ';
$labels['undo'] = 'Atsaukt';
-$labels['installedplugins'] = 'Installed plugins';
+$labels['installedplugins'] = 'UzstÄdÄ«tie spraudņi';
$labels['plugin'] = 'Spraudnis';
$labels['version'] = 'Versija';
$labels['source'] = 'OriÄ£inÄls';
@@ -516,7 +521,7 @@ $labels['MB'] = 'MB';
$labels['GB'] = 'GB';
// character sets
-$labels['unicode'] = 'Unikoda';
+$labels['unicode'] = 'Unikods';
$labels['english'] = 'Angļu';
$labels['westerneuropean'] = 'Rietumeiropas';
$labels['easterneuropean'] = 'Austrumeiropas';
diff --git a/program/localization/lv_LV/messages.inc b/program/localization/lv_LV/messages.inc
index b69a73e2b..37ceb0463 100644
--- a/program/localization/lv_LV/messages.inc
+++ b/program/localization/lv_LV/messages.inc
@@ -28,7 +28,7 @@ $messages['dberror'] = 'DatubÄzes kļūda!';
$messages['requesttimedout'] = 'PieprasÄ«jumam iestÄjÄs noilgums';
$messages['errorreadonly'] = 'NeizdevÄs veikt darbÄ«bu: mape ir tikai lasÄma (read only)';
$messages['errornoperm'] = 'NeizdevÄs veikt darbÄ«bu: piekļuve liegta';
-$messages['erroroverquota'] = 'OperÄciju nav iespÄ“jams veikt. Uz diska nav brÄ«vas veitas.';
+$messages['erroroverquota'] = 'OperÄciju veikt nav iespÄ“jams. Uz diska nav brÄ«vas veitas.';
$messages['erroroverquotadelete'] = 'Uz diska nav brīvas vietas. Lai dzēstu vēstuli, lietojiet SHIFT+DEL.';
$messages['invalidrequest'] = 'NederÄ«gs pieprasÄ«jums! Dati netika saglabÄti ...';
$messages['invalidhost'] = 'Nederīgs servera nosaukums';
@@ -45,7 +45,7 @@ $messages['sendingmessage'] = 'Tiek sūtīta vēstule ...';
$messages['messagesent'] = 'Vēstule nosūtīta veiksmīgi';
$messages['savingmessage'] = 'VÄ“stule tiek saglabÄta ...';
$messages['messagesaved'] = 'VÄ“stule saglabÄta Uzmetumos';
-$messages['successfullysaved'] = 'VÄ“stule veiksmÄ«gi saglabÄta';
+$messages['successfullysaved'] = 'VeiksmÄ«gi saglabÄts.';
$messages['addedsuccessfully'] = 'Kontakts veiksmÄ«gi pievienots adreÅ¡u grÄmatai';
$messages['contactexists'] = 'Kontakts ar Å¡Ädu e-pasta adresi jau eksistÄ“';
$messages['contactnameexists'] = 'Kontakts ar Å¡Ädu vÄrdu jau eksistÄ“.';
@@ -100,72 +100,74 @@ $messages['deletedsuccessfully'] = 'Veiksmīgi izdzēsts';
$messages['converting'] = 'Tiek noņemts vēstules formatējums...';
$messages['messageopenerror'] = 'NevarÄ“ja ielÄdÄ“t vÄ“stuli no servera';
$messages['fileuploaderror'] = 'Faila augÅ¡upielÄde neveiksmÄ«ga';
-$messages['filesizeerror'] = 'IelÄdÄ“tais fails pÄrsniedz pieļaujamo $size apjomu';
-$messages['copysuccess'] = 'Veiksmīgi nokopētas $nr vēstules';
-$messages['copyerror'] = 'Nevarēja nokopēt nevienu adresi';
+$messages['filesizeerror'] = 'AugÅ¡upielÄdÄ“tais fails pÄrsniedz pieļaujamo $size izmÄ“ru.';
+$messages['copysuccess'] = 'Veiksmīgi nokopētas $nr adreses.';
+$messages['copyerror'] = 'Nevarēja nokopēt nevienu adresi.';
$messages['sourceisreadonly'] = 'Adreses avots ir lasÄ«Å¡anas režīmÄ tikai';
-$messages['errorsavingcontact'] = 'NevarÄ“ja saglabÄt kontakta adreses';
-$messages['movingmessage'] = 'PÄrvietoju vÄ“stules...';
+$messages['errorsavingcontact'] = 'Kontakta adresi nevarÄ“ja saglabÄt.';
+$messages['movingmessage'] = 'PÄrvieto vÄ“stules...';
$messages['copyingmessage'] = 'Kopē vēstules...';
$messages['copyingcontact'] = 'Kopē kontaktus...';
$messages['deletingmessage'] = 'Dzēš vēstules...';
$messages['markingmessage'] = 'Atzīmē vēstules...';
-$messages['addingmember'] = 'Pievieno kontaktu(s) grupai...';
-$messages['removingmember'] = 'Atvieno kontaktu(s) no grupas...';
-$messages['receiptsent'] = 'SaņemÅ¡anas apstiprinÄjums nosÅ«tÄ«ts';
-$messages['errorsendingreceipt'] = 'NeizdevÄs nosÅ«tÄ«t apstiprinÄjumu';
-$messages['deleteidentityconfirm'] = 'Vai tieÅ¡Äm vÄ“laties dzÄ“st Å¡o identitÄti?';
-$messages['nodeletelastidentity'] = 'Å o identitÄti nevar izdzÄ“st, tÄ ir pati pÄ“dÄ“jÄ.';
-$messages['forbiddencharacter'] = 'Mapes nosaukums satur aizliegtus simbolus';
-$messages['selectimportfile'] = 'LÅ«dzu izvÄ“lieties failu, ko vÄ“laties augÅ¡upielÄdÄ“t';
-$messages['addresswriterror'] = 'IzvÄ“lÄ“tÄs adreÅ¡u grÄmatas datus nevar labot';
+$messages['addingmember'] = 'Kontaktus pievieno grupai...';
+$messages['removingmember'] = 'Kontaktus atvieno no grupas...';
+$messages['receiptsent'] = 'SaņemÅ¡anas apstiprinÄjums nosÅ«tÄ«ts veiksmÄ«gi.';
+$messages['errorsendingreceipt'] = 'NeizdevÄs nosÅ«tÄ«t saņemÅ¡anas apstiprinÄjumu.';
+$messages['deleteidentityconfirm'] = 'Vai JÅ«s tieÅ¡Äm vÄ“laties dzÄ“st Å¡o identitÄti?';
+$messages['nodeletelastidentity'] = 'Å o identitÄti nav iespÄ“jams izdzÄ“st, jo tÄ ir pati pÄ“dÄ“jÄ.';
+$messages['forbiddencharacter'] = 'Mapes nosaukums satur aizliegtus simbolus.';
+$messages['selectimportfile'] = 'LÅ«dzu norÄdiet failu, kuru vÄ“laties augÅ¡upielÄdÄ“t.';
+$messages['addresswriterror'] = 'IzvÄ“lÄ“tÄs adreÅ¡u grÄmatas datus nav iespÄ“jams rediģēt.';
$messages['contactaddedtogroup'] = 'Kontakti tika veiksmīgi pievienoti šai grupai.';
$messages['contactremovedfromgroup'] = 'Kontakti tika veiksmīgi atvienoti no šīs grupas.';
$messages['nogroupassignmentschanged'] = 'GrupÄ nekas netika mainÄ«ts.';
$messages['importwait'] = 'Importēju, lūdzu uzgaidiet...';
$messages['importformaterror'] = 'Imports neizdevÄs! AugÅ¡upielÄdÄ“tais fails nav derÄ«gs importam.';
-$messages['importconfirm'] = '<b>Veiksmīgi ieimportēti $inserted kontakti, netika importēti $skipped esoši ieraksti</b>:<p><em>$names</em></p>';
+$messages['importconfirm'] = '<b>Veiksmīgi ieimportēti $inserted kontakti</b>';
$messages['importconfirmskipped'] = '<b>Izlaida $skipped jau eksistējošus ierakstus</b>';
+$messages['importmessagesuccess'] = 'Veiksmīgi ieimportētas $nr vēstules';
+$messages['importmessageerror'] = 'ImportÄ“Å¡anas kļūda! AugÅ¡upielÄdÄ“tÄ datne satur nekorektus datus';
$messages['opnotpermitted'] = 'Darbība nav atļauta!';
-$messages['nofromaddress'] = 'IzvÄ“lÄ“tajai identitÄtei nav norÄdÄ«ta e-pasta adrese';
-$messages['editorwarning'] = 'PÄrslÄ“dzoties uz vienkÄrÅ¡otu teksta redaktoru, tiks pazaudÄ“ts esoÅ¡ais teksta formatÄ“jums. Vai vÄ“laties turpinÄt?';
-$messages['httpreceivedencrypterror'] = 'Kļūme. Lūdzu sazinieties ar administratoru. <b>Nav iespējams nosūtīt vēstuli.</b>';
+$messages['nofromaddress'] = 'IzvÄ“lÄ“tajai identitÄtei nav norÄdÄ«ta e-pasta adrese.';
+$messages['editorwarning'] = 'PÄrslÄ“dzoties uz vienkÄrÅ¡otu teksta redaktoru, tiks pazaudÄ“ts esoÅ¡ais teksta formatÄ“jums. Vai tieÅ¡Äm vÄ“laties turpinÄt?';
+$messages['httpreceivedencrypterror'] = 'Notika kritiska kļūme. Lūdzu nekavējoties sazinieties ar Jūsu administratoru. <b>Jūsu vēstuli nosūtīt nav iespējams.</b>';
$messages['smtpconnerror'] = 'SMTP kļūme ($code): NeizdevÄs pieslÄ“gties serverim';
-$messages['smtpautherror'] = 'SMTP kļūme ($code): NeizdevÄs autentificÄ“ties';
-$messages['smtpfromerror'] = 'SMTP kļūme ($code): NeizdevÄs iestatÄ«t sÅ«tÄ«tÄju "$from" ($msg)';
-$messages['smtptoerror'] = 'SMTP kļūme ($code): NeizdevÄs pievienot saņēmÄ“ju "$to" ($msg)';
-$messages['smtprecipientserror'] = 'SMTP kļūme: Nav iespējams parsēt saņēmēju sarakstu';
-$messages['smtperror'] = 'SMTP kļūme: $msg';
+$messages['smtpautherror'] = 'SMTP kļūda ($code): NeizdevÄs autorizÄ“ties.';
+$messages['smtpfromerror'] = 'SMTP kļūda ($code): NeizdevÄs iestatÄ«t sÅ«tÄ«tÄju "$from" ($msg).';
+$messages['smtptoerror'] = 'SMTP kļūda ($code): NeizdevÄs pievienot saņēmÄ“ju "$to" ($msg).';
+$messages['smtprecipientserror'] = 'SMTP kļūda: Nav iespÄ“jams aptrÄdÄt saņēmÄ“ju sarakstu.';
+$messages['smtperror'] = 'SMTP kļūda: $msg';
$messages['emailformaterror'] = 'Nepareiza e-pasta adrese: $email';
$messages['toomanyrecipients'] = 'PÄrÄk daudz saņēmÄ“ju. Samaziniet skaitu lÄ«dz $max.';
$messages['maxgroupmembersreached'] = 'Grupas dalÄ«bnieku skaits pÄrsniedz limitu $max.';
-$messages['internalerror'] = 'Servera iekÅ¡Ä“jÄ kļūda. LÅ«dzu mÄ“Ä£iniet vÄ“lreiz.';
-$messages['contactdelerror'] = 'NeizdevÄs izdzÄ“st kontaktu(s).';
-$messages['contactdeleted'] = 'Kontakti veiksmīgi izdzēsti.';
-$messages['contactrestoreerror'] = 'NeizdevÄs atjaunot izdzÄ“stos kontaktus.';
-$messages['contactrestored'] = 'Kontakti veiksmīgi atjaunoti.';
-$messages['groupdeleted'] = 'Grupa veiksmīgi izdzēsta.';
-$messages['grouprenamed'] = 'Grupa veiksmÄ«gi pÄrdÄ“vÄ“ta.';
-$messages['groupcreated'] = 'Grupa veiksmīgi izveidota.';
-$messages['savedsearchdeleted'] = 'SaglabÄtais meklÄ“Å¡anas pieprasÄ«jums veiksmÄ«gi dzÄ“sts.';
-$messages['savedsearchdeleteerror'] = 'NeizdevÄs nodzÄ“st saglabÄto meklÄ“Å¡anas pieprasÄ«jumu.';
-$messages['savedsearchcreated'] = 'SaglabÄtais meklÄ“Å¡anas pieprasÄ«jums veiksmÄ«gi saglabÄts.';
-$messages['savedsearchcreateerror'] = 'NeizdevÄs saglabÄt meklÄ“Å¡anas pieprasÄ«jumu.';
+$messages['internalerror'] = 'Notika servera iekÅ¡Ä“jÄ kļūda. LÅ«dzu mÄ“Ä£iniet vÄ“lreiz.';
+$messages['contactdelerror'] = 'Kontaktus izdzÄ“st neizdevÄs.';
+$messages['contactdeleted'] = 'Kontakti izdzēsti veiksmīgi.';
+$messages['contactrestoreerror'] = 'IzdzÄ“stos kontaktus atjaunot neizdevÄs.';
+$messages['contactrestored'] = 'Kontakti atjaunoti veiksmīgi.';
+$messages['groupdeleted'] = 'Grupa izdzēsta veiksmīgi.';
+$messages['grouprenamed'] = 'Grupa pÄrdÄ“vÄ“ta veiksmÄ«gi.';
+$messages['groupcreated'] = 'Grupa izveidota veiksmīgi.';
+$messages['savedsearchdeleted'] = 'SaglabÄtais meklÄ“Å¡anas pieprasÄ«jums izdzÄ“sts veiksmÄ«gi.';
+$messages['savedsearchdeleteerror'] = 'SaglabÄto meklÄ“Å¡anas pieprasÄ«jumu izdzÄ“st neizdevÄs.';
+$messages['savedsearchcreated'] = 'SaglabÄtais meklÄ“Å¡anas pieprasÄ«jums saglabÄts veiksmÄ«gi.';
+$messages['savedsearchcreateerror'] = 'MeklÄ“Å¡anas pieprasÄ«jumu izveidot neizdevÄs.';
$messages['messagedeleted'] = 'Vēstule(s) veiksmīgi izdzēsta(s).';
$messages['messagemoved'] = 'VÄ“stule(s) veiksmÄ«gi pÄrvietota(s).';
$messages['messagecopied'] = 'VÄ“stule(s) veiksmÄ«gi pÄrkopÄ“ta(s).';
-$messages['messagemarked'] = 'Vēstule(s) veiksmīgi iezīmēta(s).';
-$messages['autocompletechars'] = 'Ievadiet vismaz $min burtus, lai meklÄ“tu automÄtiski.';
-$messages['autocompletemore'] = 'Atrasti vairÄki ieraksti. Papildiniet meklÄ“Å¡anas kritÄ“riju.';
+$messages['messagemarked'] = 'Vēstule(s) veiksmīgi atzīmēta(s).';
+$messages['autocompletechars'] = 'Lai automÄtiski meklÄ“tu, ievadiet vismaz $min burtus.';
+$messages['autocompletemore'] = 'Atrasti vairÄki ieraksti. Papildiniet meklÄ“Å¡anas kritÄ“riju ar vairÄk burtiem.';
$messages['namecannotbeempty'] = 'LÅ«dzu ievadiet vÄrdu.';
-$messages['nametoolong'] = 'VÄrds ir par garu.';
+$messages['nametoolong'] = 'VÄrds ir pÄrÄk garÅ¡.';
$messages['folderupdated'] = 'Mape vieksmīgi atjaunota.';
$messages['foldercreated'] = 'Mape veiksmīgi izveidota.';
$messages['invalidimageformat'] = 'NederÄ«gs attÄ“la formÄts.';
$messages['mispellingsfound'] = 'Vēstulē atrastas pareizrakstības kļūdas.';
-$messages['parentnotwritable'] = 'NeizdevÄs izveidot/pÄrvietot mapi uz atzÄ«mÄ“to virsmapi. Nav piekļuves tiesÄ«bu.';
-$messages['messagetoobig'] = 'VÄ“stule ir pÄrÄk liela, lai to varÄ“tu apstrÄdÄt.';
+$messages['parentnotwritable'] = 'NeizdevÄs izveidot/pÄrvietot mapi atzÄ«mÄ“tajÄ virsmapÄ“. Nav piekļuves tiesÄ«bu.';
+$messages['messagetoobig'] = 'VÄ“stule daļa ir pÄrÄk liela, lai to varÄ“tu apstrÄdÄt.';
$messages['attachmentvalidationerror'] = 'BRĪDINÄ€JUMS! Å is pielikums ir aizdomÄ«gs, jo tÄ tips neatbilst tipam, kurÅ¡ ir uzrÄdÄ«ts e-pasta ziņojumÄ. Ja jÅ«s neuzticaties sÅ«tÄ«tÄjam, Å¡o failu Jums vaÄ¼Ä vÄ“rt nevajadzÄ“tu, jo tas var saturÄ“t ļaunprÄtÄ«gu saturu. <br/><br/><em>BÅ«tu jÄbÅ«t: $expected; Bet ir: $detected</em>';
-$messages['noscriptwarning'] = 'UzmanÄ«bu: lai lasÄ«tu e-pastus, JÅ«su tÄ«mekļa pÄrlÅ«kÄ jÄbÅ«t iespÄ“jotiem JavaScript.';
+$messages['noscriptwarning'] = 'UzmanÄ«bu: lai lasÄ«tu e-pastus, JÅ«su pÄrlÅ«kprogrammÄ jÄbÅ«t ieslÄ“gtiem JavaScript.';
?>
diff --git a/program/localization/mk_MK/labels.inc b/program/localization/mk_MK/labels.inc
index bb9606e6a..519df5823 100755
--- a/program/localization/mk_MK/labels.inc
+++ b/program/localization/mk_MK/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Ðепратени';
$labels['sent'] = 'Пратени';
$labels['trash'] = 'Корпа';
$labels['junk'] = 'Ѓубре';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÐаÑлов';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Компактно';
$labels['empty'] = 'ИÑпразни';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ИÑкориÑтен проÑтор';
$labels['unknown'] = 'непознато';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Ðово пребарување';
$labels['searchmod'] = 'Модификатори на пребарувањето';
$labels['msgtext'] = 'Цело пиÑмо';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Отвори во нов прозорец';
$labels['emlsave'] = 'Преземи (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Прикажи ја поÑледната Ñтран
$labels['group'] = 'Group';
$labels['groups'] = 'Групи';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Лични адреÑи';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ml_IN/labels.inc b/program/localization/ml_IN/labels.inc
index ed0e7402a..7d3fdc501 100644
--- a/program/localization/ml_IN/labels.inc
+++ b/program/localization/ml_IN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'പൂരàµâ€à´¤àµà´¤à´¿à´¯à´¾à´•à´¾à´¤àµà´¤à´µ';
$labels['sent'] = 'അയചàµà´šà´µ';
$labels['trash'] = 'ചവറàµà´±àµà´•àµà´Ÿàµà´Ÿ';
$labels['junk'] = 'ആവശàµà´¯à´®à´¿à´²àµà´²à´¾à´¤àµà´¤à´µ';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'വിഷയം';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'à´šàµà´°àµà´•àµà´•àµ';
$labels['empty'] = 'ശൂനàµà´¯à´‚';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'à´¡à´¿à´¸àµà´•àµà´•àµ ഉപയോഗം';
$labels['unknown'] = 'അറിയാതàµà´¤';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Reset search';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'à´®àµà´´àµà´µà´¨àµâ€ സനàµà´¦àµ‡à´¶à´µàµà´‚';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'à´ªàµà´¤à´¿à´¯ വിനàµâ€à´¡àµ‹à´¯à´¿à´²àµâ€ à´¤àµà´±à´•àµà´•àµà´•';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'കൂടàµà´Ÿà´‚';
$labels['groups'] = 'കൂടàµà´Ÿà´™àµà´™à´³àµâ€';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'à´¸àµà´µà´•à´¾à´°àµà´¯ വിലാസങàµà´™à´³àµâ€';
$labels['searchsave'] = 'തിരയലàµâ€ സൂകàµà´·à´¿à´•àµà´•àµà´•';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'à´…à´•àµà´•à´™àµà´™à´³àµâ€ ഉളàµà´³ à
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'നിഘണàµà´Ÿàµà´µà´¿à´²àµâ€ ചേരàµâ€à´•àµà´•àµà´•';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/mr_IN/labels.inc b/program/localization/mr_IN/labels.inc
index 02b129e0b..d26583d4d 100755
--- a/program/localization/mr_IN/labels.inc
+++ b/program/localization/mr_IN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'मसà¥à¤¦à¤¾';
$labels['sent'] = 'पाठवलेले';
$labels['trash'] = 'कचरा पेटी';
$labels['junk'] = 'नको असलेले कचरा संदेश';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विषय';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'यादी दरà¥à¤¶à¤• पधà¥â€à¤¦à¤¤';
$labels['folderactions'] = 'फोलà¥à¤¡à¤° कृती..';
$labels['compact'] = 'छोटा';
$labels['empty'] = 'रिकामा';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤•à¤šà¤¾ वापर';
$labels['unknown'] = 'माहित नसलेला';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'परत शोध';
$labels['searchmod'] = 'बदलकरà¥à¤¤à¥â€à¤¯à¤¾à¤‚ना शोधा';
$labels['msgtext'] = 'संपूरà¥à¤£ संदेश';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'नवीन खिडकी उघडा';
$labels['emlsave'] = 'इà¤à¤®à¤à¤² सà¥â€à¤µà¤°à¥‚पात उतरवून घà¥à¤¯à¤¾';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'शेवटचा संच दाखवा';
$labels['group'] = 'गट';
$labels['groups'] = 'अनेक गट';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'वैयकà¥à¤¤à¤¿à¤• पतà¥à¤¤à¥‡';
$labels['searchsave'] = 'शोध जतन करा';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/ms_MY/labels.inc b/program/localization/ms_MY/labels.inc
index 318af05ad..a6bdfbfa0 100644
--- a/program/localization/ms_MY/labels.inc
+++ b/program/localization/ms_MY/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Draf';
$labels['sent'] = 'Hantar';
$labels['trash'] = 'Tong Sampah';
$labels['junk'] = 'Junk';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Subjek';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Mod senarai paparan';
$labels['folderactions'] = 'Aksi folder';
$labels['compact'] = 'Kompak';
$labels['empty'] = 'Kosong';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Penggunaan cakera';
$labels['unknown'] = 'tidak diketahui';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Set semula carian';
$labels['searchmod'] = 'Pengubah carian';
$labels['msgtext'] = 'Keseluruhan mesej';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Buka dalam tetingkap baru';
$labels['emlsave'] = 'Muat-turun (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Papar set akhir';
$labels['group'] = 'Group';
$labels['groups'] = 'Kumpulan';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Alamat-alamat Peribadi';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/nb_NO/labels.inc b/program/localization/nb_NO/labels.inc
index cba58dc9c..b5c8ce4c6 100644
--- a/program/localization/nb_NO/labels.inc
+++ b/program/localization/nb_NO/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Kladd';
$labels['sent'] = 'Sendt';
$labels['trash'] = 'Slettet';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Emne';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Listevisningsmodus';
$labels['folderactions'] = 'Mappehandlinger...';
$labels['compact'] = 'Rydd opp';
$labels['empty'] = 'Tøm';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Plassforbruk';
$labels['unknown'] = 'ukjent';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Nullstill søk';
$labels['searchmod'] = 'Søke felt';
$labels['msgtext'] = 'Hele meldingen';
$labels['body'] = 'Meldingstekst';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Ã…pne i nytt vindu';
$labels['emlsave'] = 'Last ned (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Vis siste sett';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Grupper';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Egne adresser';
$labels['searchsave'] = 'Lagre søk';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorer ord med tall';
$labels['spellcheckignorecaps'] = 'Ignorer ord med kun store bokstaver';
$labels['addtodict'] = 'Legg til i ordbok';
$labels['mailtoprotohandler'] = 'Registrer protokollhåndtering for mailto-lenker';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Meldinger videresendes';
$labels['inline'] = 'i teksten';
$labels['asattachment'] = 'som vedlegg';
diff --git a/program/localization/ne_NP/labels.inc b/program/localization/ne_NP/labels.inc
index 29d43ef9c..5f69e1916 100644
--- a/program/localization/ne_NP/labels.inc
+++ b/program/localization/ne_NP/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'डà¥à¤°à¤¾à¤«à¥à¤Ÿà¤¹à¤°à¥‚';
$labels['sent'] = 'पठईà¤à¤•à¤¾ मेलहरà¥';
$labels['trash'] = 'रदà¥à¤¦à¥€ टोकरी';
$labels['junk'] = 'सà¥à¤ªà¤¾à¤®';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'विषय';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'छोटो गरà¥à¤¨à¥à¤¹à¥‹à¤¸';
$labels['empty'] = 'खाली गरà¥à¤¨à¥‡';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'डिसà¥à¤•à¤•à¥‹ उपभोग';
$labels['unknown'] = 'अजà¥à¤žà¤¾à¤¤';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'पन: खोज';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'अनà¥à¤¤à¤¿à¤® सेट देखाउनà¥à
$labels['group'] = 'Group';
$labels['groups'] = 'समूहहरà¥';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'वà¥à¤¯à¤•à¥à¤¤à¤¿à¤—त ठेगानाहरà¥';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/nl_BE/labels.inc b/program/localization/nl_BE/labels.inc
index eb44eefc0..1e6bb2d2f 100644
--- a/program/localization/nl_BE/labels.inc
+++ b/program/localization/nl_BE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Concepten';
$labels['sent'] = 'Verzonden berichten';
$labels['trash'] = 'Prullenbak';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Onderwerp';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Lijstweergave mode';
$labels['folderactions'] = 'Acties voor map...';
$labels['compact'] = 'Comprimeren';
$labels['empty'] = 'Legen';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Gebruikte schijfruimte';
$labels['unknown'] = 'onbekend';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Zoek opnieuw';
$labels['searchmod'] = 'Zoekopties';
$labels['msgtext'] = 'Volledig bericht';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Openen in een nieuw venster';
$labels['emlsave'] = 'Opslaan (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Toon laatste';
$labels['group'] = 'Groep';
$labels['groups'] = 'Groepen';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personlijke adressen';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/nl_NL/labels.inc b/program/localization/nl_NL/labels.inc
index 7bd48bd4a..8a6f994fa 100644
--- a/program/localization/nl_NL/labels.inc
+++ b/program/localization/nl_NL/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Concepten';
$labels['sent'] = 'Verzonden';
$labels['trash'] = 'Prullenbak';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Toon echte namen voor speciale mappen';
// message listing
$labels['subject'] = 'Onderwerp';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Lijstweergave';
$labels['folderactions'] = 'Mapacties...';
$labels['compact'] = 'Opschonen';
$labels['empty'] = 'Legen';
+$labels['importmessages'] = 'Berichten importeren';
$labels['quota'] = 'Opslagverbruik';
$labels['unknown'] = 'onbekend';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Wis zoekopdracht';
$labels['searchmod'] = 'Zoekopties';
$labels['msgtext'] = 'Gehele bericht';
$labels['body'] = 'Inhoud';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Openen in een nieuw venster';
$labels['emlsave'] = 'Opslaan (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Laatste pagina';
$labels['group'] = 'Groep';
$labels['groups'] = 'Groepen';
+$labels['listgroup'] = 'Toon groepsleden';
$labels['personaladrbook'] = 'Persoonlijk adresboek';
$labels['searchsave'] = 'Zoekopdracht opslaan';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Negeer woorden met cijfers';
$labels['spellcheckignorecaps'] = 'Negeer woorden welke volledig uit hoofdletters bestaan';
$labels['addtodict'] = 'Voeg toe aan woordenboek';
$labels['mailtoprotohandler'] = 'Registreer protocolhandler voor mailto: links';
+$labels['standardwindows'] = 'Behandel pop-ups als normale vensters';
$labels['forwardmode'] = 'Berichten doorsturen';
$labels['inline'] = 'invoegen';
$labels['asattachment'] = 'als bijlage';
diff --git a/program/localization/nn_NO/labels.inc b/program/localization/nn_NO/labels.inc
index d1a1c5700..5934a01d9 100644
--- a/program/localization/nn_NO/labels.inc
+++ b/program/localization/nn_NO/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Kladd';
$labels['sent'] = 'Sendt';
$labels['trash'] = 'Sletta';
$labels['junk'] = 'Søppel';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Emne';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Listevisningmodus';
$labels['folderactions'] = 'Mappehandlingar';
$labels['compact'] = 'Kompakt';
$labels['empty'] = 'Tom';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Plassbruk';
$labels['unknown'] = 'ukjend';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Tilbakestill søk';
$labels['searchmod'] = 'Søkeutsagn';
$labels['msgtext'] = 'Heile eposten';
$labels['body'] = 'Meldingstekst';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Opna i nytt vindauga';
$labels['emlsave'] = 'Last ned (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Siste side';
$labels['group'] = 'Gruppe';
$labels['groups'] = 'Gruppar';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personlege adresser';
$labels['searchsave'] = 'Lagre søk';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorer ord med tal';
$labels['spellcheckignorecaps'] = 'Ignorer ord med berre store bokstavar';
$labels['addtodict'] = 'Legg til i ordliste';
$labels['mailtoprotohandler'] = 'Registrer protokollhandsaming for mailto-lenkjer';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Meldingar vidaresendast';
$labels['inline'] = 'i teksten';
$labels['asattachment'] = 'som vedlegg';
diff --git a/program/localization/pl_PL/labels.inc b/program/localization/pl_PL/labels.inc
index 426ac381e..d7b9cd2d4 100644
--- a/program/localization/pl_PL/labels.inc
+++ b/program/localization/pl_PL/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Kopie robocze';
$labels['sent'] = 'Wysłane';
$labels['trash'] = 'Kosz';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Pokaż prawdziwe nazwy dla folderów specjalnych';
// message listing
$labels['subject'] = 'Temat';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Typ listy';
$labels['folderactions'] = 'Działania na folderach...';
$labels['compact'] = 'PorzÄ…dkuj';
$labels['empty'] = 'Opróżnij';
+$labels['importmessages'] = 'Import wiadomości';
$labels['quota'] = 'Użyte miejsce';
$labels['unknown'] = 'nieznane';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Wyczyść filtr';
$labels['searchmod'] = 'Parametry wyszukiwania';
$labels['msgtext'] = 'Cała wiadomość';
$labels['body'] = 'Treść';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Otwórz w nowym oknie';
$labels['emlsave'] = 'Pobierz (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Ostatnia strona';
$labels['group'] = 'Grupa';
$labels['groups'] = 'Grupy';
+$labels['listgroup'] = 'Członkowie grupy';
$labels['personaladrbook'] = 'Kontakty osobiste';
$labels['searchsave'] = 'Zapisz wyszukiwanie';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignoruj słowa zawierające cyfry';
$labels['spellcheckignorecaps'] = 'Ignoruj słowa pisane wielkimi literami';
$labels['addtodict'] = 'Dodaj do słownika';
$labels['mailtoprotohandler'] = 'Zainstaluj obsługę linków mailto:';
+$labels['standardwindows'] = 'Traktuj okna wyskakujÄ…ce jako standardowe okna';
$labels['forwardmode'] = 'Przekazywanie wiadomości';
$labels['inline'] = 'w treści';
$labels['asattachment'] = 'jako załącznik';
diff --git a/program/localization/pl_PL/messages.inc b/program/localization/pl_PL/messages.inc
index fb7ad6c97..3cac0c426 100644
--- a/program/localization/pl_PL/messages.inc
+++ b/program/localization/pl_PL/messages.inc
@@ -126,6 +126,8 @@ $messages['importwait'] = 'Importowanie, proszę czekać...';
$messages['importformaterror'] = 'Import nieudany! Użyty plik nie jest poprawnym plikiem importu danych.';
$messages['importconfirm'] = '<b>Pomyślnie dodano $inserted kontaktów, pominięto $skipped istniejących wpisów</b>:<p><em>$names</em></p>.';
$messages['importconfirmskipped'] = '<b>Pominięto $skipped istniejących wpisów.</b>';
+$messages['importmessagesuccess'] = 'Pomyślnie zaimportowano następującą liczbę wiadomości: $nr';
+$messages['importmessageerror'] = 'Import nieudany! Wgrywany plik nie jest poprawną wiadomością lub plikiem skrzynki pocztowej';
$messages['opnotpermitted'] = 'Niedozwolona operacja!';
$messages['nofromaddress'] = 'Brak adresu e-mail w wybranej tożsamości.';
$messages['editorwarning'] = 'Zmiana edytora spowoduje utratę formatowania tekstu. Czy jesteś pewien, że chcesz to zrobić?';
diff --git a/program/localization/ps/labels.inc b/program/localization/ps/labels.inc
index 262e3d490..d5e513419 100755
--- a/program/localization/ps/labels.inc
+++ b/program/localization/ps/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'بارليک';
$labels['sent'] = 'Ù„ÛÚ–Ù„ شوي ليکونه';
$labels['trash'] = 'کثاÙت دانÛ';
$labels['junk'] = 'جنک';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'مضمون';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Ú©ÛÚšÚ©Ù„ÛŒ';
$labels['empty'] = 'تش';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ټيکلي لارښود';
$labels['unknown'] = 'نامعلوم';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'د Ù¾Ù„Ù¼Ù†Û Ø¨ÙŠØ§Ø³Ù…ÙˆÙ†';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'په نوي Ú©Ú“Ú©Û Ú©Û Ù¾Ø±Ø§Ù†ÙŠØ²Ù‡';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'پای غونډ وښيه';
$labels['group'] = 'Group';
$labels['groups'] = 'Ú‰Ù„Û';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Úاني پتÛ';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/pt_BR/labels.inc b/program/localization/pt_BR/labels.inc
index 9a1946eee..e70ae35b9 100644
--- a/program/localization/pt_BR/labels.inc
+++ b/program/localization/pt_BR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Rascunhos';
$labels['sent'] = 'Enviados';
$labels['trash'] = 'Lixeira';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Exibir o nome real das pastas de sistema';
// message listing
$labels['subject'] = 'Assunto';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Visualização em lista';
$labels['folderactions'] = 'Ações para as pastas...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Esvaziar';
+$labels['importmessages'] = 'Importar mensagens';
$labels['quota'] = 'Uso de disco';
$labels['unknown'] = 'desconhecido';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Limpar pesquisa';
$labels['searchmod'] = 'Opções da pesquisa';
$labels['msgtext'] = 'Mensagem inteira';
$labels['body'] = 'Conteúdo';
+$labels['type'] = 'Tipo';
$labels['openinextwin'] = 'Abrir em nova janela';
$labels['emlsave'] = 'Baixar (formato .eml)';
@@ -267,7 +270,7 @@ $labels['yourmessage'] = 'Esta é uma confirmação de leitura da sua mensagem';
$labels['receiptnote'] = 'Nota: Esta confirmação de leitura somente informa que a mensagem foi aberta no computador do destinatário. Não há garantia que o destinatário tenha lido ou compreendido o conteúdo da mensagem.';
// address boook
-$labels['name'] = 'Nome de exibição';
+$labels['name'] = 'Nome';
$labels['firstname'] = 'Primeiro Nome';
$labels['surname'] = 'Sobrenome';
$labels['middlename'] = 'Segundo Nome';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Última Página';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
+$labels['listgroup'] = 'Listar membros do grupo';
$labels['personaladrbook'] = 'Endereços pessoais';
$labels['searchsave'] = 'Salvar pesquisa';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorar palavras com números';
$labels['spellcheckignorecaps'] = 'Ignorar palavras com todas letras maiúsculas';
$labels['addtodict'] = 'Adicionar ao dicionário';
$labels['mailtoprotohandler'] = 'Associar links de e-mail (mailto:) para envio de mensagem através do webmail';
+$labels['standardwindows'] = 'Usar popups como janelas do navegador';
$labels['forwardmode'] = 'Encaminhamento de mensagens';
$labels['inline'] = 'Em linha (no corpo da mensagem)';
$labels['asattachment'] = 'como anexo';
@@ -484,7 +489,7 @@ $labels['messagecount'] = 'Mensagens';
$labels['create'] = 'Criar';
$labels['createfolder'] = 'Criar nova pasta';
$labels['managefolders'] = 'Gerenciar pastas';
-$labels['specialfolders'] = 'Pastas especiais';
+$labels['specialfolders'] = 'Pastas de sistema';
$labels['properties'] = 'Propriedades';
$labels['folderproperties'] = 'Propriedades da pasta';
$labels['parentfolder'] = 'Pasta pai';
diff --git a/program/localization/pt_PT/labels.inc b/program/localization/pt_PT/labels.inc
index 316255e5e..cc4c534e0 100644
--- a/program/localization/pt_PT/labels.inc
+++ b/program/localization/pt_PT/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Rascunhos';
$labels['sent'] = 'Itens Enviados';
$labels['trash'] = 'Reciclagem';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Mostrar nomes reais para as pastas especiais';
// message listing
$labels['subject'] = 'Assunto';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Modo de visualização';
$labels['folderactions'] = 'Acções para pastas...';
$labels['compact'] = 'Compactar';
$labels['empty'] = 'Esvaziar';
+$labels['importmessages'] = 'Importar mensagens';
$labels['quota'] = 'Espaço utilizado';
$labels['unknown'] = 'desconhecido';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Limpar pesquisa';
$labels['searchmod'] = 'Pesquisar em';
$labels['msgtext'] = 'Mensagem completa';
$labels['body'] = 'Corpo';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Abrir numa nova janela';
$labels['emlsave'] = 'Guardar como (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Última página';
$labels['group'] = 'Grupo';
$labels['groups'] = 'Grupos';
+$labels['listgroup'] = 'Lista de membros do grupo';
$labels['personaladrbook'] = 'Endereços pessoais';
$labels['searchsave'] = 'Guardar pesquisa';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorar palavras com números';
$labels['spellcheckignorecaps'] = 'Ignorar palavras em maiúsculas';
$labels['addtodict'] = 'Adicionar ao dicionário';
$labels['mailtoprotohandler'] = 'Registar manipulador de protocolo para mailto: links';
+$labels['standardwindows'] = 'Lidar com popups como janelas padrão';
$labels['forwardmode'] = 'Reencaminhamento de mensagens';
$labels['inline'] = 'em linha';
$labels['asattachment'] = 'como anexo';
diff --git a/program/localization/ro_RO/labels.inc b/program/localization/ro_RO/labels.inc
index 6b59da313..4f6ddb1fa 100644
--- a/program/localization/ro_RO/labels.inc
+++ b/program/localization/ro_RO/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Ciorne';
$labels['sent'] = 'Trimise';
$labels['trash'] = 'Gunoi';
$labels['junk'] = 'Spam';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Subiect';
@@ -46,25 +47,25 @@ $labels['to'] = 'Destinatar';
$labels['cc'] = 'Copie (CC)';
$labels['bcc'] = 'Copie oarbă (BCC)';
$labels['replyto'] = 'Răspunde la';
-$labels['followupto'] = 'Followup-To';
+$labels['followupto'] = 'Followup La';
$labels['date'] = 'Data';
$labels['size'] = 'Mărime';
$labels['priority'] = 'Prioritate';
$labels['organization'] = 'Organizaţie';
-$labels['readstatus'] = 'Starea de citit';
+$labels['readstatus'] = 'Citit/Necitit';
$labels['listoptions'] = 'Listează opţiunile...';
$labels['mailboxlist'] = 'Dosare';
$labels['messagesfromto'] = 'Mesaje de la $from până la $to din $count';
$labels['threadsfromto'] = 'Grupuri de la $from până la $to din $count';
-$labels['messagenrof'] = '$nr mesaje din $count';
+$labels['messagenrof'] = 'Mesajul $nr din $count';
$labels['fromtoshort'] = '$from - $to din $count';
$labels['copy'] = 'Copiază';
$labels['move'] = 'Mută';
$labels['moveto'] = 'Mută in...';
$labels['download'] = 'Descarcă';
-$labels['open'] = 'Open';
+$labels['open'] = 'Deschide';
$labels['showattachment'] = 'Arată';
$labels['showanyway'] = 'Arată oricum';
@@ -127,22 +128,22 @@ $labels['checkmail'] = 'Verifică mesaje noi';
$labels['compose'] = 'Scrie un mesaj';
$labels['writenewmessage'] = 'Scrie mesaj nou';
$labels['reply'] = 'Răspunde';
-$labels['replytomessage'] = 'Răspunde la mesaj';
+$labels['replytomessage'] = 'Răspunde expeditorului';
$labels['replytoallmessage'] = 'Răspunde la toţi';
$labels['replyall'] = 'Răspunde la toţi';
-$labels['replylist'] = 'Lista de răspuns';
+$labels['replylist'] = 'Răspunde listei';
$labels['forward'] = 'Înaintează';
$labels['forwardinline'] = 'Înaintează ca citat';
$labels['forwardattachment'] = 'Înaintează ca ataşament';
$labels['forwardmessage'] = 'Trimite mesajul mai departe';
-$labels['deletemessage'] = 'Trimite mesajul la gunoi';
+$labels['deletemessage'] = 'Șterge mesajul';
$labels['movemessagetotrash'] = 'Mută mesajul la gunoi';
$labels['printmessage'] = 'Listează mesajul';
$labels['previousmessage'] = 'Afişează mesajul anterior';
$labels['firstmessage'] = 'Afişează primul mesaj';
$labels['nextmessage'] = 'Afişează următorul mesaj';
$labels['lastmessage'] = 'Afişează ultimul mesaj';
-$labels['backtolist'] = 'ÃŽnapoi la lista cu mesaje';
+$labels['backtolist'] = 'ÃŽnapoi la mesaje';
$labels['viewsource'] = 'Afişează sursa';
$labels['mark'] = 'Marchează';
$labels['markmessages'] = 'Marchează mesajele';
@@ -157,12 +158,12 @@ $labels['options'] = 'Opţiuni';
$labels['select'] = 'Selectează';
$labels['all'] = 'Toate';
-$labels['none'] = 'Fără sortare';
+$labels['none'] = 'Niciunul';
$labels['currpage'] = 'Pagina curentă';
$labels['unread'] = 'Necitite';
$labels['flagged'] = 'Marcat';
$labels['unanswered'] = 'Fără răspuns';
-$labels['withattachment'] = 'With attachment';
+$labels['withattachment'] = 'Cu atașament';
$labels['deleted'] = 'Åžterse';
$labels['undeleted'] = 'Nu a fost șters';
$labels['invert'] = 'Inversează';
@@ -190,9 +191,10 @@ $labels['listsorting'] = 'Sortează după';
$labels['listorder'] = 'Ordinea de sortare';
$labels['listmode'] = 'Mod de vizualizare';
-$labels['folderactions'] = 'Actiuni asupra folder-ului...';
+$labels['folderactions'] = 'Acțiuni dosar...';
$labels['compact'] = 'Compactează';
$labels['empty'] = 'GoleÅŸte';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Spaţiu folosit';
$labels['unknown'] = 'necunoscut';
@@ -203,17 +205,18 @@ $labels['resetsearch'] = 'Anulează căutarea';
$labels['searchmod'] = 'Parametrii de căutare';
$labels['msgtext'] = 'Tot mesajul';
$labels['body'] = 'Corp';
+$labels['type'] = 'Type';
-$labels['openinextwin'] = 'Deschide într-o fereastră nouă';
+$labels['openinextwin'] = 'Deschide în fereastră nouă';
$labels['emlsave'] = 'Salvează în format .eml';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Afișează în format text';
+$labels['changeformathtml'] = 'Afișează în format HTML';
// message compose
$labels['editasnew'] = 'Editează ca nou';
$labels['send'] = 'Trimite';
$labels['sendmessage'] = 'Trimite mesaj';
-$labels['savemessage'] = 'Salvează această ciornă';
+$labels['savemessage'] = 'Salvează ciornă';
$labels['addattachment'] = 'Ataşează fişier';
$labels['charset'] = 'Set de caractere';
$labels['editortype'] = 'Tip de editor';
@@ -244,21 +247,21 @@ $labels['highest'] = 'Cea mai mare';
$labels['nosubject'] = '(fără subiect)';
$labels['showimages'] = 'Afişează imagini';
$labels['alwaysshow'] = 'Afişează întotdeauna imaginile de la $sender';
-$labels['isdraft'] = 'Acesta este un mesaj schiţă.';
+$labels['isdraft'] = 'Acest mesaj este o ciornă.';
$labels['andnmore'] = '$nr mai multe...';
$labels['togglemoreheaders'] = 'Arată mai mult din antet';
$labels['togglefullheaders'] = 'Arată mai puțin din antet';
$labels['htmltoggle'] = 'HTML';
$labels['plaintoggle'] = 'Text simplu';
-$labels['savesentmessagein'] = 'Salvează mesajele în';
+$labels['savesentmessagein'] = 'Salvează mesajele trimise în';
$labels['dontsave'] = 'Nu salva';
-$labels['maxuploadsize'] = 'Mărimea maximă admisă a fişierului este $size';
+$labels['maxuploadsize'] = 'Mărimea maxim admisă a fişierului este $size';
-$labels['addcc'] = 'Adaugă Cc';
-$labels['addbcc'] = 'Adaugă Bcc';
+$labels['addcc'] = 'Adaugă CC';
+$labels['addbcc'] = 'Adaugă BCC';
$labels['addreplyto'] = 'Adaugă Raspunde-La';
-$labels['addfollowupto'] = 'Adaugă Followup-To';
+$labels['addfollowupto'] = 'Adaugă Followup-La';
// mdn
$labels['mdnrequest'] = 'Expeditorul acestui mesaj a solicitat să fie notificat la cititrea mesajului. Doriţi să notificaţi expeditorul?';
@@ -267,7 +270,7 @@ $labels['yourmessage'] = 'Aceasta este o confirmare de primire a mesajului dumne
$labels['receiptnote'] = 'Notă: Această confirmare doar vă informează că mesajul a fost afişat pe calculatorul destinatarului. Nu există nici o garanţie că destinatarul a citit sau a inţeles conţinutul mesajului.';
// address boook
-$labels['name'] = 'Numele Contactului';
+$labels['name'] = 'Numele Contact';
$labels['firstname'] = 'Nume';
$labels['surname'] = 'Prenume';
$labels['middlename'] = 'Iniţiala tatălui';
@@ -281,11 +284,11 @@ $labels['maidenname'] = 'Nume de fată';
$labels['email'] = 'E-Mail';
$labels['phone'] = 'Telefon';
$labels['address'] = 'Adresă';
-$labels['street'] = 'Stradă';
+$labels['street'] = 'Strada';
$labels['locality'] = 'OraÈ™';
$labels['zipcode'] = 'Cod poÅŸtal';
$labels['region'] = 'Stat/Judeţ';
-$labels['country'] = 'Țară';
+$labels['country'] = 'Èšara';
$labels['birthday'] = 'Ziua de naÅŸtere:';
$labels['anniversary'] = 'Aniversare';
$labels['website'] = 'Pagină web';
@@ -302,8 +305,8 @@ $labels['advsearch'] = 'Căutare avansată';
$labels['advanced'] = 'Avansat';
$labels['other'] = 'Altele';
-$labels['typehome'] = 'Pagina Principală';
-$labels['typework'] = 'Servici';
+$labels['typehome'] = 'Acasă';
+$labels['typework'] = 'Serviciu';
$labels['typeother'] = 'Altele';
$labels['typemobile'] = 'Mobil';
$labels['typemain'] = 'Principal';
@@ -318,7 +321,7 @@ $labels['typeblog'] = 'Blog';
$labels['typeprofile'] = 'Profil';
$labels['addfield'] = 'Adaugă câmp...';
-$labels['addcontact'] = 'Adaugă contactul selectat în agendă';
+$labels['addcontact'] = 'Adaugă contact nou';
$labels['editcontact'] = 'Modifică contact';
$labels['contacts'] = 'Contacte';
$labels['contactproperties'] = 'Proprietăţile contactului...';
@@ -331,7 +334,7 @@ $labels['delete'] = 'Åžterge';
$labels['rename'] = 'RedenumeÅŸte';
$labels['addphoto'] = 'Adaugă';
$labels['replacephoto'] = 'Înlocuiește';
-$labels['uploadphoto'] = 'Încarcă poya';
+$labels['uploadphoto'] = 'Încarcă imagine';
$labels['newcontact'] = 'Creează contact nou';
$labels['deletecontact'] = 'Åžterge contactul selectat';
@@ -348,12 +351,13 @@ $labels['groupdelete'] = 'Șterge grupul';
$labels['groupremoveselected'] = 'Șterge contactele selectate din grup';
$labels['previouspage'] = 'Pagina anterioară';
-$labels['firstpage'] = 'Arată primul set';
+$labels['firstpage'] = 'Prima pagină';
$labels['nextpage'] = 'Pagina următoare';
-$labels['lastpage'] = 'Arată ultimul set';
+$labels['lastpage'] = 'Ultima pagină';
$labels['group'] = 'Grup';
$labels['groups'] = 'Grupuri';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Adrese personale';
$labels['searchsave'] = 'Salvează căutarea';
@@ -364,7 +368,7 @@ $labels['importcontacts'] = 'Importă contacte';
$labels['importfromfile'] = 'Importă din fişier:';
$labels['importtarget'] = 'Adaugă contactele noi în agenda:';
$labels['importreplace'] = 'Înlocuieşte întreaga agendă';
-$labels['importdesc'] = 'Puteți încărcat contacte dintr-o agendă existentă.<br/>Momentan este suportat importul în formatul <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> sau în formatul CSV (comma-separated).';
+$labels['importdesc'] = 'Puteți încărca contacte dintr-o agendă existentă.<br/>Momentan este suportat importul în formatul <a href="http://en.wikipedia.org/wiki/VCard">vCard</a> sau în formatul CSV (comma-separated).';
$labels['done'] = 'Finalizat';
// settings
@@ -395,14 +399,14 @@ $labels['language'] = 'Limba';
$labels['timezone'] = 'Fus orar';
$labels['pagesize'] = 'Rânduri pe pagină';
$labels['signature'] = 'Semnătură';
-$labels['dstactive'] = 'Reglare automată oră de vară';
+$labels['dstactive'] = 'Reglare ora de vară';
$labels['showinextwin'] = 'Deschide mesajul în fereastră nouă';
$labels['composeextwin'] = 'Compune mesajul în fereastră nouă';
$labels['htmleditor'] = 'Scrie mesaje HTML';
$labels['htmlonreply'] = 'la răspunsul doar către un mesaj HTML';
$labels['htmlonreplyandforward'] = 'la trimitere mai departe sau la răspuns la mesaj HTML';
$labels['htmlsignature'] = 'Semnatură HTML';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Arată adresa email alături de nume afișat';
$labels['previewpane'] = 'Previzualizare mail';
$labels['skin'] = 'Temă interfaţă';
$labels['logoutclear'] = 'GoleÅŸte CoÅŸul de Gunoi la deconectare';
@@ -411,15 +415,15 @@ $labels['uisettings'] = 'Interfaţă utilizator';
$labels['serversettings'] = 'Configuraţii server';
$labels['mailboxview'] = 'Afişare căsuţă poştală';
$labels['mdnrequests'] = 'Notificări expeditor';
-$labels['askuser'] = 'întreabă utilizatorul';
+$labels['askuser'] = 'întreabă-mă';
$labels['autosend'] = 'trimite automat';
$labels['autosendknown'] = 'trimite confirmarea de primire către contactele mele, în rest întreabă-mă';
$labels['autosendknownignore'] = 'trimite confirmarea de primire către contactele mele, în rest ignoră';
$labels['ignore'] = 'ignoră';
-$labels['readwhendeleted'] = 'Marchează mesajul ca şi citit la ştergere';
+$labels['readwhendeleted'] = 'Marchează mesajul ca citit la ştergere';
$labels['flagfordeletion'] = 'Marchează mesajul pentru ştergere în loc de a-l şterge direct';
$labels['skipdeleted'] = 'Nu arăta mesajele şterse';
-$labels['deletealways'] = 'Dacă mutarea mesajelor în coş eşuează, se vor şterge';
+$labels['deletealways'] = 'Dacă mutarea mesajelor în Coş eşuează, șterge-le';
$labels['deletejunk'] = 'Șterge direct mesajele în Junk';
$labels['showremoteimages'] = 'Arată imaginile care nu fac parte din e-mail';
$labels['fromknownsenders'] = 'de la expeditori cunoscuţi';
@@ -443,7 +447,7 @@ $labels['checkallfolders'] = 'Verifică toate dosarele pentru mesaje noi';
$labels['displaynext'] = 'După ştergerea sau mutarea unui mesaj afişează-l pe următorul din listă';
$labels['defaultfont'] = 'Font-ul implicit al mesajului HTML';
$labels['mainoptions'] = 'Opţiuni principale';
-$labels['browseroptions'] = 'Optiuni browser';
+$labels['browseroptions'] = 'Opțiuni browser';
$labels['section'] = 'Secţiune';
$labels['maintenance'] = 'Mentenanţă';
$labels['newmessage'] = 'Mesaj nou';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignoră cuvintele cu numere';
$labels['spellcheckignorecaps'] = 'Ignoră cuvintele din litere mari';
$labels['addtodict'] = 'Adaugă la dicţionar';
$labels['mailtoprotohandler'] = 'Îregistrează handler protocol pentru mailto: link-uri';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Trimitere mai departe mesaj';
$labels['inline'] = 'într-e linii';
$labels['asattachment'] = 'ca atașament';
diff --git a/program/localization/ru_RU/labels.inc b/program/localization/ru_RU/labels.inc
index 8a136aa77..d2b8e75c4 100644
--- a/program/localization/ru_RU/labels.inc
+++ b/program/localization/ru_RU/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Черновики';
$labels['sent'] = 'Отправленные';
$labels['trash'] = 'Корзина';
$labels['junk'] = 'СПÐÐœ';
+$labels['show_real_foldernames'] = 'Показывать наÑтоÑщие Ð½Ð°Ð·Ð²Ð°Ð½Ð¸Ñ Ñпециальных папок';
// message listing
$labels['subject'] = 'Тема';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Режим проÑмотра';
$labels['folderactions'] = 'Операции над папкой...';
$labels['compact'] = 'Сжать';
$labels['empty'] = 'ОпуÑтошить';
+$labels['importmessages'] = 'Импорт Ñообщений';
$labels['quota'] = 'Квота';
$labels['unknown'] = 'неизвеÑтно';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'СброÑ';
$labels['searchmod'] = 'Варианты поиÑка';
$labels['msgtext'] = 'Ð’ÑÑ‘ Ñообщение';
$labels['body'] = 'Тело пиÑьма';
+$labels['type'] = 'Тип';
$labels['openinextwin'] = 'Открыть в новом окне';
$labels['emlsave'] = 'Сохранить (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Показать поÑледнюю ÑтраницÑ
$labels['group'] = 'Группа';
$labels['groups'] = 'Группы';
+$labels['listgroup'] = 'СпиÑок членов группы';
$labels['personaladrbook'] = 'ПерÑональные адреÑа';
$labels['searchsave'] = 'Сохранить запроÑ';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'ПропуÑкать Ñлова Ñ Ñ†Ð¸Ñ„Ñ€Ð°
$labels['spellcheckignorecaps'] = 'ПропуÑкать Ñлова из пропиÑных букв';
$labels['addtodict'] = 'Добавить в Ñловарь';
$labels['mailtoprotohandler'] = 'ЗарегиÑтрировать обработчик Ð´Ð»Ñ ÑÑылок mailto:';
+$labels['standardwindows'] = 'Обрабатывать вÑплывающие окна как обычные';
$labels['forwardmode'] = 'ПереÑылка Ñообщений';
$labels['inline'] = 'в текÑте';
$labels['asattachment'] = 'как вложение';
diff --git a/program/localization/si_LK/labels.inc b/program/localization/si_LK/labels.inc
index d8cd71662..92d33d3b7 100644
--- a/program/localization/si_LK/labels.inc
+++ b/program/localization/si_LK/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'කටු සටහන්';
$labels['sent'] = 'යà·à·€à·–';
$labels['trash'] = 'ඉවතලන බඳුන';
$labels['junk'] = 'සුන්බුන්';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'මà·à¶­à·˜à¶šà·à·€';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'බහà·à¶½à·”ම් ක්â€à¶»à·’යà·...';
$labels['compact'] = 'සංයුක්ත';
$labels['empty'] = 'හිස්';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Disk usage';
$labels['unknown'] = 'නොදනී';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'සෙවුම යලි පිහිටවීම';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'සම්පූර්ණ පණිවිඩය';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'නව කවුළුවක විවෘත කරන්න';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'අවසà·à¶± පිටුව පෙන්වනà
$labels['group'] = 'කණ්ඩà·à¶ºà¶¸';
$labels['groups'] = 'කණ්ඩà·à¶ºà¶¸à·Š';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'පුද්ගලික ලිපිනය';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'අංක සහිත වචන නොසල
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'à·à¶¶à·Šà¶¯ කà·à·‚යට එක් කරන්න';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/sk_SK/labels.inc b/program/localization/sk_SK/labels.inc
index 10673382a..465252409 100644
--- a/program/localization/sk_SK/labels.inc
+++ b/program/localization/sk_SK/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Rozpísané';
$labels['sent'] = 'Odoslané';
$labels['trash'] = 'Kôš';
$labels['junk'] = 'Nevyžiadaná pošta';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Predmet';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Režim zobrazenia zoznamu';
$labels['folderactions'] = 'Akcie so zložkou...';
$labels['compact'] = 'ZhustiÅ¥ prieÄinok';
$labels['empty'] = 'Vyprázdniť';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Zaplnenie schránky';
$labels['unknown'] = 'neznáme';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'VyÄistiÅ¥ vyhľadávanie';
$labels['searchmod'] = 'Parametre hľadanie';
$labels['msgtext'] = 'Celá správa';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Otvoriť v novom okne';
$labels['emlsave'] = 'Stiahnuť';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Posledná stránka';
$labels['group'] = 'Skupina';
$labels['groups'] = 'Skupiny';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Osobné adresy';
$labels['searchsave'] = 'Uložiť vyhľadávanie';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'IgnorovaÅ¥ slová s Äíslami';
$labels['spellcheckignorecaps'] = 'Ignorovať slová písané veľkými písmenami';
$labels['addtodict'] = 'Pridať do slovníka';
$labels['mailtoprotohandler'] = 'Zaregistrovať handler pre odkazy „mailto:“';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Preposielanie správ';
$labels['inline'] = 'v tele spávy';
$labels['asattachment'] = 'ako príloha';
diff --git a/program/localization/sl_SI/labels.inc b/program/localization/sl_SI/labels.inc
index 6b9ba2d41..c33ea479c 100644
--- a/program/localization/sl_SI/labels.inc
+++ b/program/localization/sl_SI/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Osnutki';
$labels['sent'] = 'Poslano';
$labels['trash'] = 'Smeti';
$labels['junk'] = 'Nezaželena sporoÄila';
+$labels['show_real_foldernames'] = 'Prikaži prava imena za posebne mape';
// message listing
$labels['subject'] = 'Zadeva';
@@ -162,7 +163,7 @@ $labels['currpage'] = 'Trenutna stran';
$labels['unread'] = 'Neprebrano';
$labels['flagged'] = 'OznaÄeno';
$labels['unanswered'] = 'NeoznaÄeno';
-$labels['withattachment'] = 'With attachment';
+$labels['withattachment'] = 'S priponko';
$labels['deleted'] = 'Izbrisano';
$labels['undeleted'] = 'Ni izbrisano';
$labels['invert'] = 'Zamenjaj';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'NaÄin prikaza seznama';
$labels['folderactions'] = 'Upravljanje map...';
$labels['compact'] = 'Stisni';
$labels['empty'] = 'Izprazni';
+$labels['importmessages'] = 'Uvozi sporoÄila';
$labels['quota'] = 'Poraba prostora';
$labels['unknown'] = 'neznana';
@@ -203,11 +205,12 @@ $labels['resetsearch'] = 'PrekliÄi iskanje';
$labels['searchmod'] = 'Spremembe iskanja';
$labels['msgtext'] = 'Celotno sporoÄilo';
$labels['body'] = 'Vsebina sporoÄila';
+$labels['type'] = 'Tip';
$labels['openinextwin'] = 'Odpri v novem oknu';
$labels['emlsave'] = 'Prenos datoteke (.eml)';
-$labels['changeformattext'] = 'Display in plain text format';
-$labels['changeformathtml'] = 'Display in HTML format';
+$labels['changeformattext'] = 'Prikaži kot golo besedilo';
+$labels['changeformathtml'] = 'Prikaži v formatu HTML';
// message compose
$labels['editasnew'] = 'Uredi kot novo';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Zadnja stran';
$labels['group'] = 'Skupina';
$labels['groups'] = 'Skupine';
+$labels['listgroup'] = 'IzpiÅ¡i seznam Älanov skupine';
$labels['personaladrbook'] = 'Stiki';
$labels['searchsave'] = 'Shrani iskanje';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'Sestavi sporoÄila z obogatenim besedilom';
$labels['htmlonreply'] = 'le pri odgovoru na sporoÄila z obogatenim besedilom';
$labels['htmlonreplyandforward'] = 'le pri posredovanju ali odgovoru na sporoÄila z obogatenim besedilom';
$labels['htmlsignature'] = 'Podpis z obogatenim besedilom';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Prikaži e-naslove poleg imen';
$labels['previewpane'] = 'Prikaži predogled';
$labels['skin'] = 'Tema uporabniškega vmesnika';
$labels['logoutclear'] = 'Izprazni mapo Smeti ob odjavi';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ne upoštevaj besed, ki vsebujejo številke';
$labels['spellcheckignorecaps'] = 'Ne upoÅ¡tevaj besed, ki vsebujejo samo velike Ärke';
$labels['addtodict'] = 'Dodaj v slovar';
$labels['mailtoprotohandler'] = 'Registriraj upravljavca protokola za e-naslov: povezave';
+$labels['standardwindows'] = 'Prikaži pojavna okna kot obiÄajna';
$labels['forwardmode'] = 'Posredovanje sporoÄil';
$labels['inline'] = 'medvrstiÄno';
$labels['asattachment'] = 'Kot priponka';
diff --git a/program/localization/sl_SI/messages.inc b/program/localization/sl_SI/messages.inc
index 081d912c1..dc731d01b 100644
--- a/program/localization/sl_SI/messages.inc
+++ b/program/localization/sl_SI/messages.inc
@@ -126,6 +126,8 @@ $messages['importwait'] = 'Uvažanje poteka...';
$messages['importformaterror'] = 'Uvoz ni uspel! Uvožena datoteka ni pravega formata.';
$messages['importconfirm'] = '<b>Uspešno uvoženi $inserted stiki, $skipped stikov že obstaja v imeniku</b>:<p><em>$names</em></p>';
$messages['importconfirmskipped'] = '<b>PreskoÄeni že obstojeÄi vnosi $skipped </b>';
+$messages['importmessagesuccess'] = 'UpeÅ¡no ste uvozili $nr sporoÄil.';
+$messages['importmessageerror'] = 'Uvoz je spodletel. Naložena datoteka ni veljavno sporoÄilo ali poÅ¡tna datoteka';
$messages['opnotpermitted'] = 'Operacija ni dovoljena.';
$messages['nofromaddress'] = 'V izbrani identiteti manjka elektronski naslov.';
$messages['editorwarning'] = 'Preklop v sploÅ¡en urejevalnik onemogoÄa uporabo izbranih nastavitev oblikovanja. Želite nadaljevati?';
diff --git a/program/localization/sq_AL/labels.inc b/program/localization/sq_AL/labels.inc
index ba9b559d8..e2cb6791b 100644
--- a/program/localization/sq_AL/labels.inc
+++ b/program/localization/sq_AL/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Drafte';
$labels['sent'] = 'Dërguar';
$labels['trash'] = 'Fshirë';
$labels['junk'] = 'Reklama';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Tema';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'Zvogëlo';
$labels['empty'] = 'Boshatis';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Përdorimi i diskut';
$labels['unknown'] = 'i panjohur';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Pastro kërkimin';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Shfaq grupin e fundit';
$labels['group'] = 'Group';
$labels['groups'] = 'Grupet';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Adresat Personale';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/sr_CS/labels.inc b/program/localization/sr_CS/labels.inc
index 130d3a7a6..4bdf25020 100644
--- a/program/localization/sr_CS/labels.inc
+++ b/program/localization/sr_CS/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'U pripremi';
$labels['sent'] = 'ПоÑлате';
$labels['trash'] = 'Канта';
$labels['junk'] = 'Смеће';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'ÐаÑлов';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'ЛиÑÑ‚ режим приказивања';
$labels['folderactions'] = 'ПоÑтавке фаÑцикле';
$labels['compact'] = 'Компакција';
$labels['empty'] = 'ИÑпразни';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Квота';
$labels['unknown'] = 'непозната';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Прикажи Ñве поруке';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Цела порука';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Отвори у новом прозору';
$labels['emlsave'] = 'Довнлоад (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Прикажи поÑледњи Ñкуп';
$labels['group'] = 'Група';
$labels['groups'] = 'Групе';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Личне адреÑе';
$labels['searchsave'] = 'Сачувај претрагу';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'игнориши речи Ñа бројевÐ
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Додај у речник';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/sv_SE/labels.inc b/program/localization/sv_SE/labels.inc
index f61433527..7169aeba8 100644
--- a/program/localization/sv_SE/labels.inc
+++ b/program/localization/sv_SE/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Utkast';
$labels['sent'] = 'Skickat';
$labels['trash'] = 'Papperskorg';
$labels['junk'] = 'Skräp';
+$labels['show_real_foldernames'] = 'Visa verkliga namn på särskilda kataloger';
// message listing
$labels['subject'] = 'Ämne';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Visningsläge';
$labels['folderactions'] = 'Hantera kataloger';
$labels['compact'] = 'Packa';
$labels['empty'] = 'Töm';
+$labels['importmessages'] = 'Importera meddelanden';
$labels['quota'] = 'Diskutrymme';
$labels['unknown'] = 'okänt';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Återställ sökning';
$labels['searchmod'] = 'Sökalternativ';
$labels['msgtext'] = 'Hela meddelandet';
$labels['body'] = 'Innehåll';
+$labels['type'] = 'Typ';
$labels['openinextwin'] = 'Öppna i nytt fönster';
$labels['emlsave'] = 'Spara (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Visa sista sidan';
$labels['group'] = 'Grupp';
$labels['groups'] = 'Kontaktgrupper';
+$labels['listgroup'] = 'Visa gruppmedlemmar';
$labels['personaladrbook'] = 'Personliga adresser';
$labels['searchsave'] = 'Lägg till sökning';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignorera ord med siffror';
$labels['spellcheckignorecaps'] = 'Ignorera ord med enbart stora bokstäver';
$labels['addtodict'] = 'Lägg till i ordlista';
$labels['mailtoprotohandler'] = 'Ange program för hantering av mailto-länkar';
+$labels['standardwindows'] = 'Hantera popup-rutor som standardfönster';
$labels['forwardmode'] = 'Vidarebefordra meddelande';
$labels['inline'] = 'Infogat';
$labels['asattachment'] = 'Bilaga';
diff --git a/program/localization/ta_IN/labels.inc b/program/localization/ta_IN/labels.inc
index bc1db7d00..197e80606 100644
--- a/program/localization/ta_IN/labels.inc
+++ b/program/localization/ta_IN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'வரைவà¯à®•à®³à¯';
$labels['sent'] = 'அனà¯à®ªà¯à®ªà®¿à®¯ அஞà¯à®šà®²à¯';
$labels['trash'] = 'கà¯à®ªà¯à®ªà¯ˆ';
$labels['junk'] = 'எரிதமà¯';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'தலைபà¯à®ªà¯';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'கà¯à®±à¯à®•à®¿à®¯';
$labels['empty'] = 'காலி';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'பயனà¯à®ªà®¾à®Ÿà¯à®Ÿà¯ அளவà¯';
$labels['unknown'] = 'தெரியாத';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'தேடலை மறà¯à®…மை';
$labels['searchmod'] = 'மாறà¯à®±à®¿à®•à®³à¯ˆ தேடà¯';
$labels['msgtext'] = 'à®®à¯à®´à¯ செயà¯à®¤à®¿';
$labels['body'] = 'Body';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'பà¯à®¤à¯ சாளரதà¯à®¤à®¿à®²à¯ திற';
$labels['emlsave'] = 'பதிவிறகà¯à®•à¯ (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'கடைசி கà¯à®´à¯à®µà¯ˆ காடà¯à®Ÿà
$labels['group'] = 'Group';
$labels['groups'] = 'கà¯à®´à¯à®•à¯à®•à®³à¯';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'சà¯à®¯ à®®à¯à®•à®µà®°à®¿';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'as attachment';
diff --git a/program/localization/th_TH/labels.inc b/program/localization/th_TH/labels.inc
index 03b4161fb..85b091e5b 100644
--- a/program/localization/th_TH/labels.inc
+++ b/program/localization/th_TH/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸ˆà¸”หมายร่าง';
$labels['sent'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸‚าออà¸';
$labels['trash'] = 'ถังขยะ';
$labels['junk'] = 'à¸à¸¥à¹ˆà¸­à¸‡à¸ˆà¸”หมายขยะ';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'หัวจดหมาย';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'List view mode';
$labels['folderactions'] = 'Folder actions...';
$labels['compact'] = 'à¹à¸šà¸šà¸¢à¹ˆà¸­';
$labels['empty'] = 'ว่างเปล่า';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'พื้นที่ใช้งาน';
$labels['unknown'] = 'ไม่ทราบ';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'ล้างà¸à¸²à¸£à¸„้นหา';
$labels['searchmod'] = 'Search modifiers';
$labels['msgtext'] = 'Entire message';
$labels['body'] = 'เนื้อหา';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Open in new window';
$labels['emlsave'] = 'Download (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Show last page';
$labels['group'] = 'Group';
$labels['groups'] = 'Groups';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Personal Addresses';
$labels['searchsave'] = 'Save search';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ignore words with numbers';
$labels['spellcheckignorecaps'] = 'Ignore words with all letters capitalized';
$labels['addtodict'] = 'Add to dictionary';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Messages forwarding';
$labels['inline'] = 'inline';
$labels['asattachment'] = 'เป็นไฟล์à¹à¸™à¸š';
diff --git a/program/localization/tr_TR/labels.inc b/program/localization/tr_TR/labels.inc
index 9e78ea3fa..c62c5c079 100644
--- a/program/localization/tr_TR/labels.inc
+++ b/program/localization/tr_TR/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Taslaklar';
$labels['sent'] = 'Giden';
$labels['trash'] = 'Çöp';
$labels['junk'] = 'Ä°stenmeyen';
+$labels['show_real_foldernames'] = 'Özel klasörler için gerçek isimleri göster';
// message listing
$labels['subject'] = 'Konu';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Liste görünümü';
$labels['folderactions'] = 'Klasör eylemleri...';
$labels['compact'] = 'Sıklaştır';
$labels['empty'] = 'BoÅŸalt';
+$labels['importmessages'] = 'Mesajları içe aktar';
$labels['quota'] = 'Disk kullanımı';
$labels['unknown'] = 'bilinmeyen';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Aramayı bitir';
$labels['searchmod'] = 'Arama detayları';
$labels['msgtext'] = 'Tüm posta gövdesi';
$labels['body'] = 'Gövde';
+$labels['type'] = 'Tip';
$labels['openinextwin'] = 'Yeni pencerede aç';
$labels['emlsave'] = 'Ä°ndir (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Sonuncuyu göster';
$labels['group'] = 'Grup';
$labels['groups'] = 'Gruplar';
+$labels['listgroup'] = 'Grup üyelerini listele';
$labels['personaladrbook'] = 'Adresler';
$labels['searchsave'] = 'Aramayı kaydet';
@@ -402,7 +406,7 @@ $labels['htmleditor'] = 'HTML postaları oluştur';
$labels['htmlonreply'] = 'sadece HTML postaları yanıtlarken';
$labels['htmlonreplyandforward'] = 'HTML biçimindeki posta yanıtlandığında veye iletildiğinde';
$labels['htmlsignature'] = 'HTML imza';
-$labels['showemail'] = 'Show email address with display name';
+$labels['showemail'] = 'Eposta adresini görünüm ismi ile görüntüle';
$labels['previewpane'] = 'Önizleme panelini göster';
$labels['skin'] = 'Arayüz görünümü';
$labels['logoutclear'] = 'Oturumu kapatınca Çöpü temizle';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'İçinde rakam geçen kelimleri göz ardı et
$labels['spellcheckignorecaps'] = 'Tümü büyük harf olan kelimleri göz ardı et';
$labels['addtodict'] = 'Sözlüğe Ekle';
$labels['mailtoprotohandler'] = 'mailto: bağlantıları için protokol işleyici kayıt et';
+$labels['standardwindows'] = 'Popup pencerelerini standart pencere olarak yönet';
$labels['forwardmode'] = 'Posta yönlendirme';
$labels['inline'] = 'postanın içinde';
$labels['asattachment'] = 'ek olarak';
diff --git a/program/localization/tr_TR/messages.inc b/program/localization/tr_TR/messages.inc
index 3b451d556..3f728b523 100644
--- a/program/localization/tr_TR/messages.inc
+++ b/program/localization/tr_TR/messages.inc
@@ -126,6 +126,8 @@ $messages['importwait'] = 'Aktarılıyor, lütfen bekleyin...';
$messages['importformaterror'] = 'İçe aktarım başarısız. Yüklenen dosya geçerli bir içe aktarım dosyası değil.';
$messages['importconfirm'] = '<b>$inserted kişi başarıyla aktarıldı</b>';
$messages['importconfirmskipped'] = '<b>Var olan $skipped girdi atlandı</b>';
+$messages['importmessagesuccess'] = '$nr adet mesaj başarıyla içe aktarıldı';
+$messages['importmessageerror'] = 'İçe aktarım başarısız. Yüklenen dosya geçerli bir içe aktarım dosyası değil.';
$messages['opnotpermitted'] = 'Bu iÅŸleme izin verilmedi!';
$messages['nofromaddress'] = 'Seçili kimlikte e-posta adresi yok';
$messages['editorwarning'] = 'Düz metin düzenleyiciye geçmek, metin üzerindeki bütün biçimlendirmeleri kaldıracak. Devam etmek istiyor musunuz?';
diff --git a/program/localization/uk_UA/labels.inc b/program/localization/uk_UA/labels.inc
index 4605bb98d..6ff37ee21 100644
--- a/program/localization/uk_UA/labels.inc
+++ b/program/localization/uk_UA/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Чернетки';
$labels['sent'] = 'ÐадіÑлані';
$labels['trash'] = 'Кошик';
$labels['junk'] = 'Спам';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Тема';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Режим переглÑду';
$labels['folderactions'] = 'Операції з папкою...';
$labels['compact'] = 'СтиÑнути';
$labels['empty'] = 'Спорожнити';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ВикориÑтано';
$labels['unknown'] = 'невідомо';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'ОчиÑтити пошук';
$labels['searchmod'] = 'Де шукати';
$labels['msgtext'] = 'Ð’ уÑьому лиÑÑ‚Ñ–';
$labels['body'] = 'Тіло повідомленнÑ';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Відкрити в новому вікні';
$labels['emlsave'] = 'Зберегти (.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'ОÑÑ‚Ð°Ð½Ð½Ñ Ñторінка';
$labels['group'] = 'Група';
$labels['groups'] = 'Групи';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'ПерÑональні адреÑи';
$labels['searchsave'] = 'Зберегти пошук';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'Ігнорувати Ñлова із чиÑл
$labels['spellcheckignorecaps'] = 'Ігнорувати Ñлова із великими буквами';
$labels['addtodict'] = 'Додати до Ñловника';
$labels['mailtoprotohandler'] = 'ЗареєÑтрувати обробник Ð´Ð»Ñ Ð¿Ð¾Ñилань mailto';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'ПереÑÐ¸Ð»Ð°Ð½Ð½Ñ Ð¿Ð¾Ð²Ñ–Ð´Ð¾Ð¼Ð»ÐµÐ½ÑŒ';
$labels['inline'] = 'у текÑÑ‚Ñ–';
$labels['asattachment'] = 'Ñк вкладеннÑ';
diff --git a/program/localization/vi_VN/labels.inc b/program/localization/vi_VN/labels.inc
index f1cf95149..aad0dafe6 100644
--- a/program/localization/vi_VN/labels.inc
+++ b/program/localization/vi_VN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'Thư nháp';
$labels['sent'] = 'Äã gá»­i';
$labels['trash'] = 'Sá»t rác';
$labels['junk'] = 'Thư rác';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = 'Tiêu Ä‘á»';
@@ -193,6 +194,7 @@ $labels['listmode'] = 'Xem dạng danh sách';
$labels['folderactions'] = 'Thao tác với thư mục';
$labels['compact'] = 'Nén';
$labels['empty'] = 'Trống';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'Lượng đĩa sử dụng';
$labels['unknown'] = 'Không rõ';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'Thiết lập lại tìm kiếm';
$labels['searchmod'] = 'Tìm kiếm với từ khóa và ký tự đặc biệt [() : " - ]';
$labels['msgtext'] = 'Toàn bộ thư';
$labels['body'] = 'Ná»™i dung thÆ°';
+$labels['type'] = 'Type';
$labels['openinextwin'] = 'Mở trong khung cửa mới';
$labels['emlsave'] = 'Tải vỠtheo định dạng .eml';
@@ -354,6 +357,7 @@ $labels['lastpage'] = 'Hiển thị trang cuối';
$labels['group'] = 'Nhóm';
$labels['groups'] = 'Các nhóm';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = 'Các địa chỉ cá nhân';
$labels['searchsave'] = 'Lưu tìm kiếm';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = 'BỠqua các từ kèm số';
$labels['spellcheckignorecaps'] = 'BỠqua các từ được viết hoa';
$labels['addtodict'] = 'Thêm vào từ điển';
$labels['mailtoprotohandler'] = 'Xác định cách xử lý giao thức mailto: liên kết';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = 'Chuyển tiếp thư';
$labels['inline'] = 'nội tuyến';
$labels['asattachment'] = 'dạng gửi kèm';
diff --git a/program/localization/zh_CN/labels.inc b/program/localization/zh_CN/labels.inc
index 23a42b96d..b568a7008 100644
--- a/program/localization/zh_CN/labels.inc
+++ b/program/localization/zh_CN/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'è‰ç¨¿ç®±';
$labels['sent'] = 'å·²å‘é€é‚®ä»¶';
$labels['trash'] = '已删除邮件';
$labels['junk'] = '垃圾邮件';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '主题';
@@ -193,6 +194,7 @@ $labels['listmode'] = '列表视图样å¼';
$labels['folderactions'] = '文件夹æ“作...';
$labels['compact'] = '压缩';
$labels['empty'] = '清空';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = '邮箱容é‡';
$labels['unknown'] = '未知';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = '清空';
$labels['searchmod'] = '修改æœç´¢';
$labels['msgtext'] = 'æ•´å°é‚®ä»¶';
$labels['body'] = '正文';
+$labels['type'] = 'Type';
$labels['openinextwin'] = '在新窗å£ä¸­æ‰“å¼€';
$labels['emlsave'] = '下载(.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = '最åŽä¸€é¡µ';
$labels['group'] = '分组';
$labels['groups'] = '分组';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = '个人通讯录';
$labels['searchsave'] = 'ä¿å­˜æœç´¢';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = '忽略带数字的å•è¯';
$labels['spellcheckignorecaps'] = '忽略所有大写字æ¯çš„å•è¯';
$labels['addtodict'] = '添加到字典中';
$labels['mailtoprotohandler'] = 'Register protocol handler for mailto: links';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = '邮件转å‘æ–¹å¼';
$labels['inline'] = '内嵌';
$labels['asattachment'] = '作为附件';
diff --git a/program/localization/zh_TW/labels.inc b/program/localization/zh_TW/labels.inc
index a545f2f81..7726da5dd 100644
--- a/program/localization/zh_TW/labels.inc
+++ b/program/localization/zh_TW/labels.inc
@@ -37,6 +37,7 @@ $labels['drafts'] = 'è‰ç¨¿åŒ£';
$labels['sent'] = '寄件備份';
$labels['trash'] = '垃圾桶';
$labels['junk'] = '垃圾郵件';
+$labels['show_real_foldernames'] = 'Show real names for special folders';
// message listing
$labels['subject'] = '主旨';
@@ -193,6 +194,7 @@ $labels['listmode'] = '清單檢視模å¼';
$labels['folderactions'] = '資料夾動作...';
$labels['compact'] = '壓縮';
$labels['empty'] = '清空';
+$labels['importmessages'] = 'Import messages';
$labels['quota'] = 'ç£ç¢Ÿä½¿ç”¨é‡';
$labels['unknown'] = '未知';
@@ -203,6 +205,7 @@ $labels['resetsearch'] = 'é‡è¨­æœå°‹';
$labels['searchmod'] = '修改æœå°‹';
$labels['msgtext'] = 'æ•´å°éƒµä»¶';
$labels['body'] = '內文';
+$labels['type'] = 'Type';
$labels['openinextwin'] = '在新視窗開啟';
$labels['emlsave'] = '下載(.eml)';
@@ -354,6 +357,7 @@ $labels['lastpage'] = '顯示最後一é ';
$labels['group'] = '群組';
$labels['groups'] = '群組';
+$labels['listgroup'] = 'List group members';
$labels['personaladrbook'] = '個人通訊錄';
$labels['searchsave'] = '儲存æœå°‹çµæžœ';
@@ -472,6 +476,7 @@ $labels['spellcheckignorenums'] = '忽略數字';
$labels['spellcheckignorecaps'] = '忽略大寫字æ¯';
$labels['addtodict'] = '加入詞典';
$labels['mailtoprotohandler'] = '註冊mailto:å”定處ç†ç¨‹å¼';
+$labels['standardwindows'] = 'Handle popups as standard windows';
$labels['forwardmode'] = '郵件轉寄方å¼';
$labels['inline'] = '放入內文';
$labels['asattachment'] = '當æˆé™„件';
diff --git a/program/steps/addressbook/copy.inc b/program/steps/addressbook/copy.inc
index 480a9b52e..d4387194a 100644
--- a/program/steps/addressbook/copy.inc
+++ b/program/steps/addressbook/copy.inc
@@ -57,10 +57,16 @@ foreach ($cids as $source => $cid)
foreach ($cid as $cid) {
$a_record = $CONTACTS->get_record($cid, true);
+ // avoid copying groups
+ if ($a_record['_type'] == 'group')
+ continue;
+
// Check if contact exists, if so, we'll need it's ID
// Note: Some addressbooks allows empty email address field
- if (!empty($a_record['email']))
- $result = $TARGET->search('email', $a_record['email'], 1, true, true);
+ // @TODO: should we check all email addresses?
+ $email = $CONTACTS->get_col_values('email', $a_record, true);
+ if (!empty($email))
+ $result = $TARGET->search('email', $email[0], 1, true, true);
else if (!empty($a_record['name']))
$result = $TARGET->search('name', $a_record['name'], 1, true, true);
else
@@ -114,7 +120,7 @@ foreach ($cids as $source => $cid)
}
}
-if ($success == 0)
+if (!$success)
$OUTPUT->show_message($errormsg, 'error');
else
$OUTPUT->show_message('copysuccess', 'notice', array('nr' => $success));
diff --git a/program/steps/addressbook/delete.inc b/program/steps/addressbook/delete.inc
index 56118583c..3bb2ef500 100644
--- a/program/steps/addressbook/delete.inc
+++ b/program/steps/addressbook/delete.inc
@@ -68,48 +68,14 @@ foreach ($cids as $source => $cid)
$page = isset($_SESSION['page']) ? $_SESSION['page'] : 1;
// update saved search after data changed
-if (($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
- $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
- $afields = $RCMAIL->config->get('contactlist_fields');
- $search = (array)$_SESSION['search'][$search_request];
- $records = array();
-
- // Get records from all sources (refresh search)
- foreach ($search as $s => $set) {
- $source = $RCMAIL->get_address_book($s);
-
- // reset page
- $source->set_page(1);
- $source->set_pagesize(9999);
- $source->set_search_set($set);
-
- // get records
- $result = $source->list_records($afields);
-
- if (!$result->count) {
- unset($search[$s]);
- continue;
- }
-
- while ($row = $result->next()) {
- $row['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($row, $sort_col);
- $records[$key] = $row;
- }
- unset($result);
-
- $search[$s] = $source->get_search_set();
- }
-
- $_SESSION['search'][$search_request] = $search;
-
+if (($records = rcmail_search_update(true)) !== false) {
// create resultset object
$count = count($records);
$first = ($page-1) * $PAGE_SIZE;
$result = new rcube_result_set($count, $first);
+ $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE);
// get records from the next page to add to the list
- $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE);
if ($_GET['_from'] != 'show' && $pages > 1 && $page < $pages) {
// sort the records
ksort($records, SORT_LOCALE_STRING);
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index 3db2409e8..8ec581f9a 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -307,7 +307,7 @@ function rcmail_contacts_list($attrib)
global $CONTACTS, $OUTPUT;
// define list of cols to be displayed
- $a_show_cols = array('name');
+ $a_show_cols = array('name','action');
// add id to message list table if not specified
if (!strlen($attrib['id']))
@@ -322,7 +322,7 @@ function rcmail_contacts_list($attrib)
$OUTPUT->include_script('list.js');
// add some labels to client
- $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'contactdeleting');
+ $OUTPUT->add_label('deletecontactconfirm', 'copyingcontact', 'movingcontact', 'contactdeleting');
return $out;
}
@@ -336,31 +336,73 @@ function rcmail_js_contacts_list($result, $prefix='')
return;
// define list of cols to be displayed
- $a_show_cols = array('name');
+ $a_show_cols = array('name','action');
while ($row = $result->next()) {
+ $row['CID'] = $row['ID'];
+ $row['email'] = reset(rcube_addressbook::get_col_values('email', $row, true));
+
+ $source_id = $OUTPUT->get_env('source');
$a_row_cols = array();
- $classes = array('person'); // org records will follow some day
+ $classes = array($row['_type'] ? $row['_type'] : 'person');
// build contact ID with source ID
if (isset($row['sourceid'])) {
$row['ID'] = $row['ID'].'-'.$row['sourceid'];
+ $source_id = $row['sourceid'];
}
// format each col
foreach ($a_show_cols as $col) {
- $val = $col == 'name' ? rcube_addressbook::compose_list_name($row) : $row[$col];
- $a_row_cols[$col] = Q($val);
+ $val = '';
+ switch ($col) {
+ case 'name':
+ $val = Q(rcube_addressbook::compose_list_name($row));
+ break;
+
+ case 'action':
+ if ($row['_type'] == 'group') {
+ $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']),
+ ), '&raquo;');
+ }
+ else
+ $val = '&nbsp;';
+ break;
+
+ default:
+ $val = Q($row[$col]);
+ break;
+ }
+
+ $a_row_cols[$col] = $val;
}
if ($row['readonly'])
$classes[] = 'readonly';
- $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes));
+ $OUTPUT->command($prefix.'add_contact_row', $row['ID'], $a_row_cols, join(' ', $classes), array_intersect_key($row, array('ID'=>1,'readonly'=>1,'_type'=>1,'email'=>1,'name'=>1)));
}
}
+function rcmail_contacts_list_title($attrib)
+{
+ global $OUTPUT;
+
+ $attrib += array('label' => 'contacts', 'id' => 'rcmabooklisttitle', 'tag' => 'span');
+ unset($attrib['name']);
+
+ $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);
+}
+
+
// similar function as /steps/settings/identities.inc::rcmail_identity_frame()
function rcmail_contact_frame($attrib)
{
@@ -429,7 +471,7 @@ function rcmail_get_type_label($type)
function rcmail_contact_form($form, $record, $attrib = null)
{
- global $RCMAIL, $CONFIG;
+ global $RCMAIL;
// Allow plugins to modify contact form content
$plugin = $RCMAIL->plugins->exec_hook('contact_form', array(
@@ -438,7 +480,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' => $CONFIG['skin_path'] . $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' => rcube_label('delete'))) : rcube_label('delete');
unset($attrib['deleteicon']);
$out = '';
@@ -695,12 +737,15 @@ function rcmail_contact_form($form, $record, $attrib = null)
function rcmail_contact_photo($attrib)
{
- global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL, $CONFIG;
+ global $SOURCE_ID, $CONTACTS, $CONTACT_COLTYPES, $RCMAIL;
if ($result = $CONTACTS->get_result())
$record = $result->first();
- $photo_img = $attrib['placeholder'] ? $CONFIG['skin_path'] . $attrib['placeholder'] : 'program/resources/blank.gif';
+ $photo_img = $attrib['placeholder'] ? $RCMAIL->output->get_skin_file($attrib['placeholder']) : 'program/resources/blank.gif';
+ if ($record['_type'] == 'group' && $attrib['placeholdergroup'])
+ $photo_img = $RCMAIL->output->get_skin_file($attrib['placeholdergroup']);
+
$RCMAIL->output->set_env('photo_placeholder', $photo_img);
unset($attrib['placeholder']);
@@ -734,6 +779,54 @@ function rcmail_format_date_col($val)
return format_date($val, $RCMAIL->config->get('date_format', 'Y-m-d'), false);
}
+/**
+ * Updates saved search after data changed
+ */
+function rcmail_search_update($return = false)
+{
+ global $RCMAIL;
+
+ if (($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
+ $search = (array)$_SESSION['search'][$search_request];
+ $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
+ $afields = $return ? $RCMAIL->config->get('contactlist_fields') : array('name', 'email');
+ $records = array();
+
+ foreach ($search as $s => $set) {
+ $source = $RCMAIL->get_address_book($s);
+
+ // reset page
+ $source->set_page(1);
+ $source->set_pagesize(9999);
+ $source->set_search_set($set);
+
+ // get records
+ $result = $source->list_records($afields);
+
+ if (!$result->count) {
+ unset($search[$s]);
+ continue;
+ }
+
+ if ($return) {
+ while ($row = $result->next()) {
+ $row['sourceid'] = $s;
+ $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $records[$key] = $row;
+ }
+ unset($result);
+ }
+
+ $search[$s] = $source->get_search_set();
+ }
+
+ $_SESSION['search'][$search_request] = $search;
+
+ return $records;
+ }
+
+ return false;
+}
/**
* Returns contact ID(s) and source(s) from GET/POST data
@@ -791,6 +884,7 @@ $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')
diff --git a/program/steps/addressbook/list.inc b/program/steps/addressbook/list.inc
index 1bb28658b..aca58d279 100644
--- a/program/steps/addressbook/list.inc
+++ b/program/steps/addressbook/list.inc
@@ -19,47 +19,20 @@
+-----------------------------------------------------------------------+
*/
-$afields = $RCMAIL->config->get('contactlist_fields');
+if (!empty($_GET['_page']))
+ $page = intval($_GET['_page']);
+else
+ $page = !empty($_SESSION['page']) ? $_SESSION['page'] : 1;
-// Use search result
-if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']]))
-{
- $search = (array)$_SESSION['search'][$_REQUEST['_search']];
- $records = array();
-
- if (!empty($_GET['_page']))
- $page = intval($_GET['_page']);
- else
- $page = isset($_SESSION['page']) ? $_SESSION['page'] : 1;
-
- $_SESSION['page'] = $page;
- $sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
-
- // Get records from all sources
- foreach ($search as $s => $set) {
- $source = $RCMAIL->get_address_book($s);
-
- // reset page
- $source->set_page(1);
- $source->set_pagesize(9999);
- $source->set_search_set($set);
-
- // get records
- $result = $source->list_records($afields);
-
- while ($row = $result->next()) {
- $row['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($row, $sort_col);
- $records[$key] = $row;
- }
- unset($result);
- }
+$_SESSION['page'] = $page;
+// Use search result
+if (($records = rcmail_search_update(true)) !== false) {
// sort the records
ksort($records, SORT_LOCALE_STRING);
// create resultset object
- $count = count($records);
+ $count = count($records);
$first = ($page-1) * $PAGE_SIZE;
$result = new rcube_result_set($count, $first);
@@ -72,6 +45,7 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
}
// List selected directory
else {
+ $afields = $RCMAIL->config->get('contactlist_fields');
$CONTACTS = rcmail_contact_source(null, true);
// get contacts for this user
@@ -81,6 +55,11 @@ else {
$OUTPUT->show_message('contactsearchonly', 'notice');
$OUTPUT->command('command', 'advanced-search');
}
+
+ if ($CONTACTS->group_id) {
+ $OUTPUT->command('set_group_prop', array('ID' => $CONTACTS->group_id)
+ + array_intersect_key((array)$CONTACTS->get_group($CONTACTS->group_id), array('name'=>1,'email'=>1)));
+ }
}
// update message count display
diff --git a/program/steps/addressbook/move.inc b/program/steps/addressbook/move.inc
new file mode 100644
index 000000000..f8204e9ee
--- /dev/null
+++ b/program/steps/addressbook/move.inc
@@ -0,0 +1,208 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/addressbook/move.inc |
+ | |
+ | This file is part of the Roundcube Webmail client |
+ | 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. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Move a contact record from one direcotry to another |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ | Author: Aleksander Machniak <alec@alec.pl> |
+ +-----------------------------------------------------------------------+
+*/
+
+// only process ajax requests
+if (!$OUTPUT->ajax_call) {
+ return;
+}
+
+$cids = rcmail_get_cids();
+$target = get_input_value('_to', RCUBE_INPUT_POST);
+$target_group = get_input_value('_togid', RCUBE_INPUT_POST);
+
+$all = 0;
+$deleted = 0;
+$success = 0;
+$errormsg = 'moveerror';
+$maxnum = $RCMAIL->config->get('max_group_members', 0);
+$page = !empty($_SESSION['page']) ? $_SESSION['page'] : 1;
+
+foreach ($cids as $source => $source_cids) {
+ // Something wrong, target not specified
+ if (!strlen($target)) {
+ break;
+ }
+
+ // It maight happen when moving records from search result
+ // Do nothing, go to next source
+ if ((string)$target === (string)$source) {
+ continue;
+ }
+
+ $CONTACTS = $RCMAIL->get_address_book($source);
+ $TARGET = $RCMAIL->get_address_book($target);
+
+ if (!$TARGET || !$TARGET->ready || $TARGET->readonly) {
+ break;
+ }
+
+ if (!$CONTACTS || !$CONTACTS->ready || $CONTACTS->readonly) {
+ continue;
+ }
+
+ $ids = array();
+
+ foreach ($source_cids as $idx => $cid) {
+ $a_record = $CONTACTS->get_record($cid, true);
+
+ // avoid moving groups
+ if ($a_record['_type'] == 'group') {
+ unset($source_cids[$idx]);
+ continue;
+ }
+
+ // Check if contact exists, if so, we'll need it's ID
+ // Note: Some addressbooks allows empty email address field
+ // @TODO: should we check all email addresses?
+ $email = $CONTACTS->get_col_values('email', $a_record, true);
+ if (!empty($email))
+ $result = $TARGET->search('email', $email[0], 1, true, true);
+ else if (!empty($a_record['name']))
+ $result = $TARGET->search('name', $a_record['name'], 1, true, true);
+ else
+ $result = new rcube_result_set();
+
+ // insert contact record
+ if (!$result->count) {
+ $plugin = $RCMAIL->plugins->exec_hook('contact_create', array(
+ 'record' => $a_record, 'source' => $target, 'group' => $target_group));
+
+ if (!$plugin['abort']) {
+ if ($insert_id = $TARGET->insert($plugin['record'], false)) {
+ $ids[] = $insert_id;
+ $success++;
+ }
+ }
+ else if ($plugin['result']) {
+ $ids = array_merge($ids, $plugin['result']);
+ $success++;
+ }
+ }
+ else {
+ $record = $result->first();
+ $ids[] = $record['ID'];
+ $errormsg = empty($a_record['email']) ? 'contactnameexists' : 'contactexists';
+ }
+ }
+
+ // remove source contacts
+ if ($success && !empty($source_cids)) {
+ $all += count($source_cids);
+ $plugin = $RCMAIL->plugins->exec_hook('contact_delete', array(
+ 'id' => $source_cids, 'source' => $source));
+
+ $del_status = !$plugin['abort'] ? $CONTACTS->delete($source_cids) : $plugin['result'];
+
+ if ($del_status) {
+ $deleted += $del_status;
+ }
+ }
+
+ // assign to group
+ if ($target_group && $TARGET->groups && !empty($ids)) {
+ $plugin = $RCMAIL->plugins->exec_hook('group_addmembers', array(
+ 'group_id' => $target_group, 'ids' => $ids, 'source' => $target));
+
+ if (!$plugin['abort']) {
+ $TARGET->reset();
+ $TARGET->set_group($target_group);
+
+ if ($maxnum && ($TARGET->count()->count + count($plugin['ids']) > $maxnum)) {
+ $OUTPUT->show_message('maxgroupmembersreached', 'warning', array('max' => $maxnum));
+ $OUTPUT->send();
+ }
+
+ if (($cnt = $TARGET->add_to_group($target_group, $plugin['ids'])) && $cnt > $success)
+ $success = $cnt;
+ }
+ else if ($plugin['result']) {
+ $success = $plugin['result'];
+ }
+
+ $errormsg = $plugin['message'] ? $plugin['message'] : 'moveerror';
+ }
+}
+
+if (!$deleted || $deleted != $all) {
+ // update saved search after data changed
+ if ($deleted) {
+ rcmail_search_update();
+ }
+ $OUTPUT->command('list_contacts');
+}
+else {
+ // update saved search after data changed
+ if (($records = rcmail_search_update(true)) !== false) {
+ // create resultset object
+ $count = count($records);
+ $first = ($page-1) * $PAGE_SIZE;
+ $result = new rcube_result_set($count, $first);
+ $pages = ceil((count($records) + $delcnt) / $PAGE_SIZE);
+
+ // get records from the next page to add to the list
+ if ($_GET['_from'] != 'show' && $pages > 1 && $page < $pages) {
+ // sort the records
+ ksort($records, SORT_LOCALE_STRING);
+
+ $first += $PAGE_SIZE;
+ // create resultset object
+ $res = new rcube_result_set($count, $first - $deleted);
+
+ if ($PAGE_SIZE < $count) {
+ $records = array_slice($records, $first - $deleted, $deleted);
+ }
+
+ $res->records = array_values($records);
+ $records = $res;
+ }
+ else {
+ unset($records);
+ }
+ }
+ else {
+ // count contacts for this user
+ $result = $CONTACTS->count();
+ // get records from the next page to add to the list
+ $pages = ceil(($result->count + $deleted) / $PAGE_SIZE);
+
+ if ($_GET['_from'] != 'show' && $pages > 1 && $page < $pages) {
+ $CONTACTS->set_page($page);
+ $records = $CONTACTS->list_records(null, -$deleted);
+ }
+ }
+
+ // update message count display
+ $OUTPUT->set_env('pagecount', ceil($result->count / $PAGE_SIZE));
+ $OUTPUT->command('set_rowcount', rcmail_get_rowcount_text($result));
+
+ // add new rows from next page (if any)
+ if (!empty($records)) {
+ rcmail_js_contacts_list($records);
+ }
+}
+
+if (!$success)
+ $OUTPUT->show_message($errormsg, 'error');
+else
+ $OUTPUT->show_message('movesuccess', 'notice', array('nr' => $success));
+
+// send response
+$OUTPUT->send();
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 25bfbd48b..e7e5efc63 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -134,11 +134,11 @@ if (!empty($cid))
$record['email'] = reset($CONTACTS->get_col_values('email', $record, true));
$record['name'] = rcube_addressbook::compose_list_name($record);
- foreach (array('name', 'email') as $col)
+ 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);
+ $OUTPUT->command('parent.update_contact_row', $cid, $a_js_cols, $newcid, $source, $record);
// show confirmation
$OUTPUT->show_message('successfullysaved', 'confirmation', null, false);
diff --git a/program/steps/addressbook/show.inc b/program/steps/addressbook/show.inc
index 1a97c65b1..950764bb1 100644
--- a/program/steps/addressbook/show.inc
+++ b/program/steps/addressbook/show.inc
@@ -207,9 +207,8 @@ function rcmail_contact_record_groups($contact_id)
return '';
}
- $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0));
-
- $members = $CONTACTS->get_record_groups($contact_id);
+ $members = $CONTACTS->get_record_groups($contact_id);
+ $table = new html_table(array('cols' => 2, 'cellspacing' => 0, 'border' => 0));
$checkbox = new html_checkbox(array('name' => '_gid[]',
'class' => 'groupmember', 'disabled' => $CONTACTS->readonly));
diff --git a/program/steps/addressbook/undo.inc b/program/steps/addressbook/undo.inc
index 9c171143c..c23bd1cb6 100644
--- a/program/steps/addressbook/undo.inc
+++ b/program/steps/addressbook/undo.inc
@@ -46,30 +46,7 @@ foreach ((array)$undo['data'] as $source => $cid)
}
// update saved search after data changed
-if ($delcnt && ($search_request = $_REQUEST['_search']) && isset($_SESSION['search'][$search_request])) {
- $search = (array)$_SESSION['search'][$search_request];
-
- foreach ($search as $s => $set) {
- $source = $RCMAIL->get_address_book($s);
-
- // reset page
- $source->set_page(1);
- $source->set_pagesize(9999);
- $source->set_search_set($set);
-
- // get records
- $result = $source->list_records(array('name', 'email'));
-
- if (!$result->count) {
- unset($search[$s]);
- continue;
- }
-
- $search[$s] = $source->get_search_set();
- }
-
- $_SESSION['search'][$search_request] = $search;
-}
+rcmail_search_update();
$RCMAIL->session->remove('contact_undo');
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index d3bc7fe72..9ffde8a57 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -170,6 +170,9 @@ $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);
}
else if ($config_show_sig == 1)
$OUTPUT->set_env('show_sig', true);
@@ -219,8 +222,8 @@ if (!empty($msg_uid) && empty($COMPOSE['as_attachment']))
$COMPOSE['param']['sent_mbox'] = $sent_folder;
}
}
- else if ($compose_mode == RCUBE_COMPOSE_DRAFT) {
- if ($draft_info = $MESSAGE->headers->get('x-draft-info')) {
+ 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);
@@ -242,7 +245,7 @@ if (!empty($msg_uid) && empty($COMPOSE['as_attachment']))
if ($in_reply_to = $MESSAGE->headers->get('in-reply-to'))
$COMPOSE['reply_msgid'] = '<' . $in_reply_to . '>';
- $COMPOSE['references'] = $MESSAGE->headers->references;
+ $COMPOSE['references'] = $MESSAGE->headers->references;
}
}
else {
@@ -523,7 +526,7 @@ function rcmail_compose_header_from($attrib)
}
}
- $out = $select_from->show($MESSAGE->compose['from']);
+ $out = $select_from->show((int)$MESSAGE->compose['from']);
// add signatures to client
$OUTPUT->set_env('signatures', $a_signatures);
@@ -596,15 +599,32 @@ function rcmail_prepare_message_body()
}
// 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();
+ $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;
+ }
+ }
+
if ($part_body = rcmail_compose_part_body($part, $isHtml)) {
$body .= ($body ? ($isHtml ? '<br/>' : "\n") : '') . $part_body;
}
@@ -1021,7 +1041,9 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
$loaded_attachments[$attachment['name'] . $attachment['mimetype']] = $attachment;
}
- $cid_map = $messages = array();
+ $cid_map = array();
+ $messages = array();
+
foreach ((array)$message->mime_parts as $pid => $part)
{
if ($part->disposition == 'attachment' || ($part->disposition == 'inline' && $bodyIsHtml) || $part->filename) {
@@ -1033,25 +1055,32 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml)
if ($part->ctype_primary == 'message' && $compose_mode == RCUBE_COMPOSE_REPLY) {
continue;
}
- // skip inline images when forwarding
- if ($part->content_id && $part->disposition == 'inline' && $compose_mode == RCUBE_COMPOSE_FORWARD) {
+ // skip inline images when forwarding in text mode
+ if ($part->content_id && $part->disposition == 'inline' && !$bodyIsHtml && $compose_mode == RCUBE_COMPOSE_FORWARD) {
continue;
}
- $skip = false;
+ // 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 ($messages) {
+ }
+ 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) {
- $skip = true;
- break;
+ if (strpos($part->mime_id, $mimeid . '.') === 0) {
+ continue 2;
}
}
- if (!$skip && (($attachment = $loaded_attachments[rcmail_attachment_name($part) . $part->mimetype])
- || ($attachment = rcmail_save_attachment($message, $pid)))) {
+ 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',
diff --git a/program/steps/mail/func.inc b/program/steps/mail/func.inc
index 1a687f508..454650628 100644
--- a/program/steps/mail/func.inc
+++ b/program/steps/mail/func.inc
@@ -120,7 +120,7 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
if (!$OUTPUT->ajax_call)
$OUTPUT->add_label('checkingmail', 'deletemessage', 'movemessagetotrash',
'movingmessage', 'copyingmessage', 'deletingmessage', 'markingmessage',
- 'copy', 'move', 'quota', 'replyall', 'replylist');
+ 'copy', 'move', 'quota', 'replyall', 'replylist', 'importwait');
$pagetitle = $RCMAIL->localize_foldername($RCMAIL->storage->mod_folder($mbox_name), true);
$pagetitle = str_replace($delimiter, " \xC2\xBB ", $pagetitle);
@@ -128,6 +128,40 @@ if (empty($RCMAIL->action) || $RCMAIL->action == 'list') {
$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'),
+));
+
+// register action aliases
+$RCMAIL->register_action_map(array(
+ 'refresh' => 'check_recent.inc',
+ 'preview' => 'show.inc',
+ 'print' => 'show.inc',
+ 'move' => 'move_del.inc',
+ 'delete' => 'move_del.inc',
+ 'send' => 'sendmail.inc',
+ 'expunge' => 'folders.inc',
+ 'purge' => 'folders.inc',
+ 'remove-attachment' => 'attachments.inc',
+ 'display-attachment' => 'attachments.inc',
+ 'upload' => 'attachments.inc',
+ 'group-expand' => 'autocomplete.inc',
+));
+
+
+
/**
* Returns 'to' if current folder is configured Sent or Drafts
* or their subfolders, otherwise returns 'from'.
@@ -900,7 +934,7 @@ function rcmail_message_headers($attrib, $headers=null)
$value = $headers[$hkey];
else if ($headers['others'][$hkey])
$value = $headers['others'][$hkey];
- else
+ else if (!$attrib['valueof'])
continue;
if (in_array($hkey, $exclude_headers))
@@ -1579,45 +1613,6 @@ function rcmail_draftinfo_decode($str)
}
-function rcmail_message_part_controls($attrib)
-{
- global $MESSAGE, $RCMAIL;
-
- $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC));
- if (!is_object($MESSAGE) || !is_array($MESSAGE->parts) || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part])
- return '';
-
- $part = $MESSAGE->mime_parts[$part];
- $table = new html_table(array('cols' => 3));
-
- $filename = rcmail_attachment_name($part);
-
- if (!empty($filename)) {
- $table->add('title', Q(rcube_label('filename')));
- $table->add('header', Q($filename));
- $table->add('download-link', html::a(array('href' => './?'.str_replace('_frame=', '_download=', $_SERVER['QUERY_STRING'])), Q(rcube_label('download'))));
- }
-
- $table->add('title', Q(rcube_label('filesize')));
- $table->add('header', Q($RCMAIL->message_part_size($part)));
-
- return $table->show($attrib);
-}
-
-
-function rcmail_message_part_frame($attrib)
-{
- global $MESSAGE;
-
- $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))];
- $ctype_primary = strtolower($part->ctype_primary);
-
- $attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary=='text' ? '_embed=' : '_preload='), $_SERVER['QUERY_STRING']);
-
- return html::iframe($attrib);
-}
-
-
/**
* clear message composing settings
*/
@@ -1922,35 +1917,37 @@ function rcmail_message_error($uid=null)
$RCMAIL->output->send('messageerror');
}
-// 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',
- 'messagepartframe' => 'rcmail_message_part_frame',
- 'messagepartcontrols' => 'rcmail_message_part_controls',
- 'searchfilter' => 'rcmail_search_filter',
- 'searchform' => array($OUTPUT, 'search_form'),
-));
+function rcmail_message_import_form($attrib = array())
+{
+ global $OUTPUT;
-// register action aliases
-$RCMAIL->register_action_map(array(
- 'refresh' => 'check_recent.inc',
- 'preview' => 'show.inc',
- 'print' => 'show.inc',
- 'moveto' => 'move_del.inc',
- 'delete' => 'move_del.inc',
- 'send' => 'sendmail.inc',
- 'expunge' => 'folders.inc',
- 'purge' => 'folders.inc',
- 'remove-attachment' => 'attachments.inc',
- 'display-attachment' => 'attachments.inc',
- 'upload' => 'attachments.inc',
- 'group-expand' => 'autocomplete.inc',
-));
+ // 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[]',
+ 'size' => $attrib['attachmentfieldsize'],
+ '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;
+}
diff --git a/program/steps/mail/get.inc b/program/steps/mail/get.inc
index 372757720..a27e788a3 100644
--- a/program/steps/mail/get.inc
+++ b/program/steps/mail/get.inc
@@ -38,19 +38,34 @@ 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(get_input_value('_uid', RCUBE_INPUT_GET));
+ $MESSAGE = new rcube_message($uid);
}
// check connection status
check_storage_status();
+$part_id = get_input_value('_part', RCUBE_INPUT_GPC);
+
// show part page
if (!empty($_GET['_frame'])) {
- if (($part_id = get_input_value('_part', RCUBE_INPUT_GPC)) && ($part = $MESSAGE->mime_parts[$part_id])) {
- $OUTPUT->set_pagetitle(rcmail_attachment_name($part));
+ 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;
}
@@ -92,9 +107,8 @@ else if ($_GET['_thumb']) {
exit;
}
-else if (strlen($pid = get_input_value('_part', RCUBE_INPUT_GET))) {
-
- if ($part = $MESSAGE->mime_parts[$pid]) {
+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
@@ -378,7 +392,9 @@ else {
header('HTTP/1.1 404 Not Found');
exit;
-
+/**
+ * Handles nicely storage connection errors
+ */
function check_storage_status()
{
$error = rcmail::get_instance()->storage->get_error_code();
@@ -410,3 +426,49 @@ function check_storage_status()
exit;
}
}
+
+/**
+ * Attachment properties table
+ */
+function rcmail_message_part_controls($attrib)
+{
+ global $MESSAGE, $RCMAIL;
+
+ $part = asciiwords(get_input_value('_part', RCUBE_INPUT_GPC));
+ if (!is_object($MESSAGE) || !is_array($MESSAGE->parts)
+ || !($_GET['_uid'] && $_GET['_part']) || !$MESSAGE->mime_parts[$part]
+ ) {
+ return '';
+ }
+
+ $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', Q(rcube_label('type')).':');
+ $table->add('header', Q($part->mimetype));
+
+ $table->add('title', Q(rcube_label('size')).':');
+ $table->add('header', Q($RCMAIL->message_part_size($part)));
+
+ return $table->show($attrib);
+}
+
+/**
+ * Attachment preview frame
+ */
+function rcmail_message_part_frame($attrib)
+{
+ global $MESSAGE, $RCMAIL;
+
+ $part = $MESSAGE->mime_parts[asciiwords(get_input_value('_part', RCUBE_INPUT_GPC))];
+ $ctype_primary = strtolower($part->ctype_primary);
+
+ $attrib['src'] = './?' . str_replace('_frame=', ($ctype_primary=='text' ? '_embed=' : '_preload='), $_SERVER['QUERY_STRING']);
+
+ $RCMAIL->output->add_gui_object('messagepartframe', $attrib['id']);
+
+ return html::iframe($attrib);
+}
diff --git a/program/steps/mail/import.inc b/program/steps/mail/import.inc
new file mode 100644
index 000000000..f7e7a3eb8
--- /dev/null
+++ b/program/steps/mail/import.inc
@@ -0,0 +1,105 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/steps/mail/import.inc |
+ | |
+ | 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: |
+ | Save the uploaded file(s) as messages to the current IMAP folder |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+// clear all stored output properties (like scripts and env vars)
+$OUTPUT->reset();
+
+if (is_array($_FILES['_file'])) {
+ $imported = 0;
+
+ foreach ((array)$_FILES['_file']['tmp_name'] as $i => $filepath) {
+ // Process uploaded file if there is no error
+ $err = $_FILES['_file']['error'][$i];
+
+ if (!$err) {
+ // check file content type first
+ list($mtype_primary,) = explode('/', rc_mime_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;
+ }
+
+ // read the first few lines to detect header-like structure
+ $fp = fopen($filepath, 'r');
+ do { $line = fgets($fp); }
+ while ($line !== false && trim($line) == '');
+
+ if (!preg_match('/^From\s+-/', $line) && !preg_match('/^[a-z-_]+:\s+.+/i', $line)) {
+ $OUTPUT->show_message('importmessageerror', 'error');
+ continue;
+ }
+
+ $message = $lastline = '';
+ fseek($fp, 0);
+ while (($line = fgets($fp)) !== false) {
+ // importing mbox file, split by From - lines
+ if (preg_match('/^From\s+-/', $line) && $lastline == '') {
+ if (!empty($message)) {
+ if ($RCMAIL->storage->save_message(null, rtrim($message))) {
+ $imported++;
+ }
+ else {
+ rcube::raise_error("Failed to import message to " . $RCMAIL->storage->get_folder(), false, true);
+ }
+ $message = '';
+ }
+ continue;
+ }
+
+ $message .= $line;
+ $lastline = rtrim($line);
+ }
+
+ if (!empty($message) && $RCMAIL->storage->save_message(null, rtrim($message))) {
+ $imported++;
+ }
+ }
+
+ 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 ($err) {
+ $OUTPUT->show_message('fileuploaderror', 'error');
+ }
+ } // end foreach
+
+ if ($imported) {
+ $OUTPUT->show_message(rcube_label(array('name' => 'importmessagesuccess', 'nr' => $imported, 'vars' => array('nr' => $imported))), 'confirmation');
+ $OUTPUT->command('command', 'list');
+ }
+ else {
+ $OUTPUT->show_message('importmessageerror', 'error');
+ }
+}
+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');
+}
+
+// send html page with JS calls as response
+$OUTPUT->send('iframe');
+
diff --git a/program/steps/mail/list_contacts.inc b/program/steps/mail/list_contacts.inc
index 7e3b349cd..dab146431 100644
--- a/program/steps/mail/list_contacts.inc
+++ b/program/steps/mail/list_contacts.inc
@@ -19,10 +19,10 @@
+-----------------------------------------------------------------------+
*/
-$afields = $RCMAIL->config->get('contactlist_fields');
-$sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
-$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
-$page = max(1, intval($_GET['_page']));
+$afields = $RCMAIL->config->get('contactlist_fields');
+$addr_sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
+$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
+$list_page = max(1, intval($_GET['_page']));
// Use search result
if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search']])) {
@@ -42,7 +42,7 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
while ($row = $result->next()) {
$row['sourceid'] = $s;
- $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $key = rcube_addressbook::compose_contact_key($row, $addr_sort_col);
$records[$key] = $row;
}
unset($result);
@@ -53,7 +53,7 @@ if (!empty($_REQUEST['_search']) && isset($_SESSION['search'][$_REQUEST['_search
// create resultset object
$count = count($records);
- $first = ($page-1) * $page_size;
+ $first = ($list_page-1) * $page_size;
$result = new rcube_result_set($count, $first);
// we need only records for current page
@@ -71,10 +71,13 @@ else {
if ($CONTACTS && $CONTACTS->ready) {
// set list properties
$CONTACTS->set_pagesize($page_size);
- $CONTACTS->set_page($page);
+ $CONTACTS->set_page($list_page);
+ if ($group_id = get_input_value('_gid', RCUBE_INPUT_GPC)) {
+ $CONTACTS->set_group($group_id);
+ }
// list groups of this source (on page one)
- if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
+ else if ($CONTACTS->groups && $CONTACTS->list_page == 1) {
foreach ($CONTACTS->list_groups() as $group) {
$CONTACTS->reset();
$CONTACTS->set_group($group['ID']);
@@ -89,6 +92,19 @@ else {
'contactgroup' => html::span(array('title' => $email), Q($group['name']))), 'group');
}
}
+ // make virtual groups clickable to list their members
+ else if ($group_prop['virtual']) {
+ $row_id = 'G'.$group['ID'];
+ $OUTPUT->command('add_contact_row', $row_id, array(
+ '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']) . '&nbsp;' . html::span('action', '&raquo;'))),
+ 'group',
+ array('ID' => $group['ID'], 'name' => $group['name'], 'virtual' => true));
+ }
// show group with count
else if (($result = $CONTACTS->count()) && $result->count) {
$row_id = 'E'.$group['ID'];
@@ -97,10 +113,12 @@ else {
'contactgroup' => Q($group['name'] . ' (' . intval($result->count) . ')')), 'group');
}
}
+
+ $CONTACTS->reset();
+ $CONTACTS->set_group(0);
}
// get contacts for this user
- $CONTACTS->set_group(0);
$result = $CONTACTS->list_records($afields);
}
}
@@ -118,10 +136,13 @@ else if (!empty($result) && $result->count > 0) {
foreach ($emails as $i => $email) {
$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(
- 'contact' => html::span(array('title' => $email), Q($name ? $name : $email) .
+ $keyname => html::span(array('title' => $email), Q($name ? $name : $email) .
($name && count($emails) > 1 ? '&nbsp;' . html::span('email', Q($email)) : '')
- )), 'person');
+ )), $classname);
}
}
}
diff --git a/program/steps/mail/move_del.inc b/program/steps/mail/move_del.inc
index e21ba2c6b..f15cd2460 100644
--- a/program/steps/mail/move_del.inc
+++ b/program/steps/mail/move_del.inc
@@ -29,7 +29,7 @@ $old_count = $RCMAIL->storage->count(NULL, $threading ? 'THREADS' : 'ALL');
$old_pages = ceil($old_count / $RCMAIL->storage->get_pagesize());
// move messages
-if ($RCMAIL->action == 'moveto' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
+if ($RCMAIL->action == 'move' && !empty($_POST['_uid']) && strlen($_POST['_target_mbox'])) {
$count = sizeof(explode(',', ($uids = get_input_value('_uid', RCUBE_INPUT_POST))));
$target = get_input_value('_target_mbox', RCUBE_INPUT_POST, true);
$mbox = get_input_value('_mbox', RCUBE_INPUT_POST, true);
@@ -126,7 +126,7 @@ else
rcmail_set_unseen_count($mbox, $unseen_count);
}
- if ($RCMAIL->action == 'moveto' && strlen($target)) {
+ if ($RCMAIL->action == 'move' && strlen($target)) {
rcmail_send_unread_count($target, true);
}
diff --git a/program/steps/mail/search_contacts.inc b/program/steps/mail/search_contacts.inc
index 2e6bb12f8..6a30ad1f5 100644
--- a/program/steps/mail/search_contacts.inc
+++ b/program/steps/mail/search_contacts.inc
@@ -19,16 +19,15 @@
+-----------------------------------------------------------------------+
*/
-$search = get_input_value('_q', RCUBE_INPUT_GPC, true);
-$sources = $RCMAIL->get_address_sources();
-$search_mode = (int) $RCMAIL->config->get('addressbook_search_mode');
-$sort_col = $RCMAIL->config->get('addressbook_sort_col', 'name');
-$afields = $RCMAIL->config->get('contactlist_fields');
+$search = get_input_value('_q', RCUBE_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');
+$afields = $RCMAIL->config->get('contactlist_fields');
+$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
+$records = array();
+$search_set = array();
-$page = 1;
-$page_size = $RCMAIL->config->get('addressbook_pagesize', $RCMAIL->config->get('pagesize', 50));
-
-$records = $search_set = array();
foreach ($sources as $s) {
$source = $RCMAIL->get_address_book($s['id']);
$source->set_page(1);
@@ -46,7 +45,7 @@ foreach ($sources as $s) {
while ($row = $result->next()) {
$row['sourceid'] = $s['id'];
- $key = rcube_addressbook::compose_contact_key($row, $sort_col);
+ $key = rcube_addressbook::compose_contact_key($row, $addr_sort_col);
$records[$key] = $row;
}
diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc
index 34a72dd95..6d116e7d2 100644
--- a/program/steps/settings/folders.inc
+++ b/program/steps/settings/folders.inc
@@ -232,16 +232,16 @@ function rcube_subscription_form($attrib)
// add any necessary "virtual" parent folders
if ($parent_folder && !isset($seen[$parent_folder])) {
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');
- $list_folders[] = array(
+ $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');
+ $list_folders[] = array(
'id' => $ancestor_folder,
'name' => $ancestor_name,
'level' => $i-1,
'virtual' => true,
);
- }
+ }
}
}
@@ -291,7 +291,8 @@ function rcube_subscription_form($attrib)
$classes[] = 'virtual';
}
- if (!$protected) {
+ // Check \Noselect flag (of existing folder)
+ if (!$protected && in_array($folder['id'], $a_unsubscribed)) {
$attrs = $STORAGE->folder_attributes($folder['id']);
$noselect = in_array('\\Noselect', $attrs);
}
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index 3ee098ca8..dbc9b3ce2 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -1170,7 +1170,7 @@ function rcmail_user_prefs($current = null)
function rcmail_get_skins()
{
- $path = 'skins';
+ $path = RCUBE_INSTALL_PATH . 'skins';
$skins = array();
$dir = opendir($path);
diff --git a/skins/classic/addressbook.css b/skins/classic/addressbook.css
index 5afa4592f..415142e0c 100644
--- a/skins/classic/addressbook.css
+++ b/skins/classic/addressbook.css
@@ -224,6 +224,37 @@
-o-text-overflow: ellipsis;
}
+#contacts-table .contact.readonly td
+{
+ font-style: italic;
+}
+
+#contacts-table td.name
+{
+ width: 95%;
+}
+
+#contacts-table td.action
+{
+ width: 12px;
+ padding: 0px 6px 0 4px;
+ text-align: right;
+}
+
+#contacts-table td.action a
+{
+ font-size: 16px;
+ font-weight: bold;
+ font-style: normal;
+ text-decoration: none;
+ color: #333;
+}
+
+#contacts-table .selected td.action a
+{
+ color: #fff;
+}
+
#contacts-box
{
position: absolute;
diff --git a/skins/classic/common.css b/skins/classic/common.css
index 1f62fbe07..3c322f0ed 100644
--- a/skins/classic/common.css
+++ b/skins/classic/common.css
@@ -283,6 +283,15 @@ body > #message a
text-decoration: underline;
}
+body.extwin #closelink
+{
+ position: absolute;
+ top: 5px;
+ right: 20px;
+ text-align: right;
+ z-index:100;
+}
+
.box
{
border: 1px solid #999;
diff --git a/skins/classic/functions.js b/skins/classic/functions.js
index 5dd332ab7..af561c37b 100644
--- a/skins/classic/functions.js
+++ b/skins/classic/functions.js
@@ -94,7 +94,7 @@ function rcube_mail_ui()
messagemenu: {id:'messagemenu'},
attachmentmenu: {id:'attachmentmenu'},
listmenu: {id:'listmenu', editable:1},
- dragmessagemenu:{id:'dragmessagemenu', sticky:1},
+ dragmenu: {id:'dragmenu', sticky:1},
groupmenu: {id:'groupoptionsmenu', above:1},
mailboxmenu: {id:'mailboxoptionsmenu', above:1},
composemenu: {id:'composeoptionsmenu', editable:1, overlap:1},
@@ -162,9 +162,9 @@ show_popupmenu: function(popup, show)
}
},
-dragmessagemenu: function(show)
+dragmenu: function(show)
{
- this.popups.dragmessagemenu.obj[show?'show':'hide']();
+ this.popups.dragmenu.obj[show?'show':'hide']();
},
forwardmenu: function(show)
@@ -796,24 +796,25 @@ function iframe_events()
// Abbreviate mailbox names to fit width of the container
function rcube_render_mailboxlist()
{
- var list = $('#mailboxlist > li a, #mailboxlist ul:visible > li a');
+ var list = $('#mailboxlist > li > a, #mailboxlist ul:visible > li > a');
// it's too slow with really big number of folders, especially on IE
- if (list.length > (bw.ie ? 25 : 100))
+ if (list.length > (bw.ie && bw.vendver < 9 ? 40 : 100))
return;
- list.each(function(){
+ list.each(function() {
var elem = $(this),
text = elem.data('text');
if (!text) {
- text = elem.text().replace(/\s+\(.+$/, '');
+ text = elem.text().replace(/\s+\([0-9]+\)$/, '');
elem.data('text', text);
}
+
if (text.length < 6)
return;
- var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width());
+ var abbrev = fit_string_to_size(text, elem, elem.width() - elem.children('span.unreadcount').width() - 16);
if (abbrev != text)
elem.attr('title', text);
elem.contents().filter(function(){ return (this.nodeType == 3); }).get(0).data = abbrev;
@@ -823,19 +824,23 @@ function rcube_render_mailboxlist()
// inspired by https://gist.github.com/24261/7fdb113f1e26111bd78c0c6fe515f6c0bf418af5
function fit_string_to_size(str, elem, len)
{
- var w, span, result = str, ellip = '...';
+ var w, span, $span, result = str, ellip = '...';
if (!rcmail.env.tmp_span) {
// it should be appended to elem to use the same css style
// but for performance reasons we'll append it to body (once)
- span = $('<b>').css({visibility: 'hidden', padding: '0px'})
+ span = $('<b>').css({visibility: 'hidden', padding: '0px',
+ 'font-family': elem.css('font-family'),
+ 'font-size': elem.css('font-size')})
.appendTo($('body', document)).get(0);
rcmail.env.tmp_span = span;
}
else {
span = rcmail.env.tmp_span;
}
- span.innerHTML = result;
+
+ $span = $(span);
+ $span.text(result);
// on first run, check if string fits into the length already.
w = span.offsetWidth;
@@ -848,7 +853,7 @@ function fit_string_to_size(str, elem, len)
while (true) {
offLeft = mid - cut;
offRight = mid + cut;
- span.innerHTML = str.substring(0,offLeft) + ellip + str.substring(offRight);
+ $span.text(str.substring(0,offLeft) + ellip + str.substring(offRight));
// break loop if string fits size
if (offLeft < 3 || span.offsetWidth)
@@ -935,8 +940,8 @@ function percent_indicator(obj, data)
// Optional parameters used by TinyMCE
var rcmail_editor_settings = {
- skin : "default", // "default", "o2k7"
- skin_variant : "" // "", "silver", "black"
+ skin: "default", // "default", "o2k7"
+ skin_variant: "" // "", "silver", "black"
};
var rcmail_ui;
@@ -947,46 +952,52 @@ function rcube_init_mail_ui()
rcube_event.add_listener({ object:rcmail_ui, method:'body_mouseup', event:'mouseup' });
rcube_event.add_listener({ object:rcmail_ui, method:'body_keydown', event:'keydown' });
- if (rcmail.env.quota_content)
- update_quota(rcmail.env.quota_content);
- rcmail.addEventListener('setquota', update_quota);
-
- $('iframe').load(iframe_events)
- .contents().mouseup(function(e){rcmail_ui.body_mouseup(e)});
-
- if (rcmail.env.task == 'mail') {
- rcmail.addEventListener('enable-command', 'enable_command', rcmail_ui);
- rcmail.addEventListener('menu-open', 'menu_open', rcmail_ui);
- rcmail.addEventListener('menu-save', 'menu_save', rcmail_ui);
- rcmail.addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui);
- rcmail.addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui);
- rcmail.gui_object('message_dragmenu', 'dragmessagemenu');
-
- if (rcmail.gui_objects.mailboxlist) {
- rcmail.addEventListener('responseaftermark', rcube_render_mailboxlist);
- rcmail.addEventListener('responseaftergetunread', rcube_render_mailboxlist);
- rcmail.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist);
- rcmail.addEventListener('aftercollapse-folder', rcube_render_mailboxlist);
+ rcmail.addEventListener('init', function() {
+ if (rcmail.env.quota_content)
+ update_quota(rcmail.env.quota_content);
+ rcmail.addEventListener('setquota', update_quota);
+
+ $('iframe').load(iframe_events)
+ .contents().mouseup(function(e){rcmail_ui.body_mouseup(e)});
+
+ if (rcmail.env.task == 'mail') {
+ rcmail.addEventListener('enable-command', 'enable_command', rcmail_ui);
+ rcmail.addEventListener('menu-open', 'menu_open', rcmail_ui);
+ rcmail.addEventListener('menu-save', 'menu_save', rcmail_ui);
+ rcmail.addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui);
+ rcmail.addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui);
+ rcmail.gui_object('dragmenu', 'dragmenu');
+
+ if (rcmail.gui_objects.mailboxlist) {
+ rcmail.treelist.addEventListener('expand', rcube_render_mailboxlist);
+ rcmail.addEventListener('responseaftermark', rcube_render_mailboxlist);
+ rcmail.addEventListener('responseaftergetunread', rcube_render_mailboxlist);
+ rcmail.addEventListener('responseaftercheck-recent', rcube_render_mailboxlist);
+ rcmail.addEventListener('responseafterrefresh', rcube_render_mailboxlist);
+ rcmail.addEventListener('afterimport-messages', function(){ rcmail_ui.show_popup('uploadform', false); });
+
+ new rcmail_scroller('#mailboxlist-content', '#mailboxlist-title', '#mailboxlist-footer');
+ }
- new rcmail_scroller('#mailboxlist-content', '#mailboxlist-title', '#mailboxlist-footer');
+ if (rcmail.env.action == 'compose')
+ rcmail_ui.init_compose_form();
+ else if (rcmail.env.action == 'show' || rcmail.env.action == 'preview')
+ // add menu link for each attachment
+ $('#attachment-list > li[id^="attach"]').each(function() {
+ $(this).append($('<a class="drop">').click(function() { rcmail_ui.show_attachmentmenu(this); }));
+ });
}
+ else if (rcmail.env.task == 'addressbook') {
+ rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); });
- if (rcmail.env.action == 'compose')
- rcmail_ui.init_compose_form();
- else if (rcmail.env.action == 'show' || rcmail.env.action == 'preview')
- // add menu link for each attachment
- $('#attachment-list > li[id^="attach"]').each(function() {
- $(this).append($('<a class="drop">').click(function() { rcmail_ui.show_attachmentmenu(this); }));
- });
- }
- else if (rcmail.env.task == 'addressbook') {
- rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); });
+ if (rcmail.gui_objects.folderlist)
+ new rcmail_scroller('#directorylist-content', '#directorylist-title', '#directorylist-footer');
- if (rcmail.gui_objects.folderlist)
- new rcmail_scroller('#directorylist-content', '#directorylist-title', '#directorylist-footer');
- }
- else if (rcmail.env.task == 'settings') {
- if (rcmail.gui_objects.subscriptionlist)
- new rcmail_scroller('#folderlist-content', '#folderlist-title', '#folderlist-footer');
- }
+ rcmail.gui_object('dragmenu', 'dragmenu');
+ }
+ else if (rcmail.env.task == 'settings') {
+ if (rcmail.gui_objects.subscriptionlist)
+ new rcmail_scroller('#folderlist-content', '#folderlist-title', '#folderlist-footer');
+ }
+ });
}
diff --git a/skins/classic/images/contactgroup.png b/skins/classic/images/contactgroup.png
new file mode 100644
index 000000000..c46383255
--- /dev/null
+++ b/skins/classic/images/contactgroup.png
Binary files differ
diff --git a/skins/classic/images/mail_toolbar.png b/skins/classic/images/mail_toolbar.png
index e68035da5..4a8431715 100644
--- a/skins/classic/images/mail_toolbar.png
+++ b/skins/classic/images/mail_toolbar.png
Binary files differ
diff --git a/skins/classic/includes/messagetoolbar.html b/skins/classic/includes/messagetoolbar.html
index bd14f490f..8f8efd291 100644
--- a/skins/classic/includes/messagetoolbar.html
+++ b/skins/classic/includes/messagetoolbar.html
@@ -21,7 +21,7 @@
<roundcube:button name="markmenulink" id="markmenulink" type="link" class="button markmessage" title="markmessages" onclick="rcmail_ui.show_popup('markmenu');return false" content=" " />
<roundcube:button name="messagemenulink" id="messagemenulink" type="link" class="button messagemenu" title="moreactions" onclick="rcmail_ui.show_popup('messagemenu');return false" content=" " />
<roundcube:if condition="template:name == 'message'" />
-<roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mboxlist" folder_filter="mail" />
+<roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('move', this.options[this.selectedIndex].value)" class="mboxlist" folder_filter="mail" />
<roundcube:endif />
</div>
diff --git a/skins/classic/mail.css b/skins/classic/mail.css
index 7c350ca3d..b8cc9f351 100644
--- a/skins/classic/mail.css
+++ b/skins/classic/mail.css
@@ -107,6 +107,14 @@
background-position: -192px -32px;
}
+#messagetoolbar a.print {
+ background-position: -224px 0;
+}
+
+#messagetoolbar a.printSel {
+ background-position: -224px -32px;
+}
+
#messagetoolbar a.markmessage {
background-position: -256px 0;
}
@@ -155,6 +163,14 @@
background-position: -416px -32px;
}
+#messagetoolbar a.download {
+ background-position: -480px 0;
+}
+
+#messagetoolbar a.downloadSel {
+ background-position: -480px -32px;
+}
+
#messagetoolbar select.mboxlist
{
position: relative;
@@ -284,10 +300,38 @@
#messagepartcontainer
{
position: absolute;
- top: 80px;
- left: 20px;
- right: 20px;
- bottom: 20px;
+ top: 0;
+ left: 170px;
+ right: 0;
+ bottom: 0;
+}
+
+#messagepartheader
+{
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ width: 160px;
+ border: 1px solid #999999;
+ background-color: #F9F9F9;
+ overflow: hidden;
+}
+
+#messagepartheader table
+{
+ width: 100%;
+ table-layout: fixed;
+}
+
+#messagepartheader table td
+{
+ text-overflow: ellipsis;
+}
+
+#messagepartheader table td.title
+{
+ width: 60px;
}
#mailcontframe
@@ -329,31 +373,7 @@
height: 100%;
min-height: 100%; /* Chrome 14 bug */
border: 1px solid #999999;
- background-color: #F9F9F9;
-}
-
-
-#partheader
-{
- position: absolute;
- top: 10px;
- left: 220px;
- right: 20px;
- height: 40px;
-}
-
-#partheader table td
-{
- padding-left: 2px;
- padding-right: 4px;
- vertical-align: middle;
- font-size: 11px;
-}
-
-#partheader table td.title
-{
- color: #666666;
- font-weight: bold;
+ background-color: #fff;
}
@@ -611,14 +631,22 @@ body.messagelist
background-color: #F9F9F9;
}
-#messagelist
+table.messagelist
{
width: 100%;
display: table;
table-layout: fixed;
+ border-collapse: collapse;
+ border-spacing: 0;
+ z-index: 1;
}
-#messagelist thead tr td
+table.messagelist.fixedcopy
+{
+ z-index: 2;
+}
+
+.messagelist thead tr td
{
height: 20px;
padding: 0 4px 0 2px;
@@ -630,23 +658,23 @@ body.messagelist
font-weight: bold;
}
-#messagelist thead tr td.sortedASC,
-#messagelist thead tr td.sortedDESC
+.messagelist thead tr td.sortedASC,
+.messagelist thead tr td.sortedDESC
{
background-position: 0 -26px;
}
-#messagelist thead tr td.sortedASC a
+.messagelist thead tr td.sortedASC a
{
background: url(images/icons/sort.gif) right 0 no-repeat;
}
-#messagelist thead tr td.sortedDESC a
+.messagelist thead tr td.sortedDESC a
{
background: url(images/icons/sort.gif) right -14px no-repeat;
}
-#messagelist thead tr td a
+.messagelist thead tr td a
{
display: block;
width: auto !important;
@@ -655,18 +683,19 @@ body.messagelist
text-decoration: none;
}
-#messagelist thead tr td.size
+.messagelist thead tr td.size.sortedASC a,
+.messagelist thead tr td.size.sortedDESC a
{
- text-align: left;
+ padding-right: 18px;
}
-#messagelist thead tr td.subject
+.messagelist thead tr td.subject
{
padding-left: 18px;
width: 99%;
}
-#messagelist tbody tr td
+.messagelist tbody tr td
{
height: 20px;
padding: 0;
@@ -680,7 +709,7 @@ body.messagelist
cursor: default;
}
-#messagelist tbody tr td a
+.messagelist tbody tr td a
{
color: #000;
text-decoration: none;
@@ -688,53 +717,53 @@ body.messagelist
cursor: inherit;
}
-#messagelist td img
+.messagelist td img
{
vertical-align: middle;
display: inline-block;
}
-#messagelist tbody tr td.flag,
-#messagelist tbody tr td.status,
-#messagelist tbody tr td.subject span.status
+.messagelist tbody tr td.flag,
+.messagelist tbody tr td.status,
+.messagelist tbody tr td.subject span.status
{
cursor: pointer;
}
-#messagelist tr td.flag span,
-#messagelist tr td.status span,
-#messagelist tr td.attachment span,
-#messagelist tr td.priority span
+.messagelist tr td.flag span,
+.messagelist tr td.status span,
+.messagelist tr td.attachment span,
+.messagelist tr td.priority span
{
display: block;
width: 15px;
}
-#messagelist tr td div.collapsed,
-#messagelist tr td div.expanded,
-#messagelist tr td.threads div.listmenu,
-#messagelist tr td.attachment span.attachment,
-#messagelist tr td.attachment span.report,
-#messagelist tr td.priority span.priority,
-#messagelist tr td.priority span.prio1,
-#messagelist tr td.priority span.prio2,
-#messagelist tr td.priority span.prio3,
-#messagelist tr td.priority span.prio4,
-#messagelist tr td.priority span.prio5,
-#messagelist tr td.flag span.flagged,
-#messagelist tr td.flag span.unflagged,
-#messagelist tr td.flag span.unflagged:hover,
-#messagelist tr td.status span.status,
-#messagelist tr td.status span.msgicon,
-#messagelist tr td.status span.deleted,
-#messagelist tr td.status span.unread,
-#messagelist tr td.status span.unreadchildren,
-#messagelist tr td.subject span.msgicon,
-#messagelist tr td.subject span.deleted,
-#messagelist tr td.subject span.unread,
-#messagelist tr td.subject span.replied,
-#messagelist tr td.subject span.forwarded,
-#messagelist tr td.subject span.unreadchildren
+.messagelist tr td div.collapsed,
+.messagelist tr td div.expanded,
+.messagelist tr td.threads div.listmenu,
+.messagelist tr td.attachment span.attachment,
+.messagelist tr td.attachment span.report,
+.messagelist tr td.priority span.priority,
+.messagelist tr td.priority span.prio1,
+.messagelist tr td.priority span.prio2,
+.messagelist tr td.priority span.prio3,
+.messagelist tr td.priority span.prio4,
+.messagelist tr td.priority span.prio5,
+.messagelist tr td.flag span.flagged,
+.messagelist tr td.flag span.unflagged,
+.messagelist tr td.flag span.unflagged:hover,
+.messagelist tr td.status span.status,
+.messagelist tr td.status span.msgicon,
+.messagelist tr td.status span.deleted,
+.messagelist tr td.status span.unread,
+.messagelist tr td.status span.unreadchildren,
+.messagelist tr td.subject span.msgicon,
+.messagelist tr td.subject span.deleted,
+.messagelist tr td.subject span.unread,
+.messagelist tr td.subject span.replied,
+.messagelist tr td.subject span.forwarded,
+.messagelist tr td.subject span.unreadchildren
{
display: inline-block;
vertical-align: middle;
@@ -743,212 +772,212 @@ body.messagelist
background: url(images/messageicons.png) center no-repeat;
}
-#messagelist tr td.attachment span.attachment
+.messagelist tr td.attachment span.attachment
{
background-position: 0 -170px;
}
-#messagelist tr td.attachment span.report
+.messagelist tr td.attachment span.report
{
background-position: 0 -255px;
}
-#messagelist tr td.priority span.priority
+.messagelist tr td.priority span.priority
{
background-position: 0 -309px;
}
-#messagelist tr td.priority span.prio5
+.messagelist tr td.priority span.prio5
{
background-position: 0 -358px;
}
-#messagelist tr td.priority span.prio4
+.messagelist tr td.priority span.prio4
{
background-position: 0 -340px;
}
-#messagelist tr td.priority span.prio3
+.messagelist tr td.priority span.prio3
{
background-position: 0 -324px;
}
-#messagelist tr td.priority span.prio2
+.messagelist tr td.priority span.prio2
{
background-position: 0 -309px;
}
-#messagelist tr td.priority span.prio1
+.messagelist tr td.priority span.prio1
{
background-position: 0 -290px;
}
-#messagelist tr td.flag span.flagged
+.messagelist tr td.flag span.flagged
{
background-position: 0 -153px;
}
-#messagelist tr td.flag span.unflagged:hover
+.messagelist tr td.flag span.unflagged:hover
{
background-position: 0 -136px;
}
-#messagelist tr td.subject span.msgicon,
-#messagelist tr td.subject span.unreadchildren
+.messagelist tr td.subject span.msgicon,
+.messagelist tr td.subject span.unreadchildren
{
background-position: 0 -51px;
margin: 0 2px;
}
-#messagelist tr td.subject span.replied
+.messagelist tr td.subject span.replied
{
background-position: 0 -85px;
}
-#messagelist tr td.subject span.forwarded
+.messagelist tr td.subject span.forwarded
{
background-position: 0 -68px;
}
-#messagelist tr td.subject span.replied.forwarded
+.messagelist tr td.subject span.replied.forwarded
{
background-position: 0 -102px;
}
-#messagelist tr td.status span.msgicon,
-#messagelist tr td.flag span.unflagged,
-#messagelist tr td.status span.unreadchildren
+.messagelist tr td.status span.msgicon,
+.messagelist tr td.flag span.unflagged,
+.messagelist tr td.status span.unreadchildren
{
background-position: 0 17px; /* no icon */
}
-#messagelist tr td.status span.msgicon:hover
+.messagelist tr td.status span.msgicon:hover
{
background-position: 0 -272px;
}
-#messagelist tr td.status span.deleted,
-#messagelist tr td.subject span.deleted
+.messagelist tr td.status span.deleted,
+.messagelist tr td.subject span.deleted
{
background-position: 0 -187px;
}
-#messagelist tr td.status span.status,
-#messagelist tr td.status span.unread,
-#messagelist tr td.subject span.unread
+.messagelist tr td.status span.status,
+.messagelist tr td.status span.unread,
+.messagelist tr td.subject span.unread
{
background-position: 0 -119px;
}
-#messagelist tr td div.collapsed
+.messagelist tr td div.collapsed
{
background-position: 0 -221px;
cursor: pointer;
}
-#messagelist tr td div.expanded
+.messagelist tr td div.expanded
{
background-position: 0 -204px;
cursor: pointer;
}
-#messagelist tr td.threads div.listmenu
+.messagelist tr td.threads div.listmenu
{
background-position: 0 -238px;
cursor: pointer;
}
-#messagelist tbody tr td.subject
+.messagelist tbody tr td.subject
{
width: 99%;
}
-#messagelist tbody tr td.subject a
+.messagelist tbody tr td.subject a
{
cursor: default;
vertical-align: middle; /* #1487091 */
}
/* thread parent message with unread children */
-#messagelist tbody tr.unroot td.subject a
+.messagelist tbody tr.unroot td.subject a
{
text-decoration: underline;
}
-#messagelist tr td.attachment,
-#messagelist tr td.threads,
-#messagelist tr td.status,
-#messagelist tr td.flag,
-#messagelist tr td.priority
+.messagelist tr td.attachment,
+.messagelist tr td.threads,
+.messagelist tr td.status,
+.messagelist tr td.flag,
+.messagelist tr td.priority
{
width: 17px;
padding: 0 0 0 2px;
}
-#messagelist tr td.size
+.messagelist tr td.size
{
width: 60px;
text-align: right;
padding: 0 2px;
}
-#messagelist tr td.fromto,
-#messagelist tr td.from,
-#messagelist tr td.to,
-#messagelist tr td.cc,
-#messagelist tr td.replyto
+.messagelist tr td.fromto,
+.messagelist tr td.from,
+.messagelist tr td.to,
+.messagelist tr td.cc,
+.messagelist tr td.replyto
{
width: 180px;
padding: 0 2px;
}
-#messagelist tr td.date
+.messagelist tr td.date
{
width: 118px;
padding: 0 2px;
}
-#messagelist tr.message
+.messagelist tr.message
{
background-color: #FFF;
}
-#messagelist tr.unread
+.messagelist tr.unread
{
font-weight: bold;
background-color: #FFFFFF;
}
-#messagelist tr.flagged td,
-#messagelist tr.flagged td a
+.messagelist tr.flagged td,
+.messagelist tr.flagged td a
{
color: #CC0000;
}
-#messagelist tr.selected td
+.messagelist tr.selected td
{
color: #FFFFFF;
background-color: #CC3333;
}
-#messagelist tr.unfocused td
+.messagelist tr.unfocused td
{
color: #FFFFFF;
background-color: #929292;
}
-#messagelist tr.selected td a
+.messagelist tr.selected td a
{
color: #FFFFFF;
}
-#messagelist tr.unfocused td a
+.messagelist tr.unfocused td a
{
color: #FFFFFF;
}
-#messagelist tr.deleted td,
-#messagelist tr.deleted td a
+.messagelist tr.deleted td,
+.messagelist tr.deleted td a
{
color: #CCCCCC;
}
@@ -1600,16 +1629,19 @@ input.from_address
vertical-align: middle;
}
+#upload-form,
#attachment-form
{
padding: 6px;
}
+#upload-form div,
#attachment-form div
{
padding: 2px;
}
+#upload-form div.buttons,
#attachment-form div.buttons
{
margin-top: 4px;
@@ -1687,6 +1719,14 @@ input.from_address
-o-text-overflow: ellipsis;
}
+#contacts-table td span.email
+{
+ display: inline;
+ color: #ccc;
+ font-style: italic;
+ margin-left: 0.5em;
+}
+
#abookcountbar
{
margin-top: 4px;
diff --git a/skins/classic/settings.css b/skins/classic/settings.css
index c918e3c18..2433f5040 100644
--- a/skins/classic/settings.css
+++ b/skins/classic/settings.css
@@ -85,6 +85,8 @@
{
font-weight: bold;
text-align: right;
+ width: 1%;
+ white-space: nowrap;
}
#bottomboxes
@@ -253,3 +255,15 @@ div.crop
{
overflow: auto;
}
+
+#rcmfd_signature
+{
+ width: 99%;
+ min-width: 390px;
+}
+
+#rcmfd_signature_toolbar1 td,
+#rcmfd_signature_toolbar2 td
+{
+ width: auto;
+}
diff --git a/skins/classic/templates/about.html b/skins/classic/templates/about.html
index 519acf773..429dfcf5f 100644
--- a/skins/classic/templates/about.html
+++ b/skins/classic/templates/about.html
@@ -7,11 +7,15 @@
</head>
<body>
+<roundcube:if condition="!request:_framed" />
+
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
<roundcube:include file="/includes/settingstabs.html" />
<div id="mainscreen" class="box darkbg crop">
+<roundcube:endif />
+
<div class="readtext">
<div id="license">
<roundcube:object name="aboutcontent" />
@@ -29,7 +33,10 @@ Some <a href="http://roundcube.net/license">exceptions</a> for skins &amp; plugi
<roundcube:object name="pluginlist" id="pluginlist" class="records-table" cellspacing="0" />
</div>
+
+<roundcube:if condition="!request:_framed" />
</div>
+<roundcube:endif />
</body>
</html>
diff --git a/skins/classic/templates/addressbook.html b/skins/classic/templates/addressbook.html
index ba119891c..429b83438 100644
--- a/skins/classic/templates/addressbook.html
+++ b/skins/classic/templates/addressbook.html
@@ -17,7 +17,7 @@
</style>
</head>
-<body onload="rcube_init_mail_ui()">
+<body>
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -75,7 +75,7 @@
<div id="addressscreen">
<div id="addresslist">
-<div class="boxtitle"><roundcube:label name="contacts" /></div>
+<roundcube:object name="addresslisttitle" label="contacts" tag="div" class="boxtitle" />
<div class="boxlistcontent">
<roundcube:object name="addresslist" id="contacts-table" class="records-table" cellspacing="0" summary="Contacts list" noheader="true" />
</div>
@@ -116,5 +116,16 @@
</ul>
</div>
+<div id="dragmenu" class="popupmenu">
+ <ul>
+ <li><roundcube:button command="move" onclick="return rcmail.drag_menu_action('move')" label="move" classAct="active" /></li>
+ <li><roundcube:button command="copy" onclick="return rcmail.drag_menu_action('copy')" label="copy" classAct="active" /></li>
+ </ul>
+</div>
+
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
</html>
diff --git a/skins/classic/templates/compose.html b/skins/classic/templates/compose.html
index 5b0b47924..660f354cd 100644
--- a/skins/classic/templates/compose.html
+++ b/skins/classic/templates/compose.html
@@ -16,10 +16,10 @@
</style>
</head>
<roundcube:if condition="env:extwin" />
-<body class="extwin" onload="rcube_init_mail_ui()">
+<body class="extwin">
<roundcube:object name="message" id="message" />
<roundcube:else />
-<body onload="rcube_init_mail_ui()">
+<body>
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
<roundcube:endif />
@@ -197,5 +197,9 @@
<roundcube:object name="composeAttachmentForm" id="attachment-form" attachmentFieldSize="40" class="popupmenu" />
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
</html>
diff --git a/skins/classic/templates/contact.html b/skins/classic/templates/contact.html
index d74a78b27..8be112b49 100644
--- a/skins/classic/templates/contact.html
+++ b/skins/classic/templates/contact.html
@@ -13,7 +13,7 @@
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" /></div>
<roundcube:endif />
- <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" /></div>
+ <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" placeholderGroup="/images/contactgroup.png" /></div>
<roundcube:object name="contacthead" id="contacthead" />
<div style="clear:both"></div>
<div id="contacttabs">
diff --git a/skins/classic/templates/contactadd.html b/skins/classic/templates/contactadd.html
index 05cc8aa82..86bca46ea 100644
--- a/skins/classic/templates/contactadd.html
+++ b/skins/classic/templates/contactadd.html
@@ -5,7 +5,7 @@
<roundcube:include file="/includes/links.html" />
<script type="text/javascript" src="/functions.js"></script>
</head>
-<body class="iframe" onload="rcube_init_mail_ui()">
+<body class="iframe">
<div id="contact-title" class="boxtitle"><roundcube:label name="addcontact" /></div>
<div id="contact-details" class="boxcontent">
@@ -35,7 +35,10 @@
<roundcube:object name="photoUploadForm" id="upload-form" size="30" class="popupmenu" />
<roundcube:object name="fileDropArea" id="contactpic" />
-<script type="text/javascript">rcube_init_tabs('contacttabs')</script>
+<script type="text/javascript">
+rcube_init_tabs('contacttabs');
+rcube_init_mail_ui();
+</script>
</body>
</html>
diff --git a/skins/classic/templates/contactedit.html b/skins/classic/templates/contactedit.html
index db8599ac6..8ab801d05 100644
--- a/skins/classic/templates/contactedit.html
+++ b/skins/classic/templates/contactedit.html
@@ -5,7 +5,7 @@
<roundcube:include file="/includes/links.html" />
<script type="text/javascript" src="/functions.js"></script>
</head>
-<body class="iframe" onload="rcube_init_mail_ui()">
+<body class="iframe">
<div id="contact-title" class="boxtitle"><roundcube:label name="editcontact" /></div>
<div id="contact-details" class="boxcontent">
@@ -35,7 +35,10 @@
<roundcube:object name="photoUploadForm" id="upload-form" size="30" class="popupmenu" />
<roundcube:object name="fileDropArea" id="contactpic" />
-<script type="text/javascript">rcube_init_tabs('contacttabs')</script>
+<script type="text/javascript">
+rcube_init_tabs('contacttabs');
+rcube_init_mail_ui();
+</script>
</body>
</html>
diff --git a/skins/classic/templates/folders.html b/skins/classic/templates/folders.html
index 1ae8809ec..f86be092b 100644
--- a/skins/classic/templates/folders.html
+++ b/skins/classic/templates/folders.html
@@ -12,7 +12,7 @@
}
</style>
</head>
-<body onload="rcube_init_mail_ui()">
+<body>
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -58,5 +58,9 @@
</ul>
</div>
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
</html>
diff --git a/skins/classic/templates/mail.html b/skins/classic/templates/mail.html
index c7010e87c..10aebc96d 100644
--- a/skins/classic/templates/mail.html
+++ b/skins/classic/templates/mail.html
@@ -18,7 +18,7 @@
}
</style>
</head>
-<body onload="rcube_init_mail_ui()">
+<body>
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -55,6 +55,7 @@
<div id="messagelistcontainer" class="boxlistcontent" style="top:0">
<roundcube:object name="messages"
id="messagelist"
+ class="messagelist fixedheader"
cellspacing="0"
columns=""
summary="Message list"
@@ -130,9 +131,9 @@
<roundcube:button command="reset-search" id="searchreset" image="/images/icons/reset.gif" title="resetsearch" width="13" height="13" />
</div>
-<div id="dragmessagemenu" class="popupmenu">
+<div id="dragmenu" class="popupmenu">
<ul>
- <li><roundcube:button command="moveto" onclick="return rcmail.drag_menu_action('moveto')" label="move" classAct="active" /></li>
+ <li><roundcube:button command="move" onclick="return rcmail.drag_menu_action('move')" label="move" classAct="active" /></li>
<li><roundcube:button command="copy" onclick="return rcmail.drag_menu_action('copy')" label="copy" classAct="active" /></li>
</ul>
</div>
@@ -140,7 +141,8 @@
<div id="mailboxoptionsmenu" class="popupmenu">
<ul>
<li><roundcube:button command="expunge" type="link" label="compact" classAct="active" /></li>
- <li class="separator_below"><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
+ <li><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
+ <li class="separator_below"><roundcube:button name="messageimport" type="link" class="active" label="importmessages" id="uploadformlink" onclick="rcmail_ui.show_popup('uploadform', true); return false" /></li>
<li><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
<roundcube:container name="mailboxoptions" id="mailboxoptionsmenu" />
</ul>
@@ -204,5 +206,11 @@
</div>
</div>
+<roundcube:object name="messageimportform" id="upload-form" attachmentFieldSize="40" class="popupmenu" />
+
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
</html>
diff --git a/skins/classic/templates/message.html b/skins/classic/templates/message.html
index 11e58c711..757c0a635 100644
--- a/skins/classic/templates/message.html
+++ b/skins/classic/templates/message.html
@@ -13,10 +13,10 @@
</style>
</head>
<roundcube:if condition="env:extwin" />
-<body class="extwin" onload="rcube_init_mail_ui()">
+<body class="extwin">
<roundcube:object name="message" id="message" />
<roundcube:else />
-<body onload="rcube_init_mail_ui()">
+<body>
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -81,5 +81,9 @@
</ul>
</div>
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
</html>
diff --git a/skins/classic/templates/messageerror.html b/skins/classic/templates/messageerror.html
index d02508942..eb8c7e058 100644
--- a/skins/classic/templates/messageerror.html
+++ b/skins/classic/templates/messageerror.html
@@ -27,7 +27,7 @@
</style>
</head>
-<body onload="rcube_init_mail_ui()">
+<body>
<roundcube:include file="/includes/taskbar.html" />
<roundcube:include file="/includes/header.html" />
@@ -61,6 +61,10 @@
rcmail.add_onload('mailviewsplitv.init()');
</script>
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
<roundcube:endif />
diff --git a/skins/classic/templates/messagepart.html b/skins/classic/templates/messagepart.html
index ce7dbe2e1..9f2215679 100644
--- a/skins/classic/templates/messagepart.html
+++ b/skins/classic/templates/messagepart.html
@@ -3,23 +3,39 @@
<head>
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
+<script type="text/javascript" src="/splitter.js"></script>
+<script type="text/javascript" src="/functions.js"></script>
+<style type="text/css">
+#messagepartheader { width: <roundcube:exp expression="!empty(cookie:mailpartsplitter) ? cookie:mailpartsplitter-5 : 170" />px; }
+#messagepartcontainer { left: <roundcube:exp expression="!empty(cookie:mailpartsplitter) ? cookie:mailpartsplitter+5 : 180" />px;
+<roundcube:exp expression="browser:ie ? ('width: expression((parseInt(this.parentNode.offsetWidth)-'.(!empty(cookie:mailpartsplitter) ? cookie:mailpartsplitter+5 : 180).')+\\'px\\');') : ''" />
+}
+</style>
</head>
<body class="extwin">
+<roundcube:object name="message" id="message" />
-<roundcube:include file="/includes/header.html" />
-
-<div id="partheader">
-<roundcube:object name="messagePartControls" cellpadding="2" cellspacing="0" />
-
-<div style="position:absolute; top:2px; right:0; width:12em; text-align:right">
- [<a href="#close" class="closelink" onclick="self.close()"><roundcube:label name="close" /></a>]
+<div id="messagetoolbar">
+ <roundcube:button command="download" type="link" class="button download" classAct="button download" classSel="button downloadSel" title="download" content=" " />
+ <roundcube:button command="print" type="link" class="button print" classAct="button print" classSel="button printSel" title="print" content=" " />
+ <roundcube:container name="toolbar" id="messagetoolbar" />
</div>
-</div>
-
-<div id="messagepartcontainer">
-<roundcube:object name="messagePartFrame" id="messagepartframe" width="100%" height="100%" />
+<div id="mainscreen">
+ <div id="messagepartheader">
+ <div class="boxtitle" /><roundcube:label name="properties" /></div>
+ <div class="boxlistcontent">
+ <roundcube:object name="messagePartControls" class="records-table" cellspacing="0" />
+ </div>
+ </div>
+ <div id="messagepartcontainer">
+ <roundcube:object name="messagePartFrame" id="messagepartframe" width="100%" height="100%" />
+ </div>
</div>
+<script type="text/javascript">
+var mailpartsplit = new rcube_splitter({id:'mailpartsplitter', p1: 'messagepartheader', p2: 'messagepartcontainer', orientation: 'v', relative: true, start: 165});
+rcmail.add_onload('mailpartsplit.init()');
+</script>
</body>
</html>
diff --git a/skins/classic/templates/messagepreview.html b/skins/classic/templates/messagepreview.html
index 80dbe381a..b42a06342 100644
--- a/skins/classic/templates/messagepreview.html
+++ b/skins/classic/templates/messagepreview.html
@@ -6,7 +6,7 @@
<script type="text/javascript" src="/splitter.js"></script>
<script type="text/javascript" src="/functions.js"></script>
</head>
-<body class="iframe" onload="rcube_init_mail_ui()">
+<body class="iframe">
<div class="messageheaderbox">
<div id="messagelinks">
@@ -34,5 +34,9 @@
</ul>
</div>
+<script type="text/javascript">
+rcube_init_mail_ui();
+</script>
+
</body>
</html>
diff --git a/skins/larry/addressbook.css b/skins/larry/addressbook.css
index ff3951497..090e54c7b 100644
--- a/skins/larry/addressbook.css
+++ b/skins/larry/addressbook.css
@@ -75,10 +75,6 @@
text-overflow: ellipsis;
}
-#contacts-table .contact.readonly td {
- font-style: italic;
-}
-
#directorylist li.addressbook a {
background-position: 6px -766px;
}
@@ -131,6 +127,28 @@
left: 20px;
}
+#contacts-table .contact.readonly td {
+ font-style: italic;
+}
+
+#contacts-table td.name {
+ width: 95%;
+}
+
+#contacts-table td.action {
+ width: 24px;
+ padding: 4px;
+}
+
+#contacts-table td.action a {
+ display: block;
+ width: 16px;
+ height: 14px;
+ text-indent: -5000px;
+ overflow: hidden;
+ background: url(images/listicons.png) -2px -1180px no-repeat;
+}
+
#contacts-table .contact td.name {
background-position: 6px -1603px;
}
@@ -141,6 +159,29 @@
font-weight: bold;
}
+#contacts-table .group td.name {
+ background-position: 6px -1555px;
+}
+
+#contacts-table .group.selected td.name,
+#contacts-table .group.unfocused td.name {
+ background-position: 6px -1579px;
+ font-weight: bold;
+}
+
+#addresslist .boxtitle {
+ padding-right: 95px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+#addresslist .boxtitle a.poplink {
+ color: #004458;
+ font-size: 14px;
+ line-height: 12px;
+ text-decoration: none;
+}
+
#contact-frame {
position: absolute;
top: 0;
diff --git a/skins/larry/ie7hacks.css b/skins/larry/ie7hacks.css
index 6d7af4787..fc4713361 100644
--- a/skins/larry/ie7hacks.css
+++ b/skins/larry/ie7hacks.css
@@ -41,6 +41,7 @@ a.deletebutton,
.boxfooter .listbutton .inner,
.attachmentslist li a.delete,
.attachmentslist li a.cancelupload,
+#contacts-table td.action a,
.previewheader .iconlink,
.minimal #taskbar .button-inner {
/* workaround for text-indent which also offsets the background image */
diff --git a/skins/larry/images/buttons.png b/skins/larry/images/buttons.png
index 54bee0156..9f8f44536 100644
--- a/skins/larry/images/buttons.png
+++ b/skins/larry/images/buttons.png
Binary files differ
diff --git a/skins/larry/images/contactgroup.png b/skins/larry/images/contactgroup.png
new file mode 100644
index 000000000..8303cf02f
--- /dev/null
+++ b/skins/larry/images/contactgroup.png
Binary files differ
diff --git a/skins/larry/images/listicons.png b/skins/larry/images/listicons.png
index f4505d4fa..e4ffef660 100644
--- a/skins/larry/images/listicons.png
+++ b/skins/larry/images/listicons.png
Binary files differ
diff --git a/skins/larry/includes/header.html b/skins/larry/includes/header.html
index f2efb8e06..c8b3b26f6 100644
--- a/skins/larry/includes/header.html
+++ b/skins/larry/includes/header.html
@@ -2,7 +2,7 @@
<div id="topline">
<div class="topleft">
<roundcube:container name="topline-left" id="topline-left" />
- <roundcube:button name="about" type="link" label="about" class="about-link" onclick="UI.show_about(this);return false" />
+ <roundcube:button name="about" type="link" label="about" class="about-link" onclick="UI.show_about(this);return false" condition="!env:extwin" />
<roundcube:if condition="config:support_url" />
<a href="<roundcube:var name='config:support_url' />" target="_blank" class="support-link" id="supportlink"><roundcube:label name="support" /></a>
<roundcube:endif />
@@ -14,7 +14,7 @@
<span class="username"><roundcube:object name="username" /></span>
<roundcube:button command="logout" label="logout" class="button-logout" />
<roundcube:elseif condition="env:extwin" />
- <roundcube:button command="close" label="close" class="closelink" />
+ <roundcube:button name="close" type="link" label="close" class="closelink" onclick="self.close()" />
<roundcube:endif />
</div>
</div>
@@ -35,5 +35,3 @@
<br style="clear:both" />
</div>
-
-
diff --git a/skins/larry/mail.css b/skins/larry/mail.css
index fe9e56ea3..b65b08112 100644
--- a/skins/larry/mail.css
+++ b/skins/larry/mail.css
@@ -79,6 +79,12 @@
overflow: auto;
}
+/* Real browsers accept this (not IE) */
+html>/**/body #messagelist {
+ overflow: auto;
+ overflow-x: hidden;
+}
+
#messagelistfooter {
position: absolute;
bottom: 0;
@@ -216,6 +222,46 @@ a.iconbutton.threadmode.selected {
background-position: 6px -1723px;
}
+#mailboxlist li.mailbox ul li.drafts > a {
+ background-position: 23px -238px;
+}
+
+#mailboxlist li.mailbox ul li.drafts.selected > a {
+ background-position: 23px -262px;
+}
+
+#mailboxlist li.mailbox ul li.sent > a {
+ background-position: 23px -286px;
+}
+
+#mailboxlist li.mailbox ul li.sent.selected > a {
+ background-position: 23px -310px;
+}
+
+#mailboxlist li.mailbox ul li.junk > a {
+ background-position: 23px -334px;
+}
+
+#mailboxlist li.mailbox ul li.junk.selected > a {
+ background-position: 23px -358px;
+}
+
+#mailboxlist li.mailbox ul li.trash > a {
+ background-position: 23px -382px;
+}
+
+#mailboxlist li.mailbox ul li.trash.selected > a {
+ background-position: 23px -406px;
+}
+
+#mailboxlist li.mailbox ul li.archive > a {
+ background-position: 23px -1699px;
+}
+
+#mailboxlist li.mailbox ul li.archive.selected > a {
+ background-position: 23px -1723px;
+}
+
#mailboxlist li.unread {
font-weight: bold;
}
@@ -388,7 +434,6 @@ a.iconbutton.threadmode.selected {
position: absolute;
right: 0;
top: 0;
- width: 400px;
}
#mailpreviewtoggle {
@@ -408,141 +453,154 @@ a.iconbutton.threadmode.selected {
/*** message list ***/
-#messagelist thead td:first-child {
+/* this is necessary to make FF3 display borders */
+body:-moz-last-node #messagelist {
+ border-collapse: separate;
+}
+
+table.messagelist {
+ z-index: 1;
+}
+
+table.messagelist.fixedcopy {
+ z-index: 2;
+}
+
+.messagelist thead td:first-child {
border-radius: 4px 0 0 0; /* for Chrome */
}
-#messagelist tr td.attachment,
-#messagelist tr td.threads,
-#messagelist tr td.status,
-#messagelist tr td.flag,
-#messagelist tr td.priority {
+.messagelist tr td.attachment,
+.messagelist tr td.threads,
+.messagelist tr td.status,
+.messagelist tr td.flag,
+.messagelist tr td.priority {
width: 20px;
padding: 2px 3px;
}
-.webkit #messagelist tr td.attachment,
-.webkit #messagelist tr td.threads,
-.webkit #messagelist tr td.status,
-.webkit #messagelist tr td.flag,
-.webkit #messagelist tr td.priority {
+.webkit .messagelist tr td.attachment,
+.webkit .messagelist tr td.threads,
+.webkit .messagelist tr td.status,
+.webkit .messagelist tr td.flag,
+.webkit .messagelist tr td.priority {
width: 26px;
}
-#messagelist tr td.threads {
+.messagelist tr td.threads {
width: 26px;
}
-.webkit #messagelist tr td.threads {
+.webkit .messagelist tr td.threads {
width: 30px;
}
-#messagelist tr td.threads,
-#messagelist tr td.threads + td {
+.messagelist tr td.threads,
+.messagelist tr td.threads + td {
border-left: 0;
}
-#messagelist tr td.size {
+.messagelist tr td.size {
width: 60px;
text-align: right;
}
-#messagelist thead tr td.size {
+.messagelist thead tr td.size {
text-align: left;
}
-#messagelist tr td.fromto,
-#messagelist tr td.from,
-#messagelist tr td.to,
-#messagelist tr td.cc,
-#messagelist tr td.replyto {
+.messagelist tr td.fromto,
+.messagelist tr td.from,
+.messagelist tr td.to,
+.messagelist tr td.cc,
+.messagelist tr td.replyto {
width: 200px;
}
-#messagelist tr td.date {
+.messagelist tr td.date {
width: 135px;
}
-#messagelist tr.message {
+.messagelist tr.message {
/* background-color: #fff; */
}
-#messagelist tr.thread.expanded td {
+.messagelist tr.thread.expanded td {
background-color: #ededed;
}
-#messagelist tr.unread {
+.messagelist tr.unread {
font-weight: bold;
/* background-color: #fff; */
}
-#messagelist tr.flagged td,
-#messagelist tr.flagged td a {
+.messagelist tr.flagged td,
+.messagelist tr.flagged td a {
color: #f30;
}
-#messagelist thead tr td.sortedASC a,
-#messagelist thead tr td.sortedDESC a {
+.messagelist thead tr td.sortedASC a,
+.messagelist thead tr td.sortedDESC a {
color: #004458;
text-decoration: underline;
background: url(images/listicons.png) right -912px no-repeat;
}
-#messagelist thead tr td.sortedASC a {
+.messagelist thead tr td.sortedASC a {
background-position: right -944px;
}
-#messagelist td img {
+.messagelist td img {
vertical-align: middle;
display: inline-block;
}
-#messagelist tbody td a {
+.messagelist tbody td a {
color: #333;
text-decoration: none;
white-space: nowrap;
cursor: default;
}
-#messagelist tbody tr td.flag,
-#messagelist tbody tr td.status,
-#messagelist tbody tr td.subject span.status {
+.messagelist tbody tr td.flag,
+.messagelist tbody tr td.status,
+.messagelist tbody tr td.subject span.status {
cursor: pointer;
}
-#messagelist tr td.flag span,
-#messagelist tr td.status span,
-#messagelist tr td.attachment span,
-#messagelist tr td.priority span {
+.messagelist tr td.flag span,
+.messagelist tr td.status span,
+.messagelist tr td.attachment span,
+.messagelist tr td.priority span {
display: block;
width: 20px;
}
-#messagelist tr td div.collapsed,
-#messagelist tr td div.expanded,
-#messagelist tr td.threads div.listmenu,
-#messagelist tr td.attachment span.attachment,
-#messagelist tr td.attachment span.report,
-#messagelist tr td.priority span.priority,
-#messagelist tr td.priority span.prio1,
-#messagelist tr td.priority span.prio2,
-#messagelist tr td.priority span.prio3,
-#messagelist tr td.priority span.prio4,
-#messagelist tr td.priority span.prio5,
-#messagelist tr td.flag span.flagged,
-#messagelist tr td.flag span.unflagged,
-#messagelist tr td.flag span.unflagged:hover,
-#messagelist tr td.status span.status,
-#messagelist tr td.status span.msgicon,
-#messagelist tr td.status span.deleted,
-#messagelist tr td.status span.unread,
-#messagelist tr td.status span.unreadchildren,
-#messagelist tr td.subject span.msgicon,
-#messagelist tr td.subject span.deleted,
-#messagelist tr td.subject span.unread,
-#messagelist tr td.subject span.replied,
-#messagelist tr td.subject span.forwarded,
-#messagelist tr td.subject span.unreadchildren {
+.messagelist tr td div.collapsed,
+.messagelist tr td div.expanded,
+.messagelist tr td.threads div.listmenu,
+.messagelist tr td.attachment span.attachment,
+.messagelist tr td.attachment span.report,
+.messagelist tr td.priority span.priority,
+.messagelist tr td.priority span.prio1,
+.messagelist tr td.priority span.prio2,
+.messagelist tr td.priority span.prio3,
+.messagelist tr td.priority span.prio4,
+.messagelist tr td.priority span.prio5,
+.messagelist tr td.flag span.flagged,
+.messagelist tr td.flag span.unflagged,
+.messagelist tr td.flag span.unflagged:hover,
+.messagelist tr td.status span.status,
+.messagelist tr td.status span.msgicon,
+.messagelist tr td.status span.deleted,
+.messagelist tr td.status span.unread,
+.messagelist tr td.status span.unreadchildren,
+.messagelist tr td.subject span.msgicon,
+.messagelist tr td.subject span.deleted,
+.messagelist tr td.subject span.unread,
+.messagelist tr td.subject span.replied,
+.messagelist tr td.subject span.forwarded,
+.messagelist tr td.subject span.unreadchildren {
display: inline-block;
vertical-align: middle;
height: 18px;
@@ -551,135 +609,135 @@ a.iconbutton.threadmode.selected {
background: url(images/listicons.png) -100px 0 no-repeat;
}
-#messagelist tbody tr td.attachment span.attachment {
+.messagelist tbody tr td.attachment span.attachment {
background-position: 0 -996px;
}
-#messagelist thead tr td.attachment span.attachment {
+.messagelist thead tr td.attachment span.attachment {
background-position: -24px -997px;
}
-#messagelist tbody tr td.attachment span.report {
+.messagelist tbody tr td.attachment span.report {
background-position: -24px -1116px;
}
-#messagelist tr td.priority span.prio5 {
+.messagelist tr td.priority span.prio5 {
background-position: 0 -1905px;
}
-#messagelist tr td.priority span.prio4 {
+.messagelist tr td.priority span.prio4 {
background-position: 0 -1885px;
}
-#messagelist tr td.priority span.prio2 {
+.messagelist tr td.priority span.prio2 {
background-position: 0 -1865px;
}
-#messagelist tr td.priority span.prio1 {
+.messagelist tr td.priority span.prio1 {
background-position: 0 -1845px;
}
-#messagelist tbody tr td.flag span.flagged {
+.messagelist tbody tr td.flag span.flagged {
background-position: 0 -1036px;
}
-#messagelist thead tr td.flag span.flagged {
+.messagelist thead tr td.flag span.flagged {
background-position: -24px -1036px;
}
-#messagelist tr td.status span.msgicon:hover {
+.messagelist tr td.status span.msgicon:hover {
background-position: -23px -1056px;
}
-#messagelist tr td.flag span.unflagged:hover {
+.messagelist tr td.flag span.unflagged:hover {
background-position: -23px -1076px;
}
-#messagelist tr td.subject span.msgicon,
-#messagelist tr td.subject span.unreadchildren {
+.messagelist tr td.subject span.msgicon,
+.messagelist tr td.subject span.unreadchildren {
background-position: 0 -1056px;
margin: 0 1px 0 0;
width: 24px;
}
-#messagelist tr td.subject span.replied {
+.messagelist tr td.subject span.replied {
background-position: 0 -1076px;
}
-#messagelist tr td.subject span.forwarded {
+.messagelist tr td.subject span.forwarded {
background-position: 0 -1096px;
}
-#messagelist tr td.subject span.replied.forwarded {
+.messagelist tr td.subject span.replied.forwarded {
background-position: 0 -1116px;
}
-#messagelist tr td.status span.msgicon,
-#messagelist tr td.flag span.unflagged,
-#messagelist tr td.status span.unreadchildren {
+.messagelist tr td.status span.msgicon,
+.messagelist tr td.flag span.unflagged,
+.messagelist tr td.status span.unreadchildren {
background-position: 0 1056px; /* no icon */
}
/*
-#messagelist tr td.status span.msgicon:hover {
+.messagelist tr td.status span.msgicon:hover {
background-position: 0 -272px;
}
*/
-#messagelist tr td.status span.deleted,
-#messagelist tr td.status span.deleted:hover,
-#messagelist tr td.subject span.deleted {
+.messagelist tr td.status span.deleted,
+.messagelist tr td.status span.deleted:hover,
+.messagelist tr td.subject span.deleted {
background-position: -22px -1096px;
}
-#messagelist tr td.status span.status,
-#messagelist tr td.status span.unread,
-#messagelist tr td.subject span.unread,
-#messagelist tr td.status span.unread:hover {
+.messagelist tr td.status span.status,
+.messagelist tr td.status span.unread,
+.messagelist tr td.subject span.unread,
+.messagelist tr td.status span.unread:hover {
background-position: 0 -1016px;
}
-#messagelist thead tr td.status span.status {
+.messagelist thead tr td.status span.status {
background-position: -24px -1016px;
}
-#messagelist tr td div.collapsed {
+.messagelist tr td div.collapsed {
background-position: 0 -1137px;
cursor: pointer;
}
-#messagelist tr td div.expanded {
+.messagelist tr td div.expanded {
background-position: 0 -1157px;
cursor: pointer;
}
-#messagelist tr td.threads div.listmenu {
+.messagelist tr td.threads div.listmenu {
background-position: 0 -976px;
cursor: pointer;
width: 26px;
}
-#messagelist thead tr td.subject,
-#messagelist tbody tr td.subject {
+.messagelist thead tr td.subject,
+.messagelist tbody tr td.subject {
width: 99%;
white-space: nowrap;
}
-#messagelist tbody tr td.subject a {
+.messagelist tbody tr td.subject a {
cursor: default;
vertical-align: middle; /* #1487091 */
}
/* thread parent message with unread children */
-#messagelist tbody tr.unroot td.subject a {
+.messagelist tbody tr.unroot td.subject a {
text-decoration: underline;
}
/**** tree indicators ****/
-#messagelist tbody tr td span.branch div {
+.messagelist tbody tr td span.branch div {
display: inline-block;
}
-#messagelist tbody tr td span.branch div.tree {
+.messagelist tbody tr td span.branch div.tree {
width: 15px;
}
@@ -713,7 +771,6 @@ a.iconbutton.threadmode.selected {
}
#messageheader,
-#partheader,
#composeheaders {
position: relative;
padding: 3px 0;
@@ -1148,8 +1205,8 @@ div.message-partheaders .headers-table td.header {
#messagepartcontainer {
position: absolute;
- top: 60px;
- left: 0;
+ top: 42px;
+ left: 232px;
right: 0;
bottom: 0;
}
@@ -1160,6 +1217,30 @@ div.message-partheaders .headers-table td.header {
height: 100%;
}
+#messagepartheader {
+ position: absolute;
+ top: 42px;
+ left: 0;
+ width: 220px;
+ bottom: 0;
+}
+
+#messagepartheader table {
+ table-layout: fixed;
+ overflow: hidden;
+}
+
+#messagepartheader table td {
+ text-overflow: ellipsis;
+ overflow: hidden;
+}
+
+#messagepartheader table td.title {
+ width: 60px;
+ padding-right: 0;
+}
+
+
/*** message composition ***/
#composeview-left {
@@ -1238,6 +1319,19 @@ div.message-partheaders .headers-table td.header {
text-overflow: ellipsis;
}
+#contacts-table td.contactgroup a {
+ color: #376572;
+ text-decoration: none;
+}
+
+#contacts-table td.contactgroup a span {
+ display: inline-block;
+ font-size: 16px;
+ font-weight: bold;
+ line-height: 11px;
+ margin-left: 0.3em;
+}
+
#contacts-table tr:first-child td {
border-top: 0;
}
diff --git a/skins/larry/settings.css b/skins/larry/settings.css
index 1734b55e5..59037ac76 100644
--- a/skins/larry/settings.css
+++ b/skins/larry/settings.css
@@ -267,3 +267,13 @@ img.skinthumbnail {
.webkit #pluginlist td.source {
width: 9em;
}
+
+#rcmfd_signature {
+ width: 99%;
+ min-width: 390px;
+}
+
+#rcmfd_signature_toolbar1 td,
+#rcmfd_signature_toolbar2 td {
+ width: auto;
+}
diff --git a/skins/larry/styles.css b/skins/larry/styles.css
index cfbf9ac5f..ec4f3047c 100644
--- a/skins/larry/styles.css
+++ b/skins/larry/styles.css
@@ -690,17 +690,6 @@ a.iconlink.upload {
opacity: 0.999;
}
-.partwin #topline {
- position: absolute;
- right: 6px;
- top: 18px;
- width: auto;
- z-index: 100;
- background: transparent;
- background: none;
- border: 0;
-}
-
.minimal #topline a.button-logout {
display: none;
}
@@ -883,10 +872,6 @@ a.iconlink.upload {
top: 102px;
}
-.partwin #mainscreen {
- top: 60px
-}
-
.extwin #mainscreen {
top: 40px;
}
@@ -896,7 +881,7 @@ a.iconlink.upload {
}
#mainscreen .offset {
- margin-top: 42px;
+ top: 42px;
}
.uibox {
@@ -1059,6 +1044,10 @@ table.listing tr.droptarget td {
background-color: #e8e798;
}
+.listbox table.listing {
+ background-color: #d9ecf4;
+}
+
table.listing,
table.layout {
border: 0;
@@ -1813,6 +1802,10 @@ ul.proplist li {
background-position: 0 -1745px;
}
+.toolbar a.button.download {
+ background-position: center -1906px;
+}
+
a.menuselector {
display: inline-block;
border: 1px solid #ababab;
@@ -1858,6 +1851,7 @@ select.decorated {
filter: alpha(opacity=0);
-khtml-appearance: none;
-webkit-appearance: none;
+ border: 0;
}
html.opera select.decorated {
@@ -1873,6 +1867,7 @@ select.decorated option {
text-shadow: 0px 1px 1px #333;
padding: 4px 6px;
outline: none;
+ cursor: default;
}
diff --git a/skins/larry/templates/about.html b/skins/larry/templates/about.html
index 301c301a9..e2bd0b019 100644
--- a/skins/larry/templates/about.html
+++ b/skins/larry/templates/about.html
@@ -4,7 +4,11 @@
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
</head>
+<roundcube:if condition="request:_framed" />
+<body class="iframe fullheight">
+<roundcube:else />
<body class="ui-widget-content">
+<roundcube:endif />
<div class="readtext">
<roundcube:object name="aboutcontent" />
diff --git a/skins/larry/templates/addressbook.html b/skins/larry/templates/addressbook.html
index 401640f1f..b33ebd999 100644
--- a/skins/larry/templates/addressbook.html
+++ b/skins/larry/templates/addressbook.html
@@ -50,7 +50,7 @@
<!-- contacts list -->
<div id="addresslist" class="uibox listbox">
-<h2 class="boxtitle"><roundcube:label name="contacts" /></h2>
+<roundcube:object name="addresslisttitle" label="contacts" tag="h2" class="boxtitle" />
<div class="scroller withfooter">
<roundcube:object name="addresslist" id="contacts-table" class="listing" noheader="true" />
</div>
@@ -106,6 +106,13 @@
</ul>
</div>
+<div id="dragcontactmenu" class="popupmenu">
+ <ul class="toolbarmenu">
+ <li><roundcube:button command="move" onclick="return rcmail.drag_menu_action('move')" label="move" classAct="active" /></li>
+ <li><roundcube:button command="copy" onclick="return rcmail.drag_menu_action('copy')" label="copy" classAct="active" /></li>
+ </ul>
+</div>
+
<roundcube:include file="/includes/footer.html" />
</body>
diff --git a/skins/larry/templates/contact.html b/skins/larry/templates/contact.html
index d252049cd..59fe6f79f 100644
--- a/skins/larry/templates/contact.html
+++ b/skins/larry/templates/contact.html
@@ -13,7 +13,7 @@
<div id="sourcename"><roundcube:label name="addressbook" />: <roundcube:var name="env:sourcename" /></div>
<roundcube:endif />
- <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" /></div>
+ <div id="contactphoto"><roundcube:object name="contactphoto" id="contactpic" placeholder="/images/contactpic.png" placeholderGroup="/images/contactgroup.png" /></div>
<roundcube:object name="contacthead" id="contacthead" />
<br style="clear:both" />
diff --git a/skins/larry/templates/mail.html b/skins/larry/templates/mail.html
index 85cd5203b..6015054d3 100644
--- a/skins/larry/templates/mail.html
+++ b/skins/larry/templates/mail.html
@@ -70,7 +70,7 @@
<div id="messagelistcontainer" class="boxlistcontent">
<roundcube:object name="messages"
id="messagelist"
- class="records-table sortheader"
+ class="records-table messagelist sortheader fixedheader"
optionsmenuIcon="true" />
</div>
@@ -140,7 +140,7 @@
<div id="dragmessagemenu" class="popupmenu">
<ul class="toolbarmenu">
- <li><roundcube:button command="moveto" onclick="return rcmail.drag_menu_action('moveto')" label="move" classAct="active" /></li>
+ <li><roundcube:button command="move" onclick="return rcmail.drag_menu_action('move')" label="move" classAct="active" /></li>
<li><roundcube:button command="copy" onclick="return rcmail.drag_menu_action('copy')" label="copy" classAct="active" /></li>
</ul>
</div>
@@ -148,7 +148,8 @@
<div id="mailboxmenu" class="popupmenu">
<ul class="toolbarmenu" id="mailboxoptionsmenu">
<li><roundcube:button command="expunge" type="link" label="compact" classAct="active" /></li>
- <li class="separator_below"><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
+ <li><roundcube:button command="purge" type="link" label="empty" classAct="active" /></li>
+ <li><roundcube:button name="messageimport" type="link" class="active" label="importmessages" onclick="UI.show_uploadform()" /></li>
<li><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
<roundcube:container name="mailboxoptions" id="mailboxoptionsmenu" />
</ul>
@@ -226,6 +227,14 @@
</div>
</div>
+<div id="upload-dialog" class="propform popupdialog" title="<roundcube:label name='importmessages' />">
+ <roundcube:object name="messageimportform" id="uploadform" attachmentFieldSize="40" buttons="no" />
+ <div class="formbuttons">
+ <roundcube:button command="import-messages" type="input" class="button mainaction" label="upload" />
+ <roundcube:button name="close" type="input" class="button" label="cancel" onclick="UI.show_uploadform()" />
+ </div>
+</div>
+
<roundcube:include file="/includes/footer.html" />
</body>
diff --git a/skins/larry/templates/message.html b/skins/larry/templates/message.html
index 7ac7e5b55..6937b00af 100644
--- a/skins/larry/templates/message.html
+++ b/skins/larry/templates/message.html
@@ -17,7 +17,7 @@
<roundcube:endif />
<roundcube:include file="/includes/mailtoolbar.html" />
<div class="toolbarselect">
- <roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('moveto', this.options[this.selectedIndex].value)" class="mailboxlist decorated" folder_filter="mail" />
+ <roundcube:object name="mailboxlist" type="select" noSelection="moveto" maxlength="25" onchange="rcmail.command('move', this.options[this.selectedIndex].value)" class="mailboxlist decorated" folder_filter="mail" />
</div>
</div>
diff --git a/skins/larry/templates/messagepart.html b/skins/larry/templates/messagepart.html
index dbb4940de..d0e3a808d 100644
--- a/skins/larry/templates/messagepart.html
+++ b/skins/larry/templates/messagepart.html
@@ -4,33 +4,35 @@
<title><roundcube:object name="pagetitle" /></title>
<roundcube:include file="/includes/links.html" />
</head>
-<body class="partwin">
+<body class="extwin noscroll">
-<div id="header">
-<div id="topline">
- <div class="topright">
- <a href="#close" class="closelink" onclick="self.close()"><roundcube:label name="close" /></a>
- </div>
-</div>
+<roundcube:include file="/includes/header.html" />
-<div id="topnav">
- <roundcube:object name="logo" src="/images/roundcube_logo.png" id="toplogo" border="0" alt="Logo" />
-</div>
+<div id="mainscreen">
-<br style="clear:both" />
+<div id="messagetoolbar" class="toolbar fullwidth">
+ <roundcube:button command="download" type="link" class="button download disabled" classAct="button download" classSel="button download pressed" label="download" />
+ <roundcube:button command="print" type="link" class="button print disabled" classAct="button print" classSel="button print pressed" label="print" />
+ <roundcube:container name="toolbar" id="messagetoolbar" />
</div>
-<div id="mainscreen">
-
-<div id="partheader" class="uibox">
-<roundcube:object name="messagePartControls" class="headers-table" />
+<div id="messagepartheader" class="uibox listbox">
+ <h2 class="boxtitle"><roundcube:label name="properties" /></h2>
+ <div class="scroller">
+ <roundcube:object name="messagePartControls" class="listing" />
+ </div>
</div>
<div id="messagepartcontainer" class="uibox">
-<roundcube:object name="messagePartFrame" id="messagepartframe" frameborder="0" />
+ <div class="iframebox">
+ <roundcube:object name="messagePartFrame" id="messagepartframe" frameborder="0" />
+ </div>
+ <roundcube:object name="message" id="message" class="statusbar" />
</div>
</div>
+<roundcube:include file="/includes/footer.html" />
+
</body>
</html>
diff --git a/skins/larry/ui.js b/skins/larry/ui.js
index f7428f4da..e5733bd23 100644
--- a/skins/larry/ui.js
+++ b/skins/larry/ui.js
@@ -19,7 +19,7 @@ function rcube_mail_ui()
searchmenu: { editable:1, callback:searchmenu },
attachmentmenu: { },
listoptions: { editable:1 },
- dragmessagemenu: { sticky:1 },
+ dragmenu: { sticky:1 },
groupmenu: { above:1 },
mailboxmenu: { above:1 },
spellmenu: { callback: spellmenu },
@@ -90,8 +90,8 @@ function rcube_mail_ui()
var dragmenu = $('#dragmessagemenu');
if (dragmenu.length) {
- rcmail.gui_object('message_dragmenu', 'dragmessagemenu');
- popups.dragmessagemenu = dragmenu;
+ rcmail.gui_object('dragmenu', 'dragmessagemenu');
+ popups.dragmenu = dragmenu;
}
if (rcmail.env.action == 'show' || rcmail.env.action == 'preview') {
@@ -152,6 +152,11 @@ function rcube_mail_ui()
rcmail.addEventListener('setquota', update_quota);
rcmail.addEventListener('enable-command', enable_command);
+ rcmail.addEventListener('afterimport-messages', show_uploadform);
+ }
+ else if (rcmail.env.action == 'get') {
+ new rcube_splitter({ id:'mailpartsplitterv', p1:'#messagepartheader', p2:'#messagepartcontainer',
+ orientation:'v', relative:true, start:226, min:150, size:12}).init();
}
if ($('#mailview-left').length) {
@@ -190,6 +195,8 @@ function rcube_mail_ui()
/*** addressbook task ***/
else if (rcmail.env.task == 'addressbook') {
rcmail.addEventListener('afterupload-photo', show_uploadform);
+ rcmail.addEventListener('beforepushgroup', push_contactgroup);
+ rcmail.addEventListener('beforepopgroup', pop_contactgroup);
if (rcmail.env.action == '') {
new rcube_splitter({ id:'addressviewsplitterd', p1:'#addressview-left', p2:'#addressview-right',
@@ -199,12 +206,12 @@ function rcube_mail_ui()
new rcube_scroller('#directorylist-content', '#directorylist-header', '#directorylist-footer');
}
- }
- // set min-width to show all toolbar buttons
- var screen = $('.minwidth');
- if (screen.length) {
- screen.css('min-width', $('.toolbar').width() + $('#quicksearchbar').parent().width() + 20);
+ var dragmenu = $('#dragcontactmenu');
+ if (dragmenu.length) {
+ rcmail.gui_object('dragmenu', 'dragcontactmenu');
+ popups.dragmenu = dragmenu;
+ }
}
// turn a group of fieldsets into tabs
@@ -218,6 +225,7 @@ function rcube_mail_ui()
}
var select = $(this),
+ parent = select.parent(),
height = Math.max(select.height(), 26) - 2,
width = select.width() - 22,
title = $('option', this).first().text();
@@ -232,20 +240,23 @@ function rcube_mail_ui()
overlay.children().width(width).height(height).css('line-height', (height - 1) + 'px');
- select.change(function() {
- var val = $('option:selected', this).text();
- $(this).next().children().html(val);
- });
-
- var parent = select.parent();
if (parent.css('position') != 'absolute')
parent.css('position', 'relative');
// re-set original select width to fix click action and options width in some browsers
- if (!bw.mz)
- select.width(overlay.width());
+ select.width(overlay.width())
+ .change(function() {
+ var val = $('option:selected', this).text();
+ $(this).next().children().text(val);
+ });
});
+ // set min-width to show all toolbar buttons
+ var screen = $('body > div.minwidth');
+ if (screen.length) {
+ screen.css('min-width', $('.toolbar').width() + $('#quicksearchbar').width() + $('#searchfilter').width() + 30);
+ }
+
$(document.body)
.bind('mouseup', body_mouseup)
.bind('keyup', function(e){
@@ -589,8 +600,11 @@ function rcube_mail_ui()
mailviewsplit.handle.hide();
}
- if (visible && uid && rcmail.message_list)
- rcmail.message_list.scrollto(uid);
+ if (rcmail.message_list) {
+ if (visible && uid)
+ rcmail.message_list.scrollto(uid);
+ rcmail.message_list.resize();
+ }
rcmail.command('save-pref', { name:'preview_pane', value:(visible?1:0) });
}
@@ -824,6 +838,35 @@ function rcube_mail_ui()
});
}
+ function push_contactgroup(p)
+ {
+ // lets the contacts list swipe to the left, nice!
+ var table = $('#contacts-table'),
+ scroller = table.parent().css('overflow', 'hidden');
+
+ table.clone()
+ .css({ position:'absolute', top:'0', left:'0', width:table.width()+'px', 'z-index':10 })
+ .appendTo(scroller)
+ .animate({ left: -(table.width()+5) + 'px' }, 300, 'swing', function(){
+ $(this).remove();
+ scroller.css('overflow', 'auto')
+ });
+ }
+
+ function pop_contactgroup(p)
+ {
+ // lets the contacts list swipe to the left, nice!
+ var table = $('#contacts-table'),
+ scroller = table.parent().css('overflow', 'hidden'),
+ clone = table.clone().appendTo(scroller);
+
+ table.css({ position:'absolute', top:'0', left:-(table.width()+5) + 'px', width:table.width()+'px', height:table.height()+'px', 'z-index':10 })
+ .animate({ left:'0' }, 300, 'linear', function(){
+ clone.remove();
+ $(this).css({ position:'relative', left:'0', width:'100%', height:'auto', 'z-index':1 });
+ scroller.css('overflow', 'auto')
+ });
+ }
function show_uploadform()
{
@@ -834,7 +877,7 @@ function rcube_mail_ui()
$dialog.dialog('close');
return;
}
-
+
// add icons to clone file input field
if (rcmail.env.action == 'compose' && !$dialog.data('extended')) {
$('<a>')
diff --git a/tests/Framework/ImapGeneric.php b/tests/Framework/ImapGeneric.php
index 2f9b6d10f..af73158e5 100644
--- a/tests/Framework/ImapGeneric.php
+++ b/tests/Framework/ImapGeneric.php
@@ -35,4 +35,27 @@ class Framework_ImapGeneric extends PHPUnit_Framework_TestCase
$this->assertSame(array(1, 2, 3), $result);
$this->assertCount(3, $result);
}
+
+ /**
+ * Test for tokenizeResponse
+ */
+ function test_tokenizeResponse()
+ {
+ $response = "test brack[et] {1}\r\na {0}\r\n (item1 item2)";
+
+ $result = rcube_imap_generic::tokenizeResponse($response, 1);
+ $this->assertSame("test", $result);
+
+ $result = rcube_imap_generic::tokenizeResponse($response, 1);
+ $this->assertSame("brack[et]", $result);
+
+ $result = rcube_imap_generic::tokenizeResponse($response, 1);
+ $this->assertSame("a", $result);
+
+ $result = rcube_imap_generic::tokenizeResponse($response, 1);
+ $this->assertSame("", $result);
+
+ $result = rcube_imap_generic::tokenizeResponse($response, 1);
+ $this->assertSame(array('item1', 'item2'), $result);
+ }
}