summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Bruederli <thomas@roundcube.net>2013-09-10 23:37:10 +0200
committerThomas Bruederli <thomas@roundcube.net>2013-09-10 23:37:10 +0200
commit52830ea6056dc85d8ffcb0cfb7ead7d70624e109 (patch)
tree3bfd0de172752bcf87430c5fe248e69a89a1f965
parent6128ad7e962a8f9bf82a1ef87e4efbe36d719d92 (diff)
Improve handling of date strings and DateTime values in contacts
-rw-r--r--program/lib/Roundcube/rcube_addressbook.php6
-rw-r--r--program/lib/Roundcube/rcube_contacts.php4
-rw-r--r--program/lib/Roundcube/rcube_utils.php38
-rw-r--r--program/lib/Roundcube/rcube_vcard.php4
-rw-r--r--program/steps/addressbook/save.inc10
5 files changed, 57 insertions, 5 deletions
diff --git a/program/lib/Roundcube/rcube_addressbook.php b/program/lib/Roundcube/rcube_addressbook.php
index c8cf2d290..9301211ff 100644
--- a/program/lib/Roundcube/rcube_addressbook.php
+++ b/program/lib/Roundcube/rcube_addressbook.php
@@ -563,9 +563,9 @@ abstract class rcube_addressbook
// use only strict comparison (mode = 1)
// @TODO: partial search, e.g. match only day and month
if (in_array($colname, $this->date_cols)) {
- return (($value = rcube_utils::strtotime($value))
- && ($search = rcube_utils::strtotime($search))
- && date('Ymd', $value) == date('Ymd', $search));
+ return (($value = rcube_utils::anytodatetime($value))
+ && ($search = rcube_utils::anytodatetime($search))
+ && $value->format('Ymd') == $search->format('Ymd'));
}
// composite field, e.g. address
diff --git a/program/lib/Roundcube/rcube_contacts.php b/program/lib/Roundcube/rcube_contacts.php
index 3919cdc6e..6d01368a1 100644
--- a/program/lib/Roundcube/rcube_contacts.php
+++ b/program/lib/Roundcube/rcube_contacts.php
@@ -718,6 +718,10 @@ class rcube_contacts extends rcube_addressbook
foreach ($save_data as $key => $values) {
list($field, $section) = explode(':', $key);
$fulltext = in_array($field, $this->fulltext_cols);
+ // avoid casting DateTime objects to array
+ if (is_object($values) && is_a($values, 'DateTime')) {
+ $values = array(0 => $values);
+ }
foreach ((array)$values as $value) {
if (isset($value))
$vcard->set($field, $value, $section);
diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php
index 2540f779d..1d76ae508 100644
--- a/program/lib/Roundcube/rcube_utils.php
+++ b/program/lib/Roundcube/rcube_utils.php
@@ -787,6 +787,44 @@ class rcube_utils
return (int) $ts;
}
+ /**
+ * Date parsing function that turns the given value into a DateTime object
+ *
+ * @param string $date Date string
+ *
+ * @return object DateTime instance or false on failure
+ */
+ public static function anytodatetime($date)
+ {
+ if (is_object($date) && is_a($date, 'DateTime')) {
+ return $date;
+ }
+
+ $dt = false;
+ $date = trim($date);
+
+ // try to parse string with DateTime first
+ if (!empty($date)) {
+ try {
+ $dt = new DateTime($date);
+ }
+ catch (Exception $e) {
+ // ignore
+ }
+ }
+
+ // try our advanced strtotime() method
+ if (!$dt && ($timestamp = self::strtotime($date))) {
+ try {
+ $dt = new DateTime("@".$timestamp);
+ }
+ catch (Exception $e) {
+ // ignore
+ }
+ }
+
+ return $dt;
+ }
/*
* Idn_to_ascii wrapper.
diff --git a/program/lib/Roundcube/rcube_vcard.php b/program/lib/Roundcube/rcube_vcard.php
index a85eb8873..d54dc56ad 100644
--- a/program/lib/Roundcube/rcube_vcard.php
+++ b/program/lib/Roundcube/rcube_vcard.php
@@ -358,8 +358,8 @@ class rcube_vcard
case 'birthday':
case 'anniversary':
- if (($val = rcube_utils::strtotime($value)) && ($fn = self::$fieldmap[$field])) {
- $this->raw[$fn][] = array(0 => date('Y-m-d', $val), 'value' => array('date'));
+ if (($val = rcube_utils::anytodatetime($value)) && ($fn = self::$fieldmap[$field])) {
+ $this->raw[$fn][] = array(0 => $val->format('Y-m-d'), 'value' => array('date'));
}
break;
diff --git a/program/steps/addressbook/save.inc b/program/steps/addressbook/save.inc
index 1628f5b0f..2adc53bcf 100644
--- a/program/steps/addressbook/save.inc
+++ b/program/steps/addressbook/save.inc
@@ -77,6 +77,16 @@ foreach ($GLOBALS['CONTACT_COLTYPES'] as $col => $colprop) {
}
else if (isset($_POST[$fname])) {
$a_record[$col] = get_input_value($fname, RCUBE_INPUT_POST, true);
+
+ // 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);
+ }
+ else {
+ unset($a_record[$col]);
+ }
+ }
}
}