summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--program/js/list.js4
-rw-r--r--program/lib/Roundcube/rcube_utils.php79
-rw-r--r--program/steps/addressbook/save.inc4
-rw-r--r--tests/Framework/Utils.php26
5 files changed, 81 insertions, 33 deletions
diff --git a/CHANGELOG b/CHANGELOG
index fb7fd87da..874308539 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
+- Fix an issue where shift + arrow-up key wasn't selecting all messages in collapsed thread (#1489397)
- Added icon for priority column in messages list header (#1489234)
- New feature "Canned Responses" to save and recall boilerplate text snippets
- Fix HTML part detection when encapsulated inside multipart/signed (#1489372)
diff --git a/program/js/list.js b/program/js/list.js
index 0b6f416e3..8843cd94a 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -912,7 +912,8 @@ shift_select: function(id, control)
from_rowIndex = this._rowIndex(this.rows[this.shift_start].obj),
to_rowIndex = this._rowIndex(to_row.obj);
- if (!to_row.expanded && to_row.has_children)
+ // if we're going down the list, and we hit a thread, and it's closed, select the whole thread
+ if (from_rowIndex < to_rowIndex && !to_row.expanded && to_row.has_children)
if (to_row = this.rows[(this.row_children(id)).pop()])
to_rowIndex = this._rowIndex(to_row.obj);
@@ -934,6 +935,7 @@ shift_select: function(id, control)
}
},
+
/**
* Helper method to emulate the rowIndex property of non-tr elements
*/
diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
index 174fe398c..27a618d83 100644
--- a/program/lib/Roundcube/rcube_utils.php
+++ b/program/lib/Roundcube/rcube_utils.php
@@ -747,40 +747,13 @@ class rcube_utils
*/
public static function strtotime($date)
{
- $date = trim($date);
-
- // check for MS Outlook vCard date format YYYYMMDD
- if (preg_match('/^([12][90]\d\d)([01]\d)([0123]\d)$/', $date, $m)) {
- return mktime(0,0,0, intval($m[2]), intval($m[3]), intval($m[1]));
- }
-
- // common little-endian formats, e.g. dd/mm/yyyy (not all are supported by strtotime)
- if (preg_match('/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{4})$/', $date, $m)
- && $m[1] > 0 && $m[1] <= 31 && $m[2] > 0 && $m[2] <= 12 && $m[3] >= 1970
- ) {
- return mktime(0,0,0, intval($m[2]), intval($m[1]), intval($m[3]));
- }
+ $date = self::clean_datestr($date);
// unix timestamp
if (is_numeric($date)) {
return (int) $date;
}
- // Clean malformed data
- $date = preg_replace(
- array(
- '/GMT\s*([+-][0-9]+)/', // support non-standard "GMTXXXX" literal
- '/[^a-z0-9\x20\x09:+-]/i', // remove any invalid characters
- '/\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*/i', // remove weekday names
- ),
- array(
- '\\1',
- '',
- '',
- ), $date);
-
- $date = trim($date);
-
// if date parsing fails, we have a date in non-rfc format.
// remove token from the end and try again
while ((($ts = @strtotime($date)) === false) || ($ts < 0)) {
@@ -808,8 +781,8 @@ class rcube_utils
return $date;
}
- $dt = false;
- $date = trim($date);
+ $dt = false;
+ $date = self::clean_datestr($date);
// try to parse string with DateTime first
if (!empty($date)) {
@@ -834,6 +807,52 @@ class rcube_utils
return $dt;
}
+ /**
+ * Clean up date string for strtotime() input
+ *
+ * @param string $date Date string
+ *
+ * @return string Date string
+ */
+ public static function clean_datestr($date)
+ {
+ $date = trim($date);
+
+ // check for MS Outlook vCard date format YYYYMMDD
+ if (preg_match('/^([12][90]\d\d)([01]\d)([0123]\d)$/', $date, $m)) {
+ return sprintf('%04d-%02d-%02d 00:00:00', intval($m[1]), intval($m[2]), intval($m[3]));
+ }
+
+ // Clean malformed data
+ $date = preg_replace(
+ array(
+ '/GMT\s*([+-][0-9]+)/', // support non-standard "GMTXXXX" literal
+ '/[^a-z0-9\x20\x09:+-\/]/i', // remove any invalid characters
+ '/\s*(Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s*/i', // remove weekday names
+ ),
+ array(
+ '\\1',
+ '',
+ '',
+ ), $date);
+
+ $date = trim($date);
+
+ // try to fix dd/mm vs. mm/dd discrepancy, we can't do more here
+ if (preg_match('/^(\d{1,2})[.\/-](\d{1,2})[.\/-](\d{4})$/', $date, $m)) {
+ $mdy = $m[2] > 12 && $m[1] <= 12;
+ $day = $mdy ? $m[2] : $m[1];
+ $month = $mdy ? $m[1] : $m[2];
+ $date = sprintf('%04d-%02d-%02d 00:00:00', intval($m[3]), $month, $day);
+ }
+ // I've found that YYYY.MM.DD is recognized wrong, so here's a fix
+ else if (preg_match('/^(\d{4})\.(\d{1,2})\.(\d{1,2})$/', $date)) {
+ $date = str_replace('.', '-', $date) . ' 00:00:00';
+ }
+
+ return $date;
+ }
+
/*
* Idn_to_ascii wrapper.
* Intl/Idn modules version of this function doesn't work with e-mail address
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 2adc53bcf..7911802b9 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -80,8 +80,8 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) {
// normalize the submitted date strings
if ($colprop['type'] == 'date') {
- if ($timestamp = rcube_utils::strtotime($a_record[$col])) {
- $a_record[$col] = date('Y-m-d', $timestamp);
+ if ($a_record[$col] && ($dt = rcube_utils::anytodatetime($a_record[$col]))) {
+ $a_record[$col] = $dt->format('Y-m-d');
}
else {
unset($a_record[$col]);
diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php
index 2f4aec32e..1f1e57b0e 100644
--- a/tests/Framework/Utils.php
+++ b/tests/Framework/Utils.php
@@ -294,6 +294,32 @@ class Framework_Utils extends PHPUnit_Framework_TestCase
}
/**
+ * rcube:utils::anytodatetime()
+ */
+ function test_anytodatetime()
+ {
+ $test = array(
+ '2013-04-22' => '2013-04-22',
+ '2013/04/22' => '2013-04-22',
+ '2013.04.22' => '2013-04-22',
+ '22-04-2013' => '2013-04-22',
+ '22/04/2013' => '2013-04-22',
+ '22.04.2013' => '2013-04-22',
+ '04/22/2013' => '2013-04-22',
+ '22.4.2013' => '2013-04-22',
+ '20130422' => '2013-04-22',
+ '1900-10-10' => '1900-10-10',
+ '01-01-1900' => '1900-01-01',
+ '01/30/1960' => '1960-01-30'
+ );
+
+ foreach ($test as $datetime => $ts) {
+ $result = rcube_utils::anytodatetime($datetime);
+ $this->assertSame($ts, $result ? $result->format('Y-m-d') : '', "Error parsing date: $datetime");
+ }
+ }
+
+ /**
* rcube:utils::normalize _string()
*/
function test_normalize_string()