diff --git a/plugins/libkolab/SQL/mysql.sql b/plugins/libkolab/SQL/mysql.sql index 55d0dbc9..244ab3d8 100644 --- a/plugins/libkolab/SQL/mysql.sql +++ b/plugins/libkolab/SQL/mysql.sql @@ -6,12 +6,15 @@ * @licence GNU AGPL **/ -CREATE TABLE IF NOT EXISTS `kolab_cache` ( +DROP TABLE IF EXISTS `kolab_cache`; + +CREATE TABLE `kolab_cache` ( `resource` VARCHAR(255) CHARACTER SET ascii NOT NULL, `type` VARCHAR(32) CHARACTER SET ascii NOT NULL, `msguid` BIGINT UNSIGNED NOT NULL, `uid` VARCHAR(128) CHARACTER SET ascii NOT NULL, `created` DATETIME DEFAULT NULL, + `changed` DATETIME DEFAULT NULL, `data` TEXT NOT NULL, `xml` TEXT NOT NULL, `dtstart` DATETIME, diff --git a/plugins/libkolab/lib/kolab_format.php b/plugins/libkolab/lib/kolab_format.php index 66588975..caae38fd 100644 --- a/plugins/libkolab/lib/kolab_format.php +++ b/plugins/libkolab/lib/kolab_format.php @@ -40,6 +40,7 @@ abstract class kolab_format protected $loaded = false; const VERSION = '3.0'; + const KTYPE_PREFIX = 'application/x-vnd.kolab.'; /** * Factory method to instantiate a kolab_format object of the given type @@ -166,6 +167,17 @@ abstract class kolab_format return $vec; } + /** + * Parse the X-Kolab-Type header from MIME messages and return the object type in short form + * + * @param string X-Kolab-Type header value + * @return string Kolab object type (contact,event,task,note,etc.) + */ + public static function mime2object_type($x_kolab_type) + { + return preg_replace('/dictionary.[a-z.]+$/', 'dictionary', substr($x_kolab_type, strlen(self::KTYPE_PREFIX))); + } + /** * Check for format errors after calling kolabformat::write*() * diff --git a/plugins/libkolab/lib/kolab_storage_cache.php b/plugins/libkolab/lib/kolab_storage_cache.php index 4e3846dc..004776e0 100644 --- a/plugins/libkolab/lib/kolab_storage_cache.php +++ b/plugins/libkolab/lib/kolab_storage_cache.php @@ -215,12 +215,13 @@ class kolab_storage_cache $result = $this->db->query( "INSERT INTO kolab_cache ". - " (resource, type, msguid, uid, created, data, xml, dtstart, dtend, tags, words)". - " VALUES (?, ?, ?, ?, " . $this->db->now() . ", ?, ?, ?, ?, ?, ?)", + " (resource, type, msguid, uid, created, changed, data, xml, dtstart, dtend, tags, words)". + " VALUES (?, ?, ?, ?, " . $this->db->now() . ", ?, ?, ?, ?, ?, ?, ?)", $this->resource_uri, $objtype, $msguid, $object['uid'], + $sql_data['changed'], $sql_data['data'], $sql_data['xml'], $sql_data['dtstart'], @@ -331,7 +332,7 @@ class kolab_storage_cache $index = $this->index; } else { // search by object type - $search = 'UNDELETED HEADER X-Kolab-Type ' . kolab_storage_folder::KTYPE_PREFIX . $filter['type']; + $search = 'UNDELETED HEADER X-Kolab-Type ' . kolab_format::KTYPE_PREFIX . $filter['type']; $index = $this->imap->search_once($this->folder->name, $search)->get(); } @@ -369,7 +370,7 @@ class kolab_storage_cache else { // search IMAP by object type $filter = $this->_query2assoc($query); - $ctype = kolab_storage_folder::KTYPE_PREFIX . $filter['type']; + $ctype = kolab_format::KTYPE_PREFIX . $filter['type']; $index = $this->imap->search_once($this->folder->name, 'UNDELETED HEADER X-Kolab-Type ' . $ctype); $count = $index->count(); } @@ -464,7 +465,7 @@ class kolab_storage_cache $results = array(); foreach ((array)$this->imap->fetch_headers($this->folder->name, $index, false) as $msguid => $headers) { - $object_type = preg_replace('/dictionary.[a-z]+$/', 'dictionary', substr($headers->others['x-kolab-type'], strlen(kolab_storage_folder::KTYPE_PREFIX))); + $object_type = kolab_format::mime2object_type($headers->others['x-kolab-type']); // check object type header and abort on mismatch if ($type != '*' && $object_type != $type) @@ -485,7 +486,7 @@ class kolab_storage_cache private function _serialize($object) { $bincols = array_flip($this->binary_cols); - $sql_data = array('dtstart' => null, 'dtend' => null, 'xml' => '', 'tags' => '', 'words' => ''); + $sql_data = array('changed' => null, 'dtstart' => null, 'dtend' => null, 'xml' => '', 'tags' => '', 'words' => ''); $objtype = $object['_type'] ? $object['_type'] : $this->folder->type; // set type specific values @@ -506,6 +507,10 @@ class kolab_storage_cache $sql_data['dtend'] = date('Y-m-d H:i:s', is_object($object['due']) ? $object['due']->format('U') : $object['due']); } + if ($object['changed']) { + $sql_data['changed'] = date('Y-m-d H:i:s', is_object($object['changed']) ? $object['changed']->format('U') : $object['changed']); + } + if ($object['_formatobj']) { $sql_data['xml'] = preg_replace('!()[\n\r\t\s]+!ms', '$1', (string)$object['_formatobj']->write()); $sql_data['tags'] = ' ' . join(' ', $object['_formatobj']->get_tags()) . ' '; // pad with spaces for strict/prefix search @@ -581,6 +586,7 @@ class kolab_storage_cache $this->db->quote($msguid), $this->db->quote($object['uid']), $this->db->now(), + $this->db->quote($sql_data['changed']), $this->db->quote($sql_data['data']), $this->db->quote($sql_data['xml']), $this->db->quote($sql_data['dtstart']), @@ -594,7 +600,7 @@ class kolab_storage_cache if ($buffer && (!$msguid || (strlen($buffer) + strlen($line) > $this->max_sql_packet))) { $result = $this->db->query( "INSERT INTO kolab_cache ". - " (resource, type, msguid, uid, created, data, xml, dtstart, dtend, tags, words)". + " (resource, type, msguid, uid, created, changed, data, xml, dtstart, dtend, tags, words)". " VALUES $buffer" ); if (!$this->db->affected_rows($result)) { diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php index 196e6778..c7a045f4 100644 --- a/plugins/libkolab/lib/kolab_storage_folder.php +++ b/plugins/libkolab/lib/kolab_storage_folder.php @@ -23,8 +23,6 @@ */ class kolab_storage_folder { - const KTYPE_PREFIX = 'application/x-vnd.kolab.'; - /** * The folder name. * @var string @@ -358,7 +356,7 @@ class kolab_storage_folder if ($param[0] == 'type') { $type = $param[2]; } - else if (($param[0] == 'dtstart' || $param[0] == 'dtend') && is_numeric($param[2])) { + else if (($param[0] == 'dtstart' || $param[0] == 'dtend' || $param[0] == 'changed') && is_numeric($param[2])) { $query[$i][2] = date('Y-m-d H:i:s', $param[2]); } } @@ -428,8 +426,8 @@ class kolab_storage_folder $this->imap->set_folder($folder); $headers = $this->imap->get_message_headers($msguid); - $object_type = preg_replace('/dictionary.[a-z]+$/', 'dictionary', substr($headers->others['x-kolab-type'], strlen(self::KTYPE_PREFIX))); - $content_type = self::KTYPE_PREFIX . $object_type; + $object_type = kolab_format::mime2object_type($headers->others['x-kolab-type']); + $content_type = kolab_format::KTYPE_PREFIX . $object_type; // check object type header and abort on mismatch if ($type != '*' && $object_type != $type) @@ -719,7 +717,7 @@ class kolab_storage_folder $headers['To'] = $ident['email']; } $headers['Date'] = date('r'); - $headers['X-Kolab-Type'] = self::KTYPE_PREFIX . $type; + $headers['X-Kolab-Type'] = kolab_format::KTYPE_PREFIX . $type; $headers['X-Kolab-Mime-Version'] = kolab_format::VERSION; $headers['Subject'] = $object['uid']; // $headers['Message-ID'] = $rcmail->gen_message_id();