Merge branch 'master' of github.com:roundcube/roundcubemail

pull/46/merge
Thomas Bruederli 12 years ago
commit 6ddb16d181

@ -1,10 +1,13 @@
CHANGELOG Roundcube Webmail
===========================
- Fix excessive LFs at the end of composed message with top_posting=true (#1488797)
- Support contacts import from CSV file (#1486399)
- Improved keep-alive action. Now the interval is based on session_lifetime (#1488507)
- Added cross-task 'refresh' request for system state updates (#1488507)
- Renamed config options: keep_alive to refresh_interval, min_keep_alive to min_refresh_interval
- Fix handling of text/enriched content on message reply/forward/edit
- Option to display attached images as thumbnails below message body
- Fix bug where leading blanks were stripped from quoted lines (#1488795)
- Upgraded to jQuery 1.8.2 and jQuery UI 1.9.1
- Upgraded to jQuery 1.8.3 and jQuery UI 1.9.1
- Add config option to automatically generate LDAP attributes for new entries
- Better client-side timezone detection using the jsTimezoneDetect library (#1488725)
- Add option to disable saving sent mail in Sent folder - no_save_sent_messages (#1488686)
@ -52,6 +55,14 @@ CHANGELOG Roundcube Webmail
Move global functions from main.inc and rcube_shared.inc into classes
Better classes separation
RELEASE 0.8.4
-------------
- Fix regression where unintentional page reload was done after request abort (#1488802)
- Fix XSS vulnerability in handling of text/enriched messages (#1488806)
- Fix handling of 'media' attribute on linked css (#1488789)
- Fix excessive LFs at the end of composed message with top_posting=true (#1488797)
- Fix bug where leading blanks were stripped from quoted lines (#1488795)
RELEASE 0.8.3
-------------
- Fix AREA links handling (#1488792)

@ -241,7 +241,6 @@ $rcmail_config['skin_include_php'] = false;
$rcmail_config['display_version'] = false;
// Session lifetime in minutes
// must be greater than 'keep_alive'/60
$rcmail_config['session_lifetime'] = 10;
// Session domain: .example.org
@ -504,9 +503,8 @@ $rcmail_config['recipients_separator'] = ',';
// don't let users set pagesize to more than this value if set
$rcmail_config['max_pagesize'] = 200;
// Minimal value of user's 'keep_alive' setting (in seconds)
// Must be less than 'session_lifetime'
$rcmail_config['min_keep_alive'] = 60;
// Minimal value of user's 'refresh_interval' setting (in seconds)
$rcmail_config['min_refresh_interval'] = 60;
// Enables files upload indicator. Requires APC installed and enabled apc.rfc1867 option.
// By default refresh time is set to 1 second. You can set this value to true
@ -790,9 +788,10 @@ $rcmail_config['read_when_deleted'] = true;
// Use 'Purge' to remove messages marked as deleted
$rcmail_config['flag_for_deletion'] = false;
// Default interval for keep-alive/check-recent requests (in seconds)
// Must be greater than or equal to 'min_keep_alive' and less than 'session_lifetime'
$rcmail_config['keep_alive'] = 60;
// Default interval for auto-refresh requests (in seconds)
// These are requests for system state updates e.g. checking for new messages, etc.
// Setting it to 0 disables the feature.
$rcmail_config['refresh_interval'] = 60;
// If true all folders will be checked for recent messages
$rcmail_config['check_all_folders'] = false;

@ -249,7 +249,6 @@ $plugin = $RCMAIL->plugins->exec_hook('ready', array('task' => $RCMAIL->task, 'a
$RCMAIL->set_task($plugin['task']);
$RCMAIL->action = $plugin['action'];
// handle special actions
if ($RCMAIL->action == 'keep-alive') {
$OUTPUT->reset();
@ -282,7 +281,8 @@ while ($redirects < 5) {
else if (($stepfile = $RCMAIL->get_action_file())
&& is_file($incfile = INSTALL_PATH . 'program/steps/'.$RCMAIL->task.'/'.$stepfile)
) {
include $incfile;
// include action file only once (in case it don't exit)
include_once $incfile;
$redirects++;
}
else {
@ -290,6 +290,9 @@ while ($redirects < 5) {
}
}
if ($RCMAIL->action == 'refresh') {
$RCMAIL->plugins->exec_hook('refresh', array());
}
// parse main template (default)
$OUTPUT->send($RCMAIL->task);

@ -342,9 +342,6 @@ class rcube_install
}
}
if ($current['keep_alive'] && $current['session_lifetime'] < $current['keep_alive'])
$current['session_lifetime'] = max(10, ceil($current['keep_alive'] / 60) * 2);
$this->config = array_merge($this->config, $current);
foreach ((array)$current['ldap_public'] as $key => $values) {
@ -454,7 +451,7 @@ class rcube_install
'0.5-beta', '0.5', '0.5.1',
'0.6-beta', '0.6',
'0.7-beta', '0.7', '0.7.1', '0.7.2', '0.7.3',
'0.8-beta', '0.8-rc', '0.8.0', '0.8.1', '0.8.2', '0.8.3',
'0.8-beta', '0.8-rc', '0.8.0', '0.8.1', '0.8.2', '0.8.3', '0.8.4',
));
return $select;
}

@ -25,6 +25,12 @@ $rcmail_config['password_log'] = false;
// will be not available (no Password tab in Settings)
$rcmail_config['password_login_exceptions'] = null;
// Array of hosts that support password changing. Default is NULL.
// Listed hosts will feature a Password option in Settings; others will not.
// Example:
//$rcmail_config['password_hosts'] = array('mail.example.com', 'mail2.example.org');
$rcmail_config['password_hosts'] = null;
// SQL Driver options
// ------------------

@ -15,9 +15,9 @@
<email>alec@alec.pl</email>
<active>yes</active>
</lead>
<date>2012-03-07</date>
<date>2012-11-15</date>
<version>
<release>3.1</release>
<release>3.2</release>
<api>2.0</api>
</version>
<stability>
@ -26,13 +26,8 @@
</stability>
<license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>
- Added pw_usermod driver (#1487826)
- Added option password_login_exceptions (#1487826)
- Added domainfactory driver (#1487882)
- Added DBMail driver (#1488281)
- Helper files moved to helpers/ directory from drivers/
- Added Expect driver (#1488363)
- Added Samba password (#1488364)
- Fix wrong (non-specific) error message on crypt or connection error (#1488808)
- Added option to define IMAP hosts that support password changes - password_hosts
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@ -331,5 +326,26 @@
- Fixed drivers namespace issues
</notes>
</release>
<release>
<date>2012-03-07</date>
<version>
<release>3.1</release>
<api>2.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="http://www.gnu.org/licenses/gpl-2.0.html">GNU GPLv2</license>
<notes>
- Added pw_usermod driver (#1487826)
- Added option password_login_exceptions (#1487826)
- Added domainfactory driver (#1487882)
- Added DBMail driver (#1488281)
- Helper files moved to helpers/ directory from drivers/
- Added Expect driver (#1488363)
- Added Samba password (#1488364)
</notes>
</release>
</changelog>
</package>

@ -3,7 +3,7 @@
/*
+-------------------------------------------------------------------------+
| Password Plugin for Roundcube |
| @version @package_version@ |
| @version @package_version@ |
| |
| Copyright (C) 2009-2010, Roundcube Dev. |
| |
@ -56,7 +56,13 @@ class password extends rcube_plugin
$this->load_config();
// Exceptions list
// Host exceptions
$hosts = $rcmail->config->get('password_hosts');
if (!empty($hosts) && !in_array($_SESSION['storage_host'], $hosts)) {
return;
}
// Login exceptions
if ($exceptions = $rcmail->config->get('password_login_exceptions')) {
$exceptions = array_map('trim', (array) $exceptions);
$exceptions = array_filter($exceptions);
@ -274,8 +280,10 @@ class password extends rcube_plugin
return;
case PASSWORD_CRYPT_ERROR;
$reason = $this->gettext('crypterror');
break;
case PASSWORD_CONNECT_ERROR;
$reason = $this->gettext('connecterror');
break;
case PASSWORD_ERROR:
default:
$reason = $this->gettext('internalerror');

@ -23,7 +23,8 @@
/**
* Class for HTML code creation
*
* @package HTML
* @package Framework
* @subpackage HTML
*/
class html
{

@ -94,9 +94,6 @@ class rcmail extends rcube
// create user object
$this->set_user(new rcube_user($_SESSION['user_id']));
// configure session (after user config merge!)
$this->session_configure();
// set task and action properties
$this->set_task(rcube_utils::get_input_value('_task', rcube_utils::INPUT_GPC));
$this->action = asciiwords(rcube_utils::get_input_value('_action', rcube_utils::INPUT_GPC));
@ -320,10 +317,9 @@ class rcmail extends rcube
if (!($this->output instanceof rcube_output_html))
$this->output = new rcube_output_html($this->task, $framed);
// set keep-alive/check-recent interval
if ($this->session && ($keep_alive = $this->session->get_keep_alive())) {
$this->output->set_env('keep_alive', $keep_alive);
}
// set refresh interval
$this->output->set_env('refresh_interval', $this->config->get('refresh_interval', 0));
$this->output->set_env('session_lifetime', $this->config->get('session_lifetime', 0) * 60);
if ($framed) {
$this->comm_path .= '&_framed=1';
@ -336,7 +332,7 @@ class rcmail extends rcube
$this->output->set_charset(RCMAIL_CHARSET);
// add some basic labels to client
$this->output->add_label('loading', 'servererror', 'requesttimedout');
$this->output->add_label('loading', 'servererror', 'requesttimedout', 'refreshing');
return $this->output;
}
@ -522,7 +518,6 @@ class rcmail extends rcube
// Configure environment
$this->set_user($user);
$this->set_storage_prop();
$this->session_configure();
// fix some old settings according to namespace prefix
$this->fix_namespace_settings($user);
@ -775,6 +770,7 @@ class rcmail extends rcube
}
}
/**
* Registers action aliases for current task
*
@ -789,6 +785,7 @@ class rcmail extends rcube
}
}
/**
* Returns current action filename
*
@ -803,6 +800,7 @@ class rcmail extends rcube
return strtr($this->action, '-', '_') . '.inc';
}
/**
* Fixes some user preferences according to namespace handling change.
* Old Roundcube versions were using folder names with removed namespace prefix.

@ -434,6 +434,9 @@ class rcube
$this->session->register_gc_handler(array($this, 'temp_gc'));
$this->session->register_gc_handler(array($this, 'cache_gc'));
$this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME']));
$this->session->set_ip_check($this->config->get('ip_check'));
// start PHP session (if not in CLI mode)
if ($_SERVER['REMOTE_ADDR']) {
session_start();
@ -441,33 +444,6 @@ class rcube
}
/**
* Configure session object internals
*/
public function session_configure()
{
if (!$this->session) {
return;
}
$lifetime = $this->config->get('session_lifetime', 0) * 60;
$keep_alive = $this->config->get('keep_alive');
// set keep-alive/check-recent interval
if ($keep_alive) {
// be sure that it's less than session lifetime
if ($lifetime) {
$keep_alive = min($keep_alive, $lifetime - 30);
}
$keep_alive = max(60, $keep_alive);
$this->session->set_keep_alive($keep_alive);
}
$this->session->set_secret($this->config->get('des_key') . dirname($_SERVER['SCRIPT_NAME']));
$this->session->set_ip_check($this->config->get('ip_check'));
}
/**
* Garbage collector function for temp files.
* Remove temp files older than two days

@ -23,7 +23,8 @@
/**
* Abstract skeleton of an address book/repository
*
* @package Addressbook
* @package Framework
* @subpackage Addressbook
*/
abstract class rcube_addressbook
{

@ -23,8 +23,9 @@
* Helper class to turn relative urls into absolute ones
* using a predefined base
*
* @package Core
* @author Thomas Bruederli <roundcube@gmail.com>
* @package Framework
* @subpackage Core
* @author Thomas Bruederli <roundcube@gmail.com>
*/
class rcube_base_replacer
{

@ -22,7 +22,8 @@
/**
* Provide details about the client's browser based on the User-Agent header
*
* @package Core
* @package Framework
* @subpackage Core
*/
class rcube_browser
{

@ -25,10 +25,10 @@
/**
* Interface class for accessing Roundcube cache
*
* @package Cache
* @package Framework
* @subpackage Cache
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @version 1.1
*/
class rcube_cache
{

@ -25,10 +25,11 @@
/**
* Character sets conversion functionality
*
* @package Core
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @author Edmund Grimley Evans <edmundo@rano.org>
* @package Framework
* @subpackage Core
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @author Edmund Grimley Evans <edmundo@rano.org>
*/
class rcube_charset
{
@ -655,22 +656,49 @@ class rcube_charset
*/
public static function detect($string, $failover='')
{
if (!function_exists('mb_detect_encoding')) {
return $failover;
}
// FIXME: the order is important, because sometimes
// iso string is detected as euc-jp and etc.
$enc = array(
'UTF-8', 'SJIS', 'BIG5', 'GB2312',
'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4',
'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9',
'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
'WINDOWS-1252', 'WINDOWS-1251', 'EUC-JP', 'EUC-TW', 'KOI8-R',
'ISO-2022-KR', 'ISO-2022-JP'
);
if (substr($string, 0, 4) == "\0\0\xFE\xFF") return 'UTF-32BE'; // Big Endian
if (substr($string, 0, 4) == "\xFF\xFE\0\0") return 'UTF-32LE'; // Little Endian
if (substr($string, 0, 2) == "\xFE\xFF") return 'UTF-16BE'; // Big Endian
if (substr($string, 0, 2) == "\xFF\xFE") return 'UTF-16LE'; // Little Endian
if (substr($string, 0, 3) == "\xEF\xBB\xBF") return 'UTF-8';
// heuristics
if ($string[0] == "\0" && $string[1] == "\0" && $string[2] == "\0" && $string[3] != "\0") return 'UTF-32BE';
if ($string[0] != "\0" && $string[1] == "\0" && $string[2] == "\0" && $string[3] == "\0") return 'UTF-32LE';
if ($string[0] == "\0" && $string[1] != "\0" && $string[2] == "\0" && $string[3] != "\0") return 'UTF-16BE';
if ($string[0] != "\0" && $string[1] == "\0" && $string[2] != "\0" && $string[3] == "\0") return 'UTF-16LE';
if (function_exists('mb_detect_encoding')) {
// FIXME: the order is important, because sometimes
// iso string is detected as euc-jp and etc.
$enc = array(
'UTF-8', 'SJIS', 'GB2312',
'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4',
'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9',
'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
'WINDOWS-1252', 'WINDOWS-1251', 'EUC-JP', 'EUC-TW', 'KOI8-R', 'BIG5',
'ISO-2022-KR', 'ISO-2022-JP',
);
$result = mb_detect_encoding($string, join(',', $enc));
$result = mb_detect_encoding($string, join(',', $enc));
}
else {
// No match, check for UTF-8
// from http://w3.org/International/questions/qa-forms-utf-8.html
if (preg_match('/\A(
[\x09\x0A\x0D\x20-\x7E]
| [\xC2-\xDF][\x80-\xBF]
| \xE0[\xA0-\xBF][\x80-\xBF]
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
| \xED[\x80-\x9F][\x80-\xBF]
| \xF0[\x90-\xBF][\x80-\xBF]{2}
| [\xF1-\xF3][\x80-\xBF]{3}
| \xF4[\x80-\x8F][\x80-\xBF]{2}
)*\z/xs', substr($string, 0, 2048))
) {
return 'UTF-8';
}
}
return $result ? $result : $failover;
}

@ -22,7 +22,8 @@
/**
* Configuration class for Roundcube
*
* @package Core
* @package Framework
* @subpackage Core
*/
class rcube_config
{
@ -43,6 +44,8 @@ class rcube_config
'mail_pagesize' => 'pagesize',
'addressbook_pagesize' => 'pagesize',
'reply_mode' => 'top_posting',
'refresh_interval' => 'keep_alive',
'min_refresh_interval' => 'min_keep_alive',
);

@ -23,7 +23,8 @@
/**
* Model class for the local address book database
*
* @package Addressbook
* @package Framework
* @subpackage Addressbook
*/
class rcube_contacts extends rcube_addressbook
{

@ -21,6 +21,9 @@
/**
* PHP stream filter to detect html/javascript code in attachments
*
* @package Framework
* @subpackage Core
*/
class rcube_content_filter extends php_user_filter
{

@ -0,0 +1,382 @@
<?php
/*
+-----------------------------------------------------------------------+
| program/include/rcube_csv2vcard.php |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2008-2012, 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: |
| CSV to vCard data conversion |
+-----------------------------------------------------------------------+
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
/**
* CSV to vCard data converter
*
* @package Framework
* @subpackage Addressbook
* @author Aleksander Machniak <alec@alec.pl>
*/
class rcube_csv2vcard
{
/**
* CSV to vCard fields mapping
*
* @var array
*/
protected $csv2vcard_map = array(
// MS Outlook 2010
'anniversary' => 'anniversary',
'assistants_name' => 'assistant',
'assistants_phone' => 'phone:assistant',
'birthday' => 'birthday',
'business_city' => 'locality:work',
'business_countryregion' => 'country:work',
'business_fax' => 'phone:work,fax',
'business_phone' => 'phone:work',
'business_phone_2' => 'phone:work2',
'business_postal_code' => 'zipcode:work',
'business_state' => 'region:work',
'business_street' => 'street:work',
//'business_street_2' => '',
//'business_street_3' => '',
'car_phone' => 'phone:car',
'categories' => 'categories',
//'children' => '',
'company' => 'organization',
//'company_main_phone' => '',
'department' => 'department',
//'email_2_address' => '', //@TODO
//'email_2_type' => '',
//'email_3_address' => '', //@TODO
//'email_3_type' => '',
'email_address' => 'email:main',
//'email_type' => '',
'first_name' => 'firstname',
'gender' => 'gender',
'home_city' => 'locality:home',
'home_countryregion' => 'country:home',
'home_fax' => 'phone:home,fax',
'home_phone' => 'phone:home',
'home_phone_2' => 'phone:home2',
'home_postal_code' => 'zipcode:home',
'home_state' => 'region:home',
'home_street' => 'street:home',
//'home_street_2' => '',
//'home_street_3' => '',
//'initials' => '',
//'isdn' => '',
'job_title' => 'jobtitle',
//'keywords' => '',
//'language' => '',
'last_name' => 'surname',
//'location' => '',
'managers_name' => 'manager',
'middle_name' => 'middlename',
//'mileage' => '',
'mobile_phone' => 'phone:cell',
'notes' => 'notes',
//'office_location' => '',
'other_city' => 'locality:other',
'other_countryregion' => 'country:other',
'other_fax' => 'phone:other,fax',
'other_phone' => 'phone:other',
'other_postal_code' => 'zipcode:other',
'other_state' => 'region:other',
'other_street' => 'street:other',
//'other_street_2' => '',
//'other_street_3' => '',
'pager' => 'phone:pager',
'primary_phone' => 'phone:pref',
//'profession' => '',
//'radio_phone' => '',
'spouse' => 'spouse',
'suffix' => 'suffix',
'title' => 'title',
'web_page' => 'website:homepage',
// Thunderbird
'birth_day' => 'birthday-d',
'birth_month' => 'birthday-m',
'birth_year' => 'birthday-y',
'display_name' => 'displayname',
'fax_number' => 'phone:fax',
'home_address' => 'street:home',
//'home_address_2' => '',
'home_country' => 'country:home',
'home_zipcode' => 'zipcode:home',
'mobile_number' => 'phone:cell',
'nickname' => 'nickname',
'organization' => 'organization',
'pager_number' => 'phone:pager',
'primary_email' => 'email:pref',
'secondary_email' => 'email:other',
'web_page_1' => 'website:homepage',
'web_page_2' => 'website:other',
'work_phone' => 'phone:work',
'work_address' => 'street:work',
//'work_address_2' => '',
'work_country' => 'country:work',
'work_zipcode' => 'zipcode:work',
);
/**
* CSV label to text mapping for English
*
* @var array
*/
protected $label_map = array(
// MS Outlook 2010
'anniversary' => "Anniversary",
'assistants_name' => "Assistant's Name",
'assistants_phone' => "Assistant's Phone",
'birthday' => "Birthday",
'business_city' => "Business City",
'business_countryregion' => "Business Country/Region",
'business_fax' => "Business Fax",
'business_phone' => "Business Phone",
'business_phone_2' => "Business Phone 2",
'business_postal_code' => "Business Postal Code",
'business_state' => "Business State",
'business_street' => "Business Street",
//'business_street_2' => "Business Street 2",
//'business_street_3' => "Business Street 3",
'car_phone' => "Car Phone",
'categories' => "Categories",
//'children' => "Children",
'company' => "Company",
//'company_main_phone' => "Company Main Phone",
'department' => "Department",
//'directory_server' => "Directory Server",
//'email_2_address' => "E-mail 2 Address",
//'email_2_type' => "E-mail 2 Type",
//'email_3_address' => "E-mail 3 Address",
//'email_3_type' => "E-mail 3 Type",
'email_address' => "E-mail Address",
//'email_type' => "E-mail Type",
'first_name' => "First Name",
'gender' => "Gender",
'home_city' => "Home City",
'home_countryregion' => "Home Country/Region",
'home_fax' => "Home Fax",
'home_phone' => "Home Phone",
'home_phone_2' => "Home Phone 2",
'home_postal_code' => "Home Postal Code",
'home_state' => "Home State",
'home_street' => "Home Street",
//'home_street_2' => "Home Street 2",
//'home_street_3' => "Home Street 3",
//'initials' => "Initials",
//'isdn' => "ISDN",
'job_title' => "Job Title",
//'keywords' => "Keywords",
//'language' => "Language",
'last_name' => "Last Name",
//'location' => "Location",
'managers_name' => "Manager's Name",
'middle_name' => "Middle Name",
//'mileage' => "Mileage",
'mobile_phone' => "Mobile Phone",
'notes' => "Notes",
//'office_location' => "Office Location",
'other_city' => "Other City",
'other_countryregion' => "Other Country/Region",
'other_fax' => "Other Fax",
'other_phone' => "Other Phone",
'other_postal_code' => "Other Postal Code",
'other_state' => "Other State",
'other_street' => "Other Street",
//'other_street_2' => "Other Street 2",
//'other_street_3' => "Other Street 3",
'pager' => "Pager",
'primary_phone' => "Primary Phone",
//'profession' => "Profession",
//'radio_phone' => "Radio Phone",
'spouse' => "Spouse",
'suffix' => "Suffix",
'title' => "Title",
'web_page' => "Web Page",
// Thunderbird
'birth_day' => "Birth Day",
'birth_month' => "Birth Month",
'birth_year' => "Birth Year",
'display_name' => "Display Name",
'fax_number' => "Fax Number",
'home_address' => "Home Address",
//'home_address_2' => "Home Address 2",
'home_country' => "Home Country",
'home_zipcode' => "Home ZipCode",
'mobile_number' => "Mobile Number",
'nickname' => "Nickname",
'organization' => "Organization",
'pager_number' => "Pager Namber",
'primary_email' => "Primary Email",
'secondary_email' => "Secondary Email",
'web_page_1' => "Web Page 1",
'web_page_2' => "Web Page 2",
'work_phone' => "Work Phone",
'work_address' => "Work Address",
//'work_address_2' => "Work Address 2",
'work_country' => "Work Country",
'work_zipcode' => "Work ZipCode",
);
protected $local_label_map = array();
protected $vcards = array();
protected $map = array();
/**
* Class constructor
*
* @param string $lang File language
*/
public function __construct($lang = 'en_US')
{
// Localize fields map
if ($lang && $lang != 'en_US') {
if (file_exists(INSTALL_PATH . "program/localization/$lang/csv2vcard.inc")) {
include INSTALL_PATH . "program/localization/$lang/csv2vcard.inc";
}
if (!empty($map)) {
$this->local_label_map = array_merge($this->label_map, $map);
}
}
$this->label_map = array_flip($this->label_map);
$this->local_label_map = array_flip($this->local_label_map);
}
/**
*
*/
public function import($csv)
{
// convert to UTF-8
$head = substr($csv, 0, 4096);
$fallback = rcube::get_instance()->config->get('default_charset', 'ISO-8859-1'); // fallback to Latin-1?
$charset = rcube_charset::detect($head, RCMAIL_CHARSET);
$csv = rcube_charset::convert($csv, $charset);
$head = '';
$this->map = array();
// Parse file
foreach (preg_split("/[\r\n]+/", $csv) as $i => $line) {
$line = trim($line);
if (empty($line)) {
continue;
}
$elements = rcube_utils::explode_quoted_string(',', $line);
if (empty($elements)) {
continue;
}
// Parse header
if (empty($this->map)) {
$this->parse_header($elements);
if (empty($this->map)) {
break;
}
}
// Parse data row
else {
$this->csv_to_vcard($elements);
}
}
}
/**
* @return array rcube_vcard List of vcards
*/
public function export()
{
return $this->vcards;
}
/**
* Parse CSV header line, detect fields mapping
*/
protected function parse_header($elements)
{
$map1 = array();
$map2 = array();
$size = count($elements);
// check English labels
for ($i = 0; $i < $size; $i++) {
$label = $this->label_map[$elements[$i]];
if ($label && !empty($this->csv2vcard_map[$label])) {
$map1[$i] = $this->csv2vcard_map[$label];
}
}
// check localized labels
if (!empty($this->local_label_map)) {
for ($i = 0; $i < $size; $i++) {
$label = $this->local_label_map[$elements[$i]];
if ($label && !empty($this->csv2vcard_map[$label])) {
$map2[$i] = $this->csv2vcard_map[$label];
}
}
}
$this->map = count($map1) >= count($map2) ? $map1 : $map2;
}
/**
* Convert CSV data row to vCard
*/
protected function csv_to_vcard($data)
{
$contact = array();
foreach ($this->map as $idx => $name) {
$value = $data[$idx];
if ($value !== null && $value !== '') {
$contact[$name] = $value;
}
}
if (empty($contact)) {
return;
}
// Handle special values
if (!empty($contact['birthday-d']) && !empty($contact['birthday-m']) && !empty($contact['birthday-y'])) {
$contact['birthday'] = $contact['birthday-y'] .'-' .$contact['birthday-m'] . '-' . $contact['birthday-d'];
}
foreach (array('birthday', 'anniversary') as $key) {
if (!empty($contact[$key]) && $contact[$key] == '0/0/00') { // @TODO: localization?
unset($contact[$key]);
}
}
if (!empty($contact['gender']) && ($gender = strtolower($contact['gender']))) {
if (!in_array($gender, array('male', 'female'))) {
unset($contact['gender']);
}
}
// Create vcard object
$vcard = new rcube_vcard();
foreach ($contact as $name => $value) {
$name = explode(':', $name);
$vcard->set($name[0], $value, $name[1]);
}
// add to the list
$this->vcards[] = $vcard;
}
}

@ -21,12 +21,11 @@
/**
* Database independent query interface
* Database independent query interface.
* This is a wrapper for the PHP PDO.
*
* This is a wrapper for the PHP PDO
*
* @package Database
* @version 1.0
* @package Framework
* @sbpackage Database
*/
class rcube_db
{

@ -23,11 +23,10 @@
/**
* Database independent query interface
*
* This is a wrapper for the PHP PDO
*
* @package Database
* @version 1.0
* @package Framework
* @subpackage Database
*/
class rcube_db_mssql extends rcube_db
{

@ -26,8 +26,8 @@
*
* This is a wrapper for the PHP PDO
*
* @package Database
* @version 1.0
* @package Framework
* @subpackage Database
*/
class rcube_db_mysql extends rcube_db
{

@ -23,11 +23,10 @@
/**
* Database independent query interface
*
* This is a wrapper for the PHP PDO
*
* @package Database
* @version 1.0
* @package Framework
* @subpackage Database
*/
class rcube_db_pgsql extends rcube_db
{

@ -23,11 +23,10 @@
/**
* Database independent query interface
*
* This is a wrapper for the PHP PDO
*
* @package Database
* @version 1.0
* @package Framework
* @subpackage Database
*/
class rcube_db_sqlite extends rcube_db
{

@ -23,11 +23,10 @@
/**
* Database independent query interface
*
* This is a wrapper for the PHP PDO
*
* @package Database
* @version 1.0
* @package Framework
* @subpackage Database
*/
class rcube_db_sqlsrv extends rcube_db
{

@ -21,6 +21,12 @@
+-----------------------------------------------------------------------+
*/
/**
* Image resizer and converter
*
* @package Framework
* @subpackage Utils
*/
class rcube_image
{
private $image_file;

@ -25,10 +25,10 @@
/**
* Interface class for accessing an IMAP server
*
* @package Mail
* @package Framework
* @subpackage Storage
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @version 2.0
*/
class rcube_imap extends rcube_storage
{

@ -24,10 +24,10 @@
/**
* Interface class for accessing Roundcube messages cache
*
* @package Cache
* @package Framework
* @subpackage Storage
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @version 1.0
*/
class rcube_imap_cache
{

@ -30,8 +30,8 @@
/**
* PHP based wrapper class to connect to an IMAP server
*
* @package Mail
* @author Aleksander Machniak <alec@alec.pl>
* @package Framework
* @subpackage Storage
*/
class rcube_imap_generic
{

@ -6,7 +6,7 @@
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2006-2012, The Roundcube Dev Team |
| Copyright (C) 2011, Kolab Systems AG |
| Copyright (C) 2011-2012, Kolab Systems AG |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -26,7 +26,8 @@
/**
* Model class to access an LDAP address directory
*
* @package Addressbook
* @package Framework
* @subpackage Addressbook
*/
class rcube_ldap extends rcube_addressbook
{
@ -160,7 +161,8 @@ class rcube_ldap extends rcube_addressbook
}
// make sure LDAP_rdn field is required
if (!empty($this->prop['LDAP_rdn']) && !in_array($this->prop['LDAP_rdn'], $this->prop['required_fields']) && !in_array($this->prop['LDAP_rdn'], array_keys($this->prop['autovalues']))) {
if (!empty($this->prop['LDAP_rdn']) && !in_array($this->prop['LDAP_rdn'], $this->prop['required_fields'])
&& !in_array($this->prop['LDAP_rdn'], array_keys((array)$this->prop['autovalues']))) {
$this->prop['required_fields'][] = $this->prop['LDAP_rdn'];
}

@ -24,7 +24,8 @@
* Logical representation of a mail message with all its data
* and related functions
*
* @package Mail
* @package Framework
* @subpackage Storage
* @author Thomas Bruederli <roundcube@gmail.com>
*/
class rcube_message
@ -198,14 +199,15 @@ class rcube_message
* Determine if the message contains a HTML part
*
* @param bool $recursive Enables checking in all levels of the structure
* @param bool $enriched Enables checking for text/enriched parts too
*
* @return bool True if a HTML is available, False if not
*/
function has_html_part($recursive = true)
function has_html_part($recursive = true, $enriched = false)
{
// check all message parts
foreach ($this->parts as $part) {
if ($part->mimetype == 'text/html') {
if ($part->mimetype == 'text/html' || ($enriched && $part->mimetype == 'text/enriched')) {
// Level check, we'll skip e.g. HTML attachments
if (!$recursive) {
$level = explode('.', $part->mime_id);
@ -270,10 +272,6 @@ class rcube_message
else if ($part->mimetype == 'text/html') {
$out = $this->get_part_content($mime_id);
// remove special chars encoding
$trans = array_flip(get_html_translation_table(HTML_ENTITIES));
$out = strtr($out, $trans);
// create instance of html2text class
$txt = new html2text($out);
return $txt->get_text();

@ -23,8 +23,9 @@
/**
* Struct representing an e-mail message header
*
* @package Mail
* @author Aleksander Machniak <alec@alec.pl>
* @package Framework
* @subpackage Storage
* @author Aleksander Machniak <alec@alec.pl>
*/
class rcube_message_header
{

@ -25,10 +25,10 @@
/**
* Class representing a message part
*
* @package Mail
* @package Framework
* @subpackage Storage
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @version 2.0
*/
class rcube_message_part
{

@ -25,9 +25,10 @@
/**
* Class for parsing MIME messages
*
* @package Mail
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @package Framework
* @subpackage Storage
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
*/
class rcube_mime
{

@ -22,7 +22,8 @@
/**
* Class for output generation
*
* @package HTML
* @package Framework
* @subpackage View
*/
abstract class rcube_output
{

@ -23,7 +23,8 @@
/**
* Class to create HTML page output using a skin template
*
* @package View
* @package Framework
* @subpackage View
*/
class rcube_output_html extends rcube_output
{
@ -1090,7 +1091,7 @@ class rcube_output_html extends rcube_output
// make valid href to specific buttons
if (in_array($attrib['command'], rcmail::$main_tasks)) {
$attrib['href'] = $this->app->url(array('task' => $attrib['command']));
$attrib['onclick'] = sprintf("%s.command('switch-task','%s',null,event); return false", rcmail::JS_OBJECT_NAME, $attrib['command']);
$attrib['onclick'] = sprintf("return %s.command('switch-task','%s',this,event)", rcmail::JS_OBJECT_NAME, $attrib['command']);
}
else if ($attrib['task'] && in_array($attrib['task'], rcmail::$main_tasks)) {
$attrib['href'] = $this->app->url(array('action' => $attrib['command'], 'task' => $attrib['task']));

@ -23,7 +23,8 @@
/**
* View class to produce JSON responses
*
* @package View
* @package Framework
* @subpackage View
*/
class rcube_output_json extends rcube_output
{

@ -22,7 +22,8 @@
/**
* Plugin interface class
*
* @package PluginAPI
* @package Framework
* @subpackage PluginAPI
*/
abstract class rcube_plugin
{

@ -27,7 +27,8 @@ if (!defined('RCMAIL_PLUGINS_DIR'))
/**
* The plugin loader and global API
*
* @package PluginAPI
* @package Framework
* @subpackage PluginAPI
*/
class rcube_plugin_api
{
@ -327,7 +328,7 @@ class rcube_plugin_api
if (isset($this->actions[$action])) {
call_user_func($this->actions[$action]);
}
else {
else if (rcube::get_instance()->action != 'refresh') {
rcube::raise_error(array('code' => 524, 'type' => 'php',
'file' => __FILE__, 'line' => __LINE__,
'message' => "No handler found for action $action"), true, true);

@ -24,6 +24,9 @@
/**
* Class for accessing IMAP's SORT/SEARCH/ESEARCH result
*
* @package Framework
* @subpackage Storage
*/
class rcube_result_index
{

@ -24,7 +24,8 @@
* Roundcube result set class.
* Representing an address directory result set.
*
* @package Addressbook
* @package Framework
* @subpackage Addressbook
*/
class rcube_result_set
{

@ -24,6 +24,9 @@
/**
* Class for accessing IMAP's THREAD result
*
* @package Framework
* @subpackage Storage
*/
class rcube_result_thread
{

@ -24,7 +24,8 @@
/**
* Class to provide database supported session storage
*
* @package Core
* @package Framework
* @subpackage Core
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
*/
@ -43,7 +44,6 @@ class rcube_session
private $secret = '';
private $ip_check = false;
private $logging = false;
private $keep_alive = 0;
private $memcache;
/**
@ -525,24 +525,6 @@ class rcube_session
$this->now = $now - ($now % ($this->lifetime / 2));
}
/**
* Setter for keep_alive interval
*/
public function set_keep_alive($keep_alive)
{
$this->keep_alive = $keep_alive;
if ($this->lifetime < $keep_alive)
$this->set_lifetime($keep_alive + 30);
}
/**
* Getter for keep_alive interval
*/
public function get_keep_alive()
{
return $this->keep_alive;
}
/**
* Getter for remote IP saved with this session
@ -552,6 +534,7 @@ class rcube_session
return $this->ip;
}
/**
* Setter for cookie encryption secret
*/

@ -23,7 +23,8 @@
/**
* Roundcube shared functions
*
* @package Core
* @package Framework
* @subpackage Core
*/

@ -25,7 +25,8 @@ define('SMTP_MIME_CRLF', "\r\n");
/**
* Class to provide SMTP functionality using PEAR Net_SMTP
*
* @package Mail
* @package Framework
* @subpackage Mail
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
*/

@ -25,7 +25,8 @@
/**
* Helper class for spellchecking with Googielspell and PSpell support.
*
* @package Core
* @package Framework
* @subpackage Utils
*/
class rcube_spellchecker
{

@ -25,10 +25,10 @@
/**
* Abstract class for accessing mail messages storage server
*
* @package Mail
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
* @version 2.0
* @package Framework
* @subpackage Storage
* @author Thomas Bruederli <roundcube@gmail.com>
* @author Aleksander Machniak <alec@alec.pl>
*/
abstract class rcube_storage
{

@ -23,7 +23,8 @@
/**
* Helper class for string replacements based on preg_replace_callback
*
* @package Core
* @package Framework
* @subpackage Utils
*/
class rcube_string_replacer
{

@ -5,7 +5,7 @@
| program/include/rcube_user.inc |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2005-2010, The Roundcube Dev Team |
| Copyright (C) 2005-2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -17,6 +17,7 @@
| |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
@ -24,8 +25,8 @@
/**
* Class representing a system user
*
* @package Core
* @author Thomas Bruederli <roundcube@gmail.com>
* @package Framework
* @subpackage Core
*/
class rcube_user
{
@ -47,6 +48,13 @@ class rcube_user
*/
private $rc;
/**
* Internal identities cache
*
* @var array
*/
private $identities = array();
const SEARCH_ADDRESSBOOK = 1;
const SEARCH_MAIL = 2;
@ -213,8 +221,14 @@ class rcube_user
*/
function get_identity($id = null)
{
$result = $this->list_identities($id ? sprintf('AND identity_id = %d', $id) : '');
return $result[0];
$id = (int)$id;
// cache identities for better performance
if (!array_key_exists($id, $this->identities)) {
$result = $this->list_identities($id ? 'AND identity_id = ' . $id : '');
$this->identities[$id] = $result[0];
}
return $this->identities[$id];
}
@ -273,6 +287,8 @@ class rcube_user
call_user_func_array(array($this->db, 'query'),
array_merge(array($sql), $query_params));
$this->identities = array();
return $this->db->affected_rows();
}
@ -305,6 +321,8 @@ class rcube_user
call_user_func_array(array($this->db, 'query'),
array_merge(array($sql), $insert_values));
$this->identities = array();
return $this->db->insert_id('identities');
}
@ -339,6 +357,8 @@ class rcube_user
$this->ID,
$iid);
$this->identities = array();
return $this->db->affected_rows();
}
@ -359,6 +379,8 @@ class rcube_user
" AND del <> 1",
$this->ID,
$iid);
unset($this->identities[0]);
}
}

@ -24,7 +24,8 @@
/**
* Utility class providing common functions
*
* @package Core
* @package Framework
* @subpackage Utils
*/
class rcube_utils
{
@ -761,7 +762,7 @@ class rcube_utils
}
}
$result[] = substr($string, $p);
$result[] = (string) substr($string, $p);
return $result;
}

@ -5,7 +5,7 @@
| program/include/rcube_vcard.php |
| |
| This file is part of the Roundcube Webmail client |
| Copyright (C) 2008-2011, The Roundcube Dev Team |
| Copyright (C) 2008-2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -15,6 +15,7 @@
| Logical representation of a vcard address record |
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
| Author: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
@ -23,8 +24,8 @@
* Logical representation of a vcard-based address record
* Provides functions to parse and export vCard data format
*
* @package Addressbook
* @author Thomas Bruederli <roundcube@gmail.com>
* @package Framework
* @subpackage Addressbook
*/
class rcube_vcard
{
@ -62,7 +63,6 @@ class rcube_vcard
public $middlename;
public $nickname;
public $organization;
public $notes;
public $email = array();
public static $eol = "\r\n";
@ -265,26 +265,25 @@ class rcube_vcard
*/
public function set($field, $value, $type = 'HOME')
{
$field = strtolower($field);
$field = strtolower($field);
$type_uc = strtoupper($type);
$typemap = array_flip($this->typemap);
switch ($field) {
case 'name':
case 'displayname':
$this->raw['FN'][0][0] = $value;
$this->raw['FN'][0][0] = $this->displayname = $value;
break;
case 'surname':
$this->raw['N'][0][0] = $value;
$this->raw['N'][0][0] = $this->surname = $value;
break;
case 'firstname':
$this->raw['N'][0][1] = $value;
$this->raw['N'][0][1] = $this->firstname = $value;
break;
case 'middlename':
$this->raw['N'][0][2] = $value;
$this->raw['N'][0][2] = $this->middlename = $value;
break;
case 'prefix':
@ -296,11 +295,11 @@ class rcube_vcard
break;
case 'nickname':
$this->raw['NICKNAME'][0][0] = $value;
$this->raw['NICKNAME'][0][0] = $this->nickname = $value;
break;
case 'organization':
$this->raw['ORG'][0][0] = $value;
$this->raw['ORG'][0][0] = $this->organization = $value;
break;
case 'photo':
@ -348,8 +347,10 @@ class rcube_vcard
if (($tag = self::$fieldmap[$field]) && (is_array($value) || strlen($value))) {
$index = count($this->raw[$tag]);
$this->raw[$tag][$index] = (array)$value;
if ($type)
if ($type) {
$typemap = array_flip($this->typemap);
$this->raw[$tag][$index]['type'] = explode(',', ($typemap[$type_uc] ? $typemap[$type_uc] : $type));
}
}
break;
}
@ -784,42 +785,9 @@ class rcube_vcard
*/
private static function detect_encoding($string)
{
if (substr($string, 0, 4) == "\0\0\xFE\xFF") return 'UTF-32BE'; // Big Endian
if (substr($string, 0, 4) == "\xFF\xFE\0\0") return 'UTF-32LE'; // Little Endian
if (substr($string, 0, 2) == "\xFE\xFF") return 'UTF-16BE'; // Big Endian
if (substr($string, 0, 2) == "\xFF\xFE") return 'UTF-16LE'; // Little Endian
if (substr($string, 0, 3) == "\xEF\xBB\xBF") return 'UTF-8';
// heuristics
if ($string[0] == "\0" && $string[1] == "\0" && $string[2] == "\0" && $string[3] != "\0") return 'UTF-32BE';
if ($string[0] != "\0" && $string[1] == "\0" && $string[2] == "\0" && $string[3] == "\0") return 'UTF-32LE';
if ($string[0] == "\0" && $string[1] != "\0" && $string[2] == "\0" && $string[3] != "\0") return 'UTF-16BE';
if ($string[0] != "\0" && $string[1] == "\0" && $string[2] != "\0" && $string[3] == "\0") return 'UTF-16LE';
// use mb_detect_encoding()
$encodings = array('UTF-8', 'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3',
'ISO-8859-4', 'ISO-8859-5', 'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9',
'ISO-8859-10', 'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
'WINDOWS-1252', 'WINDOWS-1251', 'BIG5', 'GB2312');
if (function_exists('mb_detect_encoding') && ($enc = mb_detect_encoding($string, $encodings)))
return $enc;
// No match, check for UTF-8
// from http://w3.org/International/questions/qa-forms-utf-8.html
if (preg_match('/\A(
[\x09\x0A\x0D\x20-\x7E]
| [\xC2-\xDF][\x80-\xBF]
| \xE0[\xA0-\xBF][\x80-\xBF]
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
| \xED[\x80-\x9F][\x80-\xBF]
| \xF0[\x90-\xBF][\x80-\xBF]{2}
| [\xF1-\xF3][\x80-\xBF]{3}
| \xF4[\x80-\x8F][\x80-\xBF]{2}
)*\z/xs', substr($string, 0, 2048)))
return 'UTF-8';
return rcube::get_instance()->config->get('default_charset', 'ISO-8859-1'); # fallback to Latin-1
$fallback = rcube::get_instance()->config->get('default_charset', 'ISO-8859-1'); // fallback to Latin-1
return rcube_charset::detect($string, $fallback);
}
}

@ -21,7 +21,6 @@
function rcube_webmail()
{
this.env = { recipients_separator:',', recipients_delimiter:', ' };
this.labels = {};
this.buttons = {};
this.buttons_sel = {};
@ -33,22 +32,24 @@ function rcube_webmail()
this.messages = {};
this.group2expand = {};
// create protected reference to myself
this.ref = 'rcmail';
var ref = this;
// webmail client settings
this.dblclick_time = 500;
this.message_time = 4000;
this.identifier_expr = new RegExp('[^0-9a-z\-_]', 'gi');
// default environment vars
this.env.keep_alive = 60; // seconds
this.env.request_timeout = 180; // seconds
this.env.draft_autosave = 0; // seconds
this.env.comm_path = './';
this.env.blankpage = 'program/resources/blank.gif';
// environment defaults
this.env = {
request_timeout: 180, // seconds
draft_autosave: 0, // seconds
comm_path: './',
blankpage: 'program/resources/blank.gif',
recipients_separator: ',',
recipients_delimiter: ', '
};
// create protected reference to myself
this.ref = 'rcmail';
var ref = this;
// set jQuery ajax options
$.ajaxSetup({
@ -58,6 +59,7 @@ function rcube_webmail()
beforeSend: function(xmlhttp){ xmlhttp.setRequestHeader('X-Roundcube-Request', ref.env.request_token); }
});
// unload fix
$(window).bind('beforeunload', function() { rcmail.unload = true; });
// set environment variable(s)
@ -82,14 +84,15 @@ function rcube_webmail()
// add a button to the button list
this.register_button = function(command, id, type, act, sel, over)
{
if (!this.buttons[command])
this.buttons[command] = [];
var button_prop = {id:id, type:type};
if (act) button_prop.act = act;
if (sel) button_prop.sel = sel;
if (over) button_prop.over = over;
if (!this.buttons[command])
this.buttons[command] = [];
this.buttons[command].push(button_prop);
if (this.loaded)
@ -188,7 +191,6 @@ function rcube_webmail()
this.enable_command('list', 'checkmail', 'add-contact', 'search', 'reset-search', 'collapse-folder', true);
if (this.gui_objects.messagelist) {
this.message_list = new rcube_list_widget(this.gui_objects.messagelist, {
multiselect:true, multiexpand:true, draggable:true, keyboard:true,
column_movable:this.env.col_movable, dblclick_time:this.dblclick_time
@ -215,9 +217,8 @@ function rcube_webmail()
}
if (this.gui_objects.qsearchbox) {
if (this.env.search_text != null) {
if (this.env.search_text != null)
this.gui_objects.qsearchbox.value = this.env.search_text;
}
$(this.gui_objects.qsearchbox).focusin(function() { rcmail.message_list.blur(); });
}
@ -323,7 +324,6 @@ function rcube_webmail()
this.enable_command('list', 'listgroup', 'listsearch', 'advanced-search', true);
if (this.gui_objects.contactslist) {
this.contact_list = new rcube_list_widget(this.gui_objects.contactslist,
{multiselect:true, draggable:this.gui_objects.folderlist?true:false, keyboard:true});
this.contact_list.row_init = function(row){ p.triggerEvent('insertrow', { cid:row.uid, row:row }); };
@ -339,9 +339,8 @@ function rcube_webmail()
this.gui_objects.contactslist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };
document.onmouseup = function(e){ return p.doc_mouse_up(e); };
if (this.gui_objects.qsearchbox) {
if (this.gui_objects.qsearchbox)
$(this.gui_objects.qsearchbox).focusin(function() { rcmail.contact_list.blur(); });
}
this.update_group_commands();
this.command('list');
@ -365,9 +364,8 @@ function rcube_webmail()
this.init_contact_form();
}
if (this.gui_objects.qsearchbox) {
if (this.gui_objects.qsearchbox)
this.enable_command('search', 'reset-search', 'moveto', true);
}
break;
@ -482,7 +480,8 @@ function rcube_webmail()
this.onloads[i]();
}
// start keep-alive interval
// start keep-alive and refresh intervals
this.start_refresh();
this.start_keepalive();
};
@ -507,6 +506,11 @@ function rcube_webmail()
if (this.busy)
return false;
// let the browser handle this click (shift/ctrl usually opens the link in a new window/tab)
if ((obj && obj.href && String(obj.href).indexOf(location.href) < 0) && rcube_event.get_modifier(event)) {
return true;
}
// command not supported or allowed
if (!this.commands[command]) {
// pass command to parent window
@ -562,7 +566,7 @@ function rcube_webmail()
break;
case 'about':
location.href = '?_task=settings&_action=about';
this.redirect('?_task=settings&_action=about', false);
break;
case 'permaurl':
@ -592,7 +596,7 @@ function rcube_webmail()
case 'open':
if (uid = this.get_single_uid()) {
obj.href = '?_task='+this.env.task+'&_action=show&_mbox='+urlencode(this.env.mailbox)+'&_uid='+uid;
obj.href = this.url('show', {_mbox: this.env.mailbox, _uid: uid});
return true;
}
break;
@ -605,9 +609,8 @@ function rcube_webmail()
case 'list':
if (props && props != '')
this.reset_qsearch();
if (this.env.action == 'compose' && this.env.extwin) {
if (this.env.action == 'compose' && this.env.extwin)
window.close();
}
else if (this.task == 'mail') {
this.list_mailbox(props);
this.set_button_titles();
@ -775,9 +778,8 @@ function rcube_webmail()
uid = props._row.uid;
// toggle read/unread
if (this.message_list.rows[uid].deleted) {
if (this.message_list.rows[uid].deleted)
flag = 'undelete';
}
else if (!this.message_list.rows[uid].unread)
flag = 'unread';
}
@ -796,7 +798,7 @@ function rcube_webmail()
// toggle flagged/unflagged
if (this.message_list.rows[uid].flagged)
flag = 'unflagged';
}
}
this.mark_message(flag, uid);
break;
@ -872,7 +874,7 @@ function rcube_webmail()
case 'previousmessage':
if (this.env.prev_uid)
this.show_message(this.env.prev_uid, false, this.env.action=='preview');
this.show_message(this.env.prev_uid, false, this.env.action == 'preview');
break;
case 'firstmessage':
@ -880,10 +882,6 @@ function rcube_webmail()
this.show_message(this.env.first_uid);
break;
case 'checkmail':
this.check_for_recent(true);
break;
case 'compose':
url = {};
@ -952,9 +950,6 @@ function rcube_webmail()
break;
}
// re-set keep-alive timeout
this.start_keepalive();
this.submit_messageform(true);
break;
@ -2064,6 +2059,15 @@ function rcube_webmail()
}
};
// sends request to check for recent messages
this.checkmail = function()
{
var lock = this.set_busy(true, 'checkingmail'),
params = this.check_recent_params();
this.http_request('check-recent', params, lock);
};
// list messages of a specific mailbox using filter
this.filter_mailbox = function(filter)
{
@ -6081,6 +6085,9 @@ function rcube_webmail()
$('<a>').attr('href', url).appendTo(document.body).get(0).click();
else
target.location.href = url;
// reset keep-alive interval
this.start_keepalive();
};
// send a http request to the server
@ -6109,6 +6116,9 @@ function rcube_webmail()
success: function(data){ ref.http_response(data); },
error: function(o, status, err) { ref.http_error(o, status, err, lock, action); }
});
// reset keep-alive interval
this.start_keepalive();
};
// send a http POST request to the server
@ -6126,7 +6136,7 @@ function rcube_webmail()
// trigger plugin hook
var result = this.triggerEvent('request'+action, postdata);
if (result !== undefined) {
// abort if one the handlers returned false
// abort if one of the handlers returned false
if (result === false)
return false;
else
@ -6141,6 +6151,9 @@ function rcube_webmail()
success: function(data){ ref.http_response(data); },
error: function(o, status, err) { ref.http_error(o, status, err, lock, action); }
});
// reset keep-alive interval
this.start_keepalive();
};
// aborts ajax request
@ -6235,6 +6248,7 @@ function rcube_webmail()
}
break;
case 'refresh':
case 'check-recent':
case 'getunread':
case 'search':
@ -6268,6 +6282,9 @@ function rcube_webmail()
this.triggerEvent('responseafter', {response: response});
this.triggerEvent('responseafter'+response.action, {response: response});
// reset keep-alive interval
this.start_keepalive();
};
// handle HTTP request errors
@ -6289,11 +6306,14 @@ function rcube_webmail()
else if (request.status == 0 && status != 'abort')
this.display_message(this.get_label('servererror') + ' (No connection)', 'error');
// redirect to url specified in location header if not empty
var location_url = request.getResponseHeader("Location");
if (location_url)
this.redirect(location_url);
// re-send keep-alive requests after 30 seconds
if (action == 'keep-alive')
setTimeout(function(){ ref.keep_alive(); ref.start_keepalive(); }, 30000);
else if (action == 'check-recent')
setTimeout(function(){ ref.check_for_recent(false); ref.start_keepalive(); }, 30000);
};
// post the given form to a hidden iframe
@ -6463,20 +6483,28 @@ function rcube_webmail()
}
};
// starts interval for keep-alive/check-recent signal
// starts interval for keep-alive signal
this.start_keepalive = function()
{
if (!this.env.keep_alive || this.env.framed)
if (!this.env.session_lifetime || this.env.framed || this.env.extwin || this.task == 'login' || this.env.action == 'print')
return;
if (this._int)
clearInterval(this._int);
if (this._keepalive)
clearInterval(this._keepalive);
if (this.task == 'mail' && this.gui_objects.mailboxlist)
this._int = setInterval(function(){ ref.check_for_recent(false); }, this.env.keep_alive * 1000);
else if (this.task != 'login' && this.env.action != 'print')
this._int = setInterval(function(){ ref.keep_alive(); }, this.env.keep_alive * 1000);
this._keepalive = setInterval(function(){ ref.keep_alive(); }, this.env.session_lifetime * 0.5 * 1000);
};
// starts interval for refresh signal
this.start_refresh = function()
{
if (!this.env.refresh_interval || this.env.framed || this.env.extwin || this.task == 'login' || this.env.action == 'print')
return;
if (this._refresh)
clearInterval(this._refresh);
this._refresh = setInterval(function(){ ref.refresh(); }, this.env.refresh_interval * 1000);
};
// sends keep-alive signal
@ -6486,29 +6514,39 @@ function rcube_webmail()
this.http_request('keep-alive');
};
// sends request to check for recent messages
this.check_for_recent = function(refresh)
// sends refresh signal
this.refresh = function()
{
if (this.busy)
if (this.busy) {
// try again after 10 seconds
setTimeout(function(){ ref.refresh(); ref.start_refresh(); }, 10000);
return;
}
var lock, url = {_mbox: this.env.mailbox};
var params = {}, lock = this.set_busy(true, 'refreshing');
if (refresh) {
lock = this.set_busy(true, 'checkingmail');
url._refresh = 1;
// reset check-recent interval
this.start_keepalive();
}
if (this.task == 'mail' && this.gui_objects.mailboxlist)
params = this.check_recent_params();
// plugins should bind to 'requestrefresh' event to add own params
this.http_request('refresh', params, lock);
};
// returns check-recent request parameters
this.check_recent_params = function()
{
var params = {_mbox: this.env.mailbox};
if (this.gui_objects.mailboxlist)
params._folderlist = 1;
if (this.gui_objects.messagelist)
url._list = 1;
params._list = 1;
if (this.gui_objects.quotadisplay)
url._quota = 1;
params._quota = 1;
if (this.env.search_request)
url._search = this.env.search_request;
params._search = this.env.search_request;
this.http_request('check-recent', url, lock);
return params;
};
@ -6534,7 +6572,8 @@ function rcube_webmail()
{
if (obj.selectionEnd !== undefined)
return obj.selectionEnd;
else if (document.selection && document.selection.createRange) {
if (document.selection && document.selection.createRange) {
var range = document.selection.createRange();
if (range.parentElement() != obj)
return 0;
@ -6548,10 +6587,10 @@ function rcube_webmail()
gm.setEndPoint('EndToStart', range);
var p = gm.text.length;
return p<=obj.value.length ? p : -1;
return p <= obj.value.length ? p : -1;
}
else
return obj.value.length;
return obj.value.length;
};
// moves cursor to specified position

File diff suppressed because one or more lines are too long

@ -102,7 +102,7 @@ class washtml
'cellpadding', 'valign', 'bgcolor', 'color', 'border', 'bordercolorlight',
'bordercolordark', 'face', 'marginwidth', 'marginheight', 'axis', 'border',
'abbr', 'char', 'charoff', 'clear', 'compact', 'coords', 'vspace', 'hspace',
'cellborder', 'size', 'lang', 'dir', 'usemap', 'shape',
'cellborder', 'size', 'lang', 'dir', 'usemap', 'shape', 'media',
// attributes of form elements
'type', 'rows', 'cols', 'disabled', 'readonly', 'checked', 'multiple', 'value'
);

@ -0,0 +1,93 @@
<?php
/*
+-----------------------------------------------------------------------+
| language/en_US/csv2vcard.inc |
| |
| Language file of the Roundcube Webmail client |
| Copyright (C) 2005-2012, 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: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
// This is a list of CSV column names specified in CSV file header
// These must be original texts used in Outlook/Thunderbird exported csv files
// Encoding UTF-8
$map = array();
// MS Outlook 2010
$map['anniversary'] = "Anniversary";
$map['assistants_name'] = "Assistant's Name";
$map['assistants_phone'] = "Assistant's Phone";
$map['birthday'] = "Birthday";
$map['business_city'] = "Business City";
$map['business_countryregion'] = "Business Country/Region";
$map['business_fax'] = "Business Fax";
$map['business_phone'] = "Business Phone";
$map['business_phone_2'] = "Business Phone 2";
$map['business_postal_code'] = "Business Postal Code";
$map['business_state'] = "Business State";
$map['business_street'] = "Business Street";
$map['car_phone'] = "Car Phone";
$map['categories'] = "Categories";
$map['company'] = "Company";
$map['department'] = "Department";
$map['email_address'] = "E-mail Address";
$map['first_name'] = "First Name";
$map['gender'] = "Gender";
$map['home_city'] = "Home City";
$map['home_countryregion'] = "Home Country/Region";
$map['home_fax'] = "Home Fax";
$map['home_phone'] = "Home Phone";
$map['home_phone_2'] = "Home Phone 2";
$map['home_postal_code'] = "Home Postal Code";
$map['home_state'] = "Home State";
$map['home_street'] = "Home Street";
$map['job_title'] = "Job Title";
$map['last_name'] = "Last Name";
$map['managers_name'] = "Manager's Name";
$map['middle_name'] = "Middle Name";
$map['mobile_phone'] = "Mobile Phone";
$map['notes'] = "Notes";
$map['other_city'] = "Other City";
$map['other_countryregion'] = "Other Country/Region";
$map['other_fax'] = "Other Fax";
$map['other_phone'] = "Other Phone";
$map['other_postal_code'] = "Other Postal Code";
$map['other_state'] = "Other State";
$map['other_street'] = "Other Street";
$map['pager'] = "Pager";
$map['primary_phone'] = "Primary Phone";
$map['spouse'] = "Spouse";
$map['suffix'] = "Suffix";
$map['title'] = "Title";
$map['web_page'] = "Web Page";
// Thunderbird
$map['birth_day'] = "Birth Day";
$map['birth_month'] = "Birth Month";
$map['birth_year'] = "Birth Year";
$map['display_name'] = "Display Name";
$map['fax_number'] = "Fax Number";
$map['home_address'] = "Home Address";
$map['home_country'] = "Home Country";
$map['home_zipcode'] = "Home ZipCode";
$map['mobile_number'] = "Mobile Number";
$map['nickname'] = "Nickname";
$map['organization'] = "Organization";
$map['pager_number'] = "Pager Namber";
$map['primary_email'] = "Primary Email";
$map['secondary_email'] = "Secondary Email";
$map['web_page_1'] = "Web Page 1";
$map['web_page_2'] = "Web Page 2";
$map['work_phone'] = "Work Phone";
$map['work_address'] = "Work Address";
$map['work_country'] = "Work Country";
$map['work_zipcode'] = "Work ZipCode";

@ -354,7 +354,7 @@ $labels['importcontacts'] = 'Import contacts';
$labels['importfromfile'] = 'Import from file:';
$labels['importtarget'] = 'Add new contacts to address book:';
$labels['importreplace'] = 'Replace the entire address book';
$labels['importtext'] = '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> data format.';
$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['done'] = 'Done';
// settings
@ -414,7 +414,7 @@ $labels['always'] = 'always';
$labels['showinlineimages'] = 'Display attached images below the message';
$labels['autosavedraft'] = 'Automatically save draft';
$labels['everynminutes'] = 'every $n minute(s)';
$labels['keepalive'] = 'Check for new messages on';
$labels['refreshinterval'] = 'Refresh (check for new messages, etc.)';
$labels['never'] = 'never';
$labels['immediately'] = 'immediately';
$labels['messagesdisplaying'] = 'Displaying Messages';

@ -1,12 +1,11 @@
<?php
/*
+-----------------------------------------------------------------------+
| language/en_US/messages.inc |
| |
| Language file of the Roundcube Webmail client |
| Copyright (C) 2005-2010, The Roundcube Dev Team |
| Copyright (C) 2005-2012, The Roundcube Dev Team |
| |
| Licensed under the GNU General Public License version 3 or |
| any later version with exceptions for skins & plugins. |
@ -15,9 +14,6 @@
+-----------------------------------------------------------------------+
| Author: Thomas Bruederli <roundcube@gmail.com> |
+-----------------------------------------------------------------------+
@version $Id$
*/
$messages = array();
@ -37,6 +33,7 @@ $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...';
@ -124,7 +121,7 @@ $messages['contactaddedtogroup'] = 'Successfully added the contacts to this grou
$messages['contactremovedfromgroup'] = 'Successfully removed contacts from this group.';
$messages['nogroupassignmentschanged'] = 'No group assignments changed.';
$messages['importwait'] = 'Importing, please wait...';
$messages['importerror'] = 'Import failed! The uploaded file is not a valid vCard file.';
$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['opnotpermitted'] = 'Operation not permitted!';

@ -0,0 +1,62 @@
<?php
/*
+-----------------------------------------------------------------------+
| language/pl_PL/csv2vcard.inc |
| |
| Language file of the Roundcube Webmail client |
| Copyright (C) 2005-2012, 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: Aleksander Machniak <alec@alec.pl> |
+-----------------------------------------------------------------------+
*/
// This is a list of CSV column names specified in CSV file header
// These must be original texts used in Outlook/Thunderbird exported csv files
// Encoding UTF-8
$map = array();
// MS Outlook 2010
$map['anniversary'] = "Rocznica";
$map['assistants_name'] = "Asystent";
$map['assistants_phone'] = "Telefon asystenta";
$map['birthday'] = "Urodziny";
$map['business_city'] = "Miasto (biuro)";
$map['business_countryregion'] = "Kraj/region (biuro)";
$map['business_fax'] = "Faks służbowy";
$map['business_phone'] = "Telefon służbowy";
$map['business_phone_2'] = "Telefon służbowy 2";
$map['business_postal_code'] = "Kod pocztowy (biuro)";
$map['business_state'] = "Województwo (biuro)";
$map['business_street'] = "Ulica (biuro)";
$map['categories'] = "Kategorie";
$map['company'] = "Firma";
$map['department'] = "Oddział";
$map['email_address'] = "Adres e-mail";
$map['first_name'] = "Imię";
$map['gender'] = "Płeć";
$map['home_city'] = "Miasto (dom)";
$map['home_countryregion'] = "Kraj/region (dom)";
$map['home_fax'] = "Faks domowy";
$map['home_phone'] = "Telefon domowy";
$map['home_phone_2'] = "Home Phone 2";
$map['home_postal_code'] = "Kod pocztowy (dom)";
$map['home_state'] = "Województwo (dom)";
$map['home_street'] = "Ulica (dom)";
$map['job_title'] = "Stanowisko";
$map['last_name'] = "Nazwisko";
$map['managers_name'] = "Menadżer";
$map['middle_name'] = "Drugie imię";
$map['mobile_phone'] = "Telefon komórkowy";
$map['notes'] = "Notatki";
$map['pager'] = "Pager";
$map['primary_phone'] = "Telefon główny";
$map['title'] = "Tytuł";
$map['web_page'] = "Osobista strona sieci Web";
$map['nickname'] = "Przydomek";

@ -64,7 +64,7 @@ function rcmail_import_form($attrib)
$OUTPUT->add_label('selectimportfile','importwait');
$OUTPUT->add_gui_object('importform', $attrib['id']);
$out = html::p(null, Q(rcube_label('importtext'), 'show'));
$out = html::p(null, Q(rcube_label('importdesc'), 'show'));
$out .= $OUTPUT->form_tag(array(
'action' => $RCMAIL->url('import'),
@ -159,11 +159,22 @@ if (is_array($_FILES['_file'])) {
$upload_error = $err;
}
else {
$file_content = file_get_contents($filepath);
// let rcube_vcard do the hard work :-)
$vcard_o = new rcube_vcard();
$vcard_o->extend_fieldmap($CONTACTS->vcard_map);
$v_list = $vcard_o->import($file_content);
if (!empty($v_list)) {
$vcards = array_merge($vcards, $v_list);
continue;
}
$v_list = $vcard_o->import(file_get_contents($filepath));
// no vCards found, try CSV
$csv = new rcube_csv2vcard($_SESSION['language']);
$csv->import($file_content);
$v_list = $csv->export();
if (!empty($v_list)) {
$vcards = array_merge($vcards, $v_list);
@ -181,7 +192,7 @@ if (is_array($_FILES['_file'])) {
$OUTPUT->show_message('fileuploaderror', 'error');
}
else {
$OUTPUT->show_message('importerror', 'error');
$OUTPUT->show_message('importformaterror', 'error');
}
}
else {

@ -19,8 +19,14 @@
+-----------------------------------------------------------------------+
*/
// If there's no folder or messages list, there's nothing to update
// This can happen on 'refresh' request
if (empty($_REQUEST['_folderlist']) && empty($_REQUEST['_list'])) {
return;
}
$current = $RCMAIL->storage->get_folder();
$check_all = !empty($_GET['_refresh']) || (bool)$RCMAIL->config->get('check_all_folders');
$check_all = $RCMAIL->action != 'refresh' || (bool)$RCMAIL->config->get('check_all_folders');
// list of folders to check
if ($check_all) {
@ -102,6 +108,4 @@ foreach ($a_mailboxes as $mbox_name) {
}
}
$RCMAIL->plugins->exec_hook('keep_alive', array());
$OUTPUT->send();

@ -611,13 +611,13 @@ function rcmail_compose_editor_mode()
$useHtml = !empty($_POST['_is_html']);
}
else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) {
$useHtml = $MESSAGE->has_html_part(false);
$useHtml = $MESSAGE->has_html_part(false, true);
}
else if ($compose_mode == RCUBE_COMPOSE_REPLY) {
$useHtml = ($html_editor == 1 || ($html_editor >= 2 && $MESSAGE->has_html_part(false)));
$useHtml = ($html_editor == 1 || ($html_editor >= 2 && $MESSAGE->has_html_part(false, true)));
}
else if ($compose_mode == RCUBE_COMPOSE_FORWARD) {
$useHtml = ($html_editor == 1 || ($html_editor == 3 && $MESSAGE->has_html_part(false)));
$useHtml = ($html_editor == 1 || ($html_editor == 3 && $MESSAGE->has_html_part(false, true)));
}
else {
$useHtml = ($html_editor == 1);
@ -730,6 +730,10 @@ function rcmail_compose_part_body($part, $isHtml = false)
if ($isHtml) {
if ($part->ctype_secondary == 'html') {
}
else if ($part->ctype_secondary == 'enriched') {
require_once(INSTALL_PATH . 'program/lib/enriched.inc');
$body = enriched_to_html($body);
}
else {
// try to remove the signature
if ($RCMAIL->config->get('strip_existing_sig', true)) {
@ -743,6 +747,12 @@ function rcmail_compose_part_body($part, $isHtml = false)
}
}
else {
if ($part->ctype_secondary == 'enriched') {
require_once(INSTALL_PATH . 'program/lib/enriched.inc');
$body = enriched_to_html($body);
$part->ctype_secondary = 'html';
}
if ($part->ctype_secondary == 'html') {
// use html part if it has been used for message (pre)viewing
// decrease line length for quoting
@ -750,6 +760,10 @@ function rcmail_compose_part_body($part, $isHtml = false)
$txt = new html2text($body, false, true, $len);
$body = $txt->get_text();
}
else if ($part->ctype_secondary == 'enriched') {
require_once(INSTALL_PATH . 'program/lib/enriched.inc');
$body = enriched_to_html($body);
}
else {
if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') {
$body = rcube_mime::unfold_flowed($body);

@ -751,9 +751,10 @@ function rcmail_print_body($part, $p = array())
}
// text/enriched
else if ($data['type'] == 'enriched') {
$part->ctype_secondary = 'html';
require_once(INSTALL_PATH . 'program/lib/enriched.inc');
$body = Q(enriched_to_html($data['body']), 'show');
$body = enriched_to_html($data['body']);
$body = rcmail_wash_html($body, $data, $part->replaces);
$part->ctype_secondary = 'html';
}
else {
// assert plaintext
@ -1845,6 +1846,7 @@ $OUTPUT->add_handlers(array(
// register action aliases
$RCMAIL->register_action_map(array(
'refresh' => 'check_recent.inc',
'preview' => 'show.inc',
'print' => 'show.inc',
'moveto' => 'move_del.inc',

@ -237,6 +237,24 @@ function rcmail_user_prefs($current=null)
);
}
if (!isset($no_override['refresh_interval'])) {
$field_id = 'rcmfd_refresh_interval';
$select_refresh_interval = new html_select(array('name' => '_refresh_interval', 'id' => $field_id));
$select_refresh_interval->add(rcube_label('never'), 0);
foreach (array(1, 3, 5, 10, 15, 30, 60) as $min) {
if (!$config['min_refresh_interval'] || $config['min_refresh_interval'] <= $min * 60) {
$label = rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min)));
$select_refresh_interval->add($label, $min);
}
}
$blocks['main']['options']['refresh_interval'] = array(
'title' => html::label($field_id, Q(rcube_label('refreshinterval'))),
'content' => $select_refresh_interval->show($config['refresh_interval']/60),
);
}
// show drop-down for available skins
if (!isset($no_override['skin'])) {
$skins = rcmail_get_skins();
@ -370,23 +388,6 @@ function rcmail_user_prefs($current=null)
'content' => $input_pagesize->show($size ? $size : 50),
);
}
if (!isset($no_override['keep_alive'])) {
$field_id = 'rcmfd_keep_alive';
$select_keep_alive = new html_select(array('name' => '_keep_alive', 'id' => $field_id));
foreach(array(1, 3, 5, 10, 15, 30, 60) as $min)
if((!$config['min_keep_alive'] || $config['min_keep_alive'] <= $min * 60)
&& (!$config['session_lifetime'] || $config['session_lifetime'] > $min)) {
$select_keep_alive->add(rcube_label(array('name' => 'everynminutes', 'vars' => array('n' => $min))), $min);
}
$blocks['new_message']['options']['keep_alive'] = array(
'title' => html::label($field_id, Q(rcube_label('keepalive'))),
'content' => $select_keep_alive->show($config['keep_alive']/60),
);
}
if (!isset($no_override['check_all_folders'])) {
$field_id = 'rcmfd_check_all_folders';
$input_check_all = new html_checkbox(array('name' => '_check_all_folders', 'id' => $field_id, 'value' => 1));

@ -33,7 +33,8 @@ switch ($CURR_SECTION)
'date_format' => isset($_POST['_date_format']) ? get_input_value('_date_format', RCUBE_INPUT_POST) : $CONFIG['date_format'],
'time_format' => isset($_POST['_time_format']) ? get_input_value('_time_format', RCUBE_INPUT_POST) : ($CONFIG['time_format'] ? $CONFIG['time_format'] : 'H:i'),
'prettydate' => isset($_POST['_pretty_date']) ? TRUE : FALSE,
'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
'refresh_interval' => isset($_POST['_refresh_interval']) ? intval($_POST['_refresh_interval'])*60 : $CONFIG['refresh_interval'],
'skin' => isset($_POST['_skin']) ? get_input_value('_skin', RCUBE_INPUT_POST) : $CONFIG['skin'],
);
// compose derived date/time format strings
@ -50,7 +51,6 @@ switch ($CURR_SECTION)
'preview_pane_mark_read' => isset($_POST['_preview_pane_mark_read']) ? intval($_POST['_preview_pane_mark_read']) : $CONFIG['preview_pane_mark_read'],
'autoexpand_threads' => isset($_POST['_autoexpand_threads']) ? intval($_POST['_autoexpand_threads']) : 0,
'mdn_requests' => isset($_POST['_mdn_requests']) ? intval($_POST['_mdn_requests']) : 0,
'keep_alive' => isset($_POST['_keep_alive']) ? intval($_POST['_keep_alive'])*60 : $CONFIG['keep_alive'],
'check_all_folders' => isset($_POST['_check_all_folders']) ? TRUE : FALSE,
'mail_pagesize' => is_numeric($_POST['_mail_pagesize']) ? max(2, intval($_POST['_mail_pagesize'])) : $CONFIG['mail_pagesize'],
);
@ -157,16 +157,16 @@ switch ($CURR_SECTION)
$a_user_prefs['timezone'] = (string) $a_user_prefs['timezone'];
break;
case 'mailbox':
// force keep_alive
if (isset($a_user_prefs['keep_alive'])) {
$a_user_prefs['keep_alive'] = max(60, $CONFIG['min_keep_alive'], $a_user_prefs['keep_alive']);
if (!empty($CONFIG['session_lifetime']))
$a_user_prefs['keep_alive'] = min($CONFIG['session_lifetime']*60, $a_user_prefs['keep_alive']);
if (isset($a_user_prefs['refresh_interval']) && !empty($CONFIG['min_refresh_interval'])) {
if ($a_user_prefs['refresh_interval'] > $CONFIG['min_refresh_interval']) {
$a_user_prefs['refresh_interval'] = $CONFIG['min_refresh_interval'];
}
}
break;
case 'mailbox':
// force min size
if ($a_user_prefs['mail_pagesize'] < 1)
$a_user_prefs['mail_pagesize'] = 10;
@ -174,7 +174,8 @@ switch ($CURR_SECTION)
if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['mail_pagesize'] > $CONFIG['max_pagesize']))
$a_user_prefs['mail_pagesize'] = (int) $CONFIG['max_pagesize'];
break;
break;
case 'addressbook':
// force min size
@ -184,7 +185,8 @@ switch ($CURR_SECTION)
if (isset($CONFIG['max_pagesize']) && ($a_user_prefs['addressbook_pagesize'] > $CONFIG['max_pagesize']))
$a_user_prefs['addressbook_pagesize'] = (int) $CONFIG['max_pagesize'];
break;
break;
case 'folders':
// special handling for 'default_folders'
@ -199,7 +201,7 @@ switch ($CURR_SECTION)
}
}
break;
break;
}
// Save preferences

@ -0,0 +1,57 @@
<?php
/**
* Test class to test rcube_csv2vcard class
*
* @package Tests
*/
class Framework_Csv2vcard extends PHPUnit_Framework_TestCase
{
function test_import_generic()
{
$csv = new rcube_csv2vcard;
// empty input
$csv->import('');
$this->assertSame(array(), $csv->export());
}
function test_import_tb_plain()
{
$csv_text = file_get_contents(TESTS_DIR . '/src/Csv2vcard/tb_plain.csv');
$vcf_text = file_get_contents(TESTS_DIR . '/src/Csv2vcard/tb_plain.vcf');
$csv = new rcube_csv2vcard;
$csv->import($csv_text);
$result = $csv->export();
$vcard = $result[0]->export(false);
$this->assertCount(1, $result);
$vcf_text = trim(str_replace("\r\n", "\n", $vcf_text));
$vcard = trim(str_replace("\r\n", "\n", $vcard));
$this->assertEquals($vcf_text, $vcard);
}
function test_import_email()
{
$csv_text = file_get_contents(TESTS_DIR . '/src/Csv2vcard/email.csv');
$vcf_text = file_get_contents(TESTS_DIR . '/src/Csv2vcard/email.vcf');
$csv = new rcube_csv2vcard;
$csv->import($csv_text);
$result = $csv->export();
$this->assertCount(4, $result);
$vcard = '';
foreach ($result as $vcf) {
$vcard .= $vcf->export(false) . "\n";
}
$vcf_text = trim(str_replace("\r\n", "\n", $vcf_text));
$vcard = trim(str_replace("\r\n", "\n", $vcard));
$this->assertEquals($vcf_text, $vcard);
}
}

@ -193,4 +193,17 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
$mod = rcube_utils::mod_css_styles("background:\\0075\\0072\\006c( javascript:alert(&#039;xss&#039;) )", 'rcmbody');
$this->assertEquals("/* evil! */", $mod, "Don't allow encoding quirks (2)");
}
/**
* Check rcube_utils::explode_quoted_string() compat. with explode()
*/
function test_explode_quoted_string_compat()
{
$data = array('', 'a,b,c', 'a', ',', ',a');
foreach ($data as $text) {
$result = rcube_utils::explode_quoted_string(',', $text);
$this->assertSame(explode(',', $text), $result);
}
}
}

@ -8,6 +8,7 @@
<file>Framework/Cache.php</file>
<file>Framework/Charset.php</file>
<file>Framework/ContentFilter.php</file>
<file>Framework/Csv2vcard.php</file>
<file>Framework/Html.php</file>
<file>Framework/Imap.php</file>
<file>Framework/ImapGeneric.php</file>

@ -0,0 +1,5 @@
Primary Email
test1@domain.tld
test2@domain.tld
test3@domain.tld
test4@domain.tld
1 Primary Email
2 test1@domain.tld
3 test2@domain.tld
4 test3@domain.tld
5 test4@domain.tld

@ -0,0 +1,20 @@
BEGIN:VCARD
VERSION:3.0
FN:test1@domain.tld
EMAIL;TYPE=INTERNET;TYPE=PREF:test1@domain.tld
END:VCARD
BEGIN:VCARD
VERSION:3.0
FN:test2@domain.tld
EMAIL;TYPE=INTERNET;TYPE=PREF:test2@domain.tld
END:VCARD
BEGIN:VCARD
VERSION:3.0
FN:test3@domain.tld
EMAIL;TYPE=INTERNET;TYPE=PREF:test3@domain.tld
END:VCARD
BEGIN:VCARD
VERSION:3.0
FN:test4@domain.tld
EMAIL;TYPE=INTERNET;TYPE=PREF:test4@domain.tld
END:VCARD

@ -0,0 +1,2 @@
First Name,Last Name,Display Name,Nickname,Primary Email,Secondary Email,Screen Name,Work Phone,Home Phone,Fax Number,Pager Number,Mobile Number,Home Address,Home Address 2,Home City,Home State,Home ZipCode,Home Country,Work Address,Work Address 2,Work City,Work State,Work ZipCode,Work Country,Job Title,Department,Organization,Web Page 1,Web Page 2,Birth Year,Birth Month,Birth Day,Custom 1,Custom 2,Custom 3,Custom 4,Notes,
Firstname,Lastname,Displayname,Nick,test@domain.tld,next@domain.tld,,phone work,phone home,fax,pager,mobile,Priv address,,City,region,xx-xxx,USA,Addr work,,city,region,33-333,Poland,title,department,Organization,http://page.com,http://webpage.tld,1970,11,15,,,,,,
1 First Name Last Name Display Name Nickname Primary Email Secondary Email Screen Name Work Phone Home Phone Fax Number Pager Number Mobile Number Home Address Home Address 2 Home City Home State Home ZipCode Home Country Work Address Work Address 2 Work City Work State Work ZipCode Work Country Job Title Department Organization Web Page 1 Web Page 2 Birth Year Birth Month Birth Day Custom 1 Custom 2 Custom 3 Custom 4 Notes
2 Firstname Lastname Displayname Nick test@domain.tld next@domain.tld phone work phone home fax pager mobile Priv address City region xx-xxx USA Addr work city region 33-333 Poland title department Organization http://page.com http://webpage.tld 1970 11 15

@ -0,0 +1,18 @@
BEGIN:VCARD
VERSION:3.0
FN:Displayname
N:Lastname;Firstname;;;
NICKNAME:Nick
EMAIL;TYPE=INTERNET;TYPE=PREF:test@domain.tld
EMAIL;TYPE=INTERNET;TYPE=OTHER:next@domain.tld
TEL;TYPE=work:phone work
TEL;TYPE=home:phone home
TEL;TYPE=fax:fax
TEL;TYPE=cell:mobile
TITLE:title
X-DEPARTMENT:department
ORG:Organization
URL;TYPE=homepage:http://page.com
URL;TYPE=other:http://webpage.tld
BDAY;VALUE=date:1970-11-15
END:VCARD
Loading…
Cancel
Save