Thomas Bruederli
2013-09-10 52830ea6056dc85d8ffcb0cfb7ead7d70624e109
Improve handling of date strings and DateTime values in contacts
5 files modified
62 ■■■■■ changed files
program/lib/Roundcube/rcube_addressbook.php 6 ●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_contacts.php 4 ●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_utils.php 38 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_vcard.php 4 ●●●● patch | view | raw | blame | history
program/steps/addressbook/save.inc 10 ●●●●● patch | view | raw | blame | history
program/lib/Roundcube/rcube_addressbook.php
@@ -563,9 +563,9 @@
        // 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
program/lib/Roundcube/rcube_contacts.php
@@ -718,6 +718,10 @@
        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);
program/lib/Roundcube/rcube_utils.php
@@ -787,6 +787,44 @@
        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.
program/lib/Roundcube/rcube_vcard.php
@@ -358,8 +358,8 @@
        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;
program/steps/addressbook/save.inc
@@ -77,6 +77,16 @@
  }
  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]);
        }
    }
  }
}