From ed35267b9bd2ad1de2ea970368665d2424e2c8c9 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Fri, 29 Jul 2016 05:42:18 -0400 Subject: [PATCH] Managesieve: Fix parsing of vacation date-time with non-default date_format (#5372) Added new method rcube_utils::format_datestr() to convert date_format date into ISO date format. --- CHANGELOG | 1 + .../lib/Roundcube/rcube_sieve_vacation.php | 4 +- program/lib/Roundcube/rcube_utils.php | 41 +++++++++++++++++-- tests/Framework/Utils.php | 18 ++++++++ 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 5dcbd5360..eca3274f8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -26,6 +26,7 @@ CHANGELOG Roundcube Webmail - Managesieve: Display warning message when filter form contains errors - Enigma: Add possibility to configure gpg-agent binary location (enigma_pgp_agent) - Fix regression in resizing JPEG images with Imagick (#5376) +- Managesieve: Fix parsing of vacation date-time with non-default date_format (#5372) RELEASE 1.2.1 ------------- diff --git a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php index 932aaaafe..874110534 100644 --- a/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php +++ b/plugins/managesieve/lib/Roundcube/rcube_sieve_vacation.php @@ -239,9 +239,11 @@ class rcube_sieve_vacation extends rcube_sieve_engine } if ($date_extension) { + $date_format = $this->rc->config->get('date_format', 'Y-m-d'); foreach (array('date_from', 'date_to') as $var) { $time = ${str_replace('date', 'time', $var)}; - $date = trim($$var . ' ' . $time); + $date = rcube_utils::format_datestr($$var, $date_format); + $date = trim($date . ' ' . $time); if ($date && ($dt = rcube_utils::anytodatetime($date, $timezone))) { if ($time) { diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php index 0aae68ad9..dfd9c855f 100644 --- a/program/lib/Roundcube/rcube_utils.php +++ b/program/lib/Roundcube/rcube_utils.php @@ -758,6 +758,7 @@ class rcube_utils $dt = $timezone ? new DateTime($date, $timezone) : new DateTime($date); } catch (Exception $e) { + rcube::raise_error($e, true, false); // ignore } } @@ -810,15 +811,47 @@ class rcube_utils $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)) { + 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); + $date = sprintf('%04d-%02d-%02d%s', intval($m[3]), $month, $day, $m[4] ?: '00:00:00'); } // 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'; + else if (preg_match('/^(\d{4})\.(\d{1,2})\.(\d{1,2})(.*)$/', $date)) { + $date = str_replace('.', '-', $date) . ($m[4] ?: '00:00:00'); + } + + return $date; + } + + /** + * Turns the given date-only string in defined format into YYYY-MM-DD format. + * + * Supported formats: 'Y/m/d', 'Y.m.d', 'd-m-Y', 'd/m/Y', 'd.m.Y', 'j.n.Y' + * + * @param string $date Date string + * @param string $format Input date format + * + * @return strin Date string in YYYY-MM-DD format, or the original string + * if format is not supported + */ + public static function format_datestr($date, $format) + { + $format_items = preg_split('/[.-\/\\\\]/', $format); + $date_items = preg_split('/[.-\/\\\\]/', $date); + $iso_format = '%04d-%02d-%02d'; + + if (count($format_items) == 3 && count($date_items) == 3) { + if ($format_items[0] == 'Y') { + $date = sprintf($iso_format, $date_items[0], $date_items[1], $date_items[2]); + } + else if (strpos('dj', $format_items[0]) !== false) { + $date = sprintf($iso_format, $date_items[2], $date_items[1], $date_items[0]); + } + else if (strpos('mn', $format_items[0]) !== false) { + $date = sprintf($iso_format, $date_items[2], $date_items[0], $date_items[1]); + } } return $date; diff --git a/tests/Framework/Utils.php b/tests/Framework/Utils.php index 08e641440..f0c248aa1 100644 --- a/tests/Framework/Utils.php +++ b/tests/Framework/Utils.php @@ -351,6 +351,24 @@ class Framework_Utils extends PHPUnit_Framework_TestCase } } + /** + * rcube:utils::format_datestr() + */ + function test_format_datestr() + { + $test = array( + array('abc-555', 'abc', 'abc-555'), + array('2013-04-22', 'Y-m-d', '2013-04-22'), + array('22/04/2013', 'd/m/Y', '2013-04-22'), + array('4.22.2013', 'm.d.Y', '2013-04-22'), + ); + + foreach ($test as $data) { + $result = rcube_utils::format_datestr($data[0], $data[1]); + $this->assertSame($data[2], $result, "Error formatting date: " . $data[0]); + } + } + /** * rcube:utils::tokenize_string() */