From 1d4233967de887d65741f130f769ce5c5e10bf66 Mon Sep 17 00:00:00 2001 From: Gunnar Wrobel Date: Mon, 27 Dec 2010 22:10:23 +0100 Subject: [PATCH] Add support for listing annotations. --- .../lib/Horde/Kolab/Storage/Driver.php | 10 ++++ .../lib/Horde/Kolab/Storage/Driver/Base.php | 22 ++++++++ .../lib/Horde/Kolab/Storage/Driver/Cclient.php | 22 ++++++++ .../Horde/Kolab/Storage/Driver/Decorator/Base.php | 13 +++++ .../lib/Horde/Kolab/Storage/Driver/Imap.php | 20 ++++++++ .../lib/Horde/Kolab/Storage/Driver/Mock.php | 59 +++++++++++++++++++--- .../lib/Horde/Kolab/Storage/Driver/Pear.php | 21 ++++++++ .../lib/Horde/Kolab/Storage/Driver/Rcube.php | 24 +++++++++ 8 files changed, 183 insertions(+), 8 deletions(-) diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver.php index f4a98759c..b57f2f547 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver.php @@ -42,6 +42,16 @@ interface Horde_Kolab_Storage_Driver public function getMailboxes(); /** + * Retrieves the specified annotation for the complete list of mailboxes. + * + * @param string $annotation The name of the annotation to retrieve. + * + * @return array An associative array combining the folder names as key with + * the corresponding annotation value. + */ + public function listAnnotation($annotation); + + /** * Does the given folder exist? * * @param string $folder The folder to check. diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Base.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Base.php index a5557813f..a264881dd 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Base.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Base.php @@ -104,4 +104,26 @@ implements Horde_Kolab_Storage_Driver } return $this->_namespace; } + + /** + * Split a name for the METADATA extension into the correct syntax for the + * older ANNOTATEMORE version. + * + * @param string $name A name for a metadata entry. + * + * @return array A list of two elements: The entry name and the value + * type. + * @throws Horde_Imap_Client_Exception + */ + protected function _getAnnotateMoreEntry($name) + { + if (substr($name, 0, 7) == '/shared') { + return array(substr($name, 7), 'value.shared'); + } else if (substr($name, 0, 8) == '/private') { + return array(substr($name, 8), 'value.priv'); + } + + $this->_exception('Invalid METADATA entry: ' . $name); + } + } \ No newline at end of file diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Cclient.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Cclient.php index 4df47b2a3..9100e724c 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Cclient.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Cclient.php @@ -159,6 +159,28 @@ extends Horde_Kolab_Storage_Driver_Base return $folders; } + + /** + * Retrieves the specified annotation for the complete list of mailboxes. + * + * @param string $annotation The name of the annotation to retrieve. + * + * @return array An associative array combining the folder names as key with + * the corresponding annotation value. + */ + public function listAnnotation($annotation) + { + list($entry, $value) = $this->_getAnnotateMoreEntry($annotation); + $list = array(); + foreach ($this->getMailboxes() as $mailbox) { + $result = imap_getannotation($this->_getImap(), $mailbox, $entry, $value); + if (isset($result[$value])) { + $list[$mailbox] = $result[$value]; + } + } + return $list; + } + /** * Opens the given folder. * diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Decorator/Base.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Decorator/Base.php index 3c9a30a35..c3529e646 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Decorator/Base.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Decorator/Base.php @@ -76,6 +76,19 @@ implements Horde_Kolab_Storage_Driver } /** + * Retrieves the specified annotation for the complete list of mailboxes. + * + * @param string $annotation The name of the annotation to retrieve. + * + * @return array An associative array combining the folder names as key with + * the corresponding annotation value. + */ + public function listAnnotation($annotation) + { + return $this->_driver->listAnnotation($annotation); + } + + /** * Does the given folder exist? * * @param string $folder The folder to check. diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Imap.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Imap.php index fecfb65b1..4bf2769ad 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Imap.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Imap.php @@ -72,6 +72,26 @@ extends Horde_Kolab_Storage_Driver_Base } /** + * Retrieves the specified annotation for the complete list of mailboxes. + * + * @param string $annotation The name of the annotation to retrieve. + * + * @return array An associative array combining the folder names as key with + * the corresponding annotation value. + */ + public function listAnnotation($annotation) + { + $result = $this->_imap->getMetadata('*', $annotation); + $data = array(); + foreach ($result as $folder => $annotations) { + if (isset($annotations[$annotation])) { + $data[$folder] = $annotations[$annotation]; + } + } + return $data; + } + + /** * Opens the given folder. * * @param string $folder The folder to open diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Mock.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Mock.php index 664f31750..3269104d2 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Mock.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Mock.php @@ -36,6 +36,13 @@ extends Horde_Kolab_Storage_Driver_Base private $_data; /** + * The regular expression for converting folder names. + * + * @var string + */ + private $_conversion_pattern; + + /** * The data of the mailbox currently opened * * @var array @@ -69,11 +76,13 @@ extends Horde_Kolab_Storage_Driver_Base } /** - * Parse the folder name into an id for this mock driver. + * Convert the external folder id to an internal mailbox name. * - * @return string The folder id. + * @param string $folder The external folder name. + * + * @return string The internal mailbox id. */ - private function _parseFolder($folder) + private function _convertToInternal($folder) { if (substr($folder, 0, 5) == 'INBOX') { $user = explode('@', $this->_user); @@ -83,6 +92,22 @@ extends Horde_Kolab_Storage_Driver_Base } /** + * Convert the internal mailbox name into an external folder id. + * + * @param string $mbox The internal mailbox name. + * + * @return string The external folder id. + */ + private function _convertToExternal($mbox) + { + if ($this->_conversion_pattern === null) { + $user = explode('@', $this->getAuth()); + $this->_conversion_pattern = '#^user/' . $user[0] . '#'; + } + return preg_replace($this->_conversion_pattern, 'INBOX', $mbox);; + } + + /** * Return the id of the user currently authenticated. * * @return string The id of the user that opened the IMAP connection. @@ -99,11 +124,28 @@ extends Horde_Kolab_Storage_Driver_Base */ public function getMailboxes() { - $user = explode('@', $this->getAuth()); - $pattern = '#^user/' . $user[0] . '#'; $result = array(); foreach (array_keys($this->_data) as $mbox) { - $result[] = preg_replace($pattern, 'INBOX', $mbox); + $result[] = $this->_convertToExternal($mbox); + } + return $result; + } + + /** + * Retrieves the specified annotation for the complete list of mailboxes. + * + * @param string $annotation The name of the annotation to retrieve. + * + * @return array An associative array combining the folder names as key with + * the corresponding annotation value. + */ + public function listAnnotation($annotation) + { + $result = array(); + foreach (array_keys($this->_data) as $mbox) { + if (isset($this->_data[$mbox]['annotations'][$annotation])) { + $result[$this->_convertToExternal($mbox)] = $this->_data[$mbox]['annotations'][$annotation]; + } } return $result; } @@ -118,7 +160,7 @@ extends Horde_Kolab_Storage_Driver_Base */ public function select($folder) { - $folder = $this->_parseFolder($folder); + $folder = $this->_convertToInternal($folder); if (!isset($GLOBALS['KOLAB_TESTING'][$folder])) { throw new Horde_Kolab_Storage_Exception(sprintf("IMAP folder %s does not exist!", $folder)); } @@ -136,6 +178,7 @@ extends Horde_Kolab_Storage_Driver_Base */ public function exists($folder) { + //@todo: make faster by directly accessing the _data array. $folders = $this->getMailboxes(); if (in_array($folder, $folders)) { return true; @@ -418,7 +461,7 @@ extends Horde_Kolab_Storage_Driver_Base */ public function getAnnotation($entry, $mailbox_name) { - $mailbox_name = $this->_parseFolder($mailbox_name); + $mailbox_name = $this->_convertToInternal($mailbox_name); $old_mbox = null; if ($mailbox_name != $this->_mboxname) { $old_mbox = $this->_mboxname; diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Pear.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Pear.php index d44714e71..9caaa679f 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Pear.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Pear.php @@ -72,6 +72,27 @@ extends Horde_Kolab_Storage_Driver_Base } /** + * Retrieves the specified annotation for the complete list of mailboxes. + * + * @param string $annotation The name of the annotation to retrieve. + * + * @return array An associative array combining the folder names as key with + * the corresponding annotation value. + */ + public function listAnnotation($annotation) + { + list($entry, $value) = $this->_getAnnotateMoreEntry($annotation); + $list = array(); + $result = $this->_imap->getAnnotation($entry, $value, '*'); + foreach ($result as $element) { + if (isset($element['ATTRIBUTES'][$value])) { + $list[$element['MAILBOX']] = $element['ATTRIBUTES'][$value]; + } + } + return $list; + } + + /** * Opens the given folder. * * @param string $folder The folder to open diff --git a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Rcube.php b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Rcube.php index d2064787b..b97eb68d9 100644 --- a/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Rcube.php +++ b/framework/Kolab_Storage/lib/Horde/Kolab/Storage/Driver/Rcube.php @@ -72,6 +72,30 @@ extends Horde_Kolab_Storage_Driver_Base } /** + * Retrieves the specified annotation for the complete list of mailboxes. + * + * @param string $annotation The name of the annotation to retrieve. + * + * @return array An associative array combining the folder names as key with + * the corresponding annotation value. + */ + public function listAnnotation($annotation) + { + list($entry, $value) = $this->_getAnnotateMoreEntry($annotation); + $result = $this->_imap->getAnnotation('*', $entry, $value); + if (empty($result)) { + return array(); + } + $data = array(); + foreach ($result as $folder => $annotations) { + if (isset($annotations[$annotation])) { + $data[$folder] = $annotations[$annotation]; + } + } + return $data; + } + + /** * Opens the given folder. * * @param string $folder The folder to open -- 2.11.0