Cleanups/Fixes/Improvments to annotate code.
authorMichael M Slusarz <slusarz@curecanti.org>
Mon, 7 Sep 2009 21:32:26 +0000 (15:32 -0600)
committerMichael M Slusarz <slusarz@curecanti.org>
Mon, 7 Sep 2009 21:36:20 +0000 (15:36 -0600)
For cclient, simply use Socket driver. Don't use IMAP extension that
requires manual patching of PHP source.
Add support for the METADATA-SERVER and ANNOTATEMORE2 extensions.
Get rid of 'nocapability' and 'annotatemore' options. This should all be
determined automatically by the driver code. The other options (maxsize,
depth) can be emulated in software based on which extension is available
(TODO for annotatemore code).
Need to define new publicly available methods in all drivers (e.g.
Cclient and Socket Pop3 drivers).

framework/Imap_Client/lib/Horde/Imap/Client/Base.php
framework/Imap_Client/lib/Horde/Imap/Client/Cclient.php
framework/Imap_Client/lib/Horde/Imap/Client/Cclient/Pop3.php
framework/Imap_Client/lib/Horde/Imap/Client/Mock.php
framework/Imap_Client/lib/Horde/Imap/Client/Socket.php
framework/Imap_Client/lib/Horde/Imap/Client/Socket/Pop3.php
framework/Imap_Client/test/Horde/Imap/test_client.php

index f9fa863..9485897 100644 (file)
@@ -2441,76 +2441,45 @@ abstract class Horde_Imap_Client_Base
     abstract protected function _getMyACLRights($mailbox);
 
     /**
-     * Get metadata for a given mailbox. The server must support the
-     * IMAP METADATA extension (RFC 5464).
+     * Get metadata for a given mailbox. The server must support either the
+     * IMAP METADATA extension (RFC 5464) or the ANNOTATEMORE extension
+     * (http://ietfreport.isoc.org/idref/draft-daboo-imap-annotatemore/).
      *
-     * @param string $mailbox A mailbox. Either in UTF7-IMAP or UTF-8.
-     * @param array  $entries The entries to fetch.
-     * @param array  $options Additional options:
+     * @param string $mailbox  A mailbox. Either in UTF7-IMAP or UTF-8.
+     * @param array $entries   The entries to fetch.
+     * @param array $options   Additional options:
      * <pre>
-     * 'maxsize'      - (int) The maximal size the returned values may have.
-     *                  This option is only available if 'annotatemore' has
-     *                  not been set.
-     *                  DEFAULT: No maximal size.
-     * 'depth'        - (string) Either "0", "1" or "infinity". Returns only
-     *                  the given value ("0"), only values one level below
-     *                  the specified value ("1") or all entries below the
-     *                  specified value ("infinity").
-     *                  This option is only available if 'annotatemore' has
-     *                  not been set.
-     *                  DEFAULT: Unset which is equivalent to "0".
-     * 'nocapability' - (boolean) Do not check for the METADATA capability of
-     *                  the server ("true"). Otherwise the call will fail if
-     *                  the server does not announce the METADATA capability
-     *                  ("false").
-     *                  DEFAULT: false - Check the capability.
-     * 'annotatemore' - (boolean) Use the ANNOTATION command rather than the 
-     *                  METADATA command ("true"). This corresponds to
-     *                  an old version of the RFC 5464 that is available for
-     *                  some servers (cyrus, dovecot).
-     *                  DEFAULT: Use the newer METADATA command.
+     * 'depth' - (string) Either "0", "1" or "infinity". Returns only the
+     *           given value ("0"), only values one level below the specified
+     *           value (1) or all entries below the specified value
+     *           ("infinity").
+     * 'maxsize' - (integer) The maximal size the returned values may have.
+     *             DEFAULT: No maximal size.
+     *           DEFAULT: 0
      * </pre>
      *
-     * @return array 
+     * @return array  An array with metadata names as the keys and metadata
+     *                values as the values.
      * @throws Horde_Imap_Client_Exception
      */
     public function getMetadata($mailbox, $entries, $options = array())
     {
-        if (empty($options['nocapability'])) {
-            if (empty($options['annotatemore'])) {
-                $capability = 'METADATA';
-            } else {
-                $capability = 'ANNOTATEMORE';
-            }
-            if (!$this->queryCapability($capability)) {
-                throw new Horde_Imap_Client_Exception('Server does not support the METADATA extension.',
-                                                      Horde_Imap_Client_Exception::NOSUPPORTIMAPEXT);
-            }
-        }
-
         if (!is_array($entries)) {
             $entries = array($entries);
         }
 
-        $entries_utf7 = array();
-        foreach ($entries as $entry) {
-            $entries_utf7[] = Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($entry);
-        }
-
-        return $this->_getMetadata(Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($mailbox),
-                                   $entries_utf7,
-                                   $options);
+        return $this->_getMetadata(Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($mailbox), array_map(array('Horde_Imap_Client_Utf7imap', 'Utf8ToUtf7Imap'), $entries), $options);
     }
 
     /**
      * Get metadata for a given mailbox.
      *
-     * @param string $mailbox A mailbox (UTF7-IMAP).
-     * @param array  $entries The entries to fetch.
-     * @param array  $options Additional options.
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $entries   The entries to fetch.
+     * @param array $options   Additional options.
      *
-     * @return array  An array with metadata names as the keys and
-     *                metadata values as the values.
+     * @return array  An array with metadata names as the keys and metadata
+     *                values as the values.
      * @throws Horde_Imap_Client_Exception
      */
     abstract protected function _getMetadata($mailbox, $entries, $options);
@@ -2518,81 +2487,30 @@ abstract class Horde_Imap_Client_Base
     /**
      * Set metadata for a given mailbox/identifier.
      *
-     * @param string $mailbox A mailbox. Either in UTF7-IMAP or UTF-8.
-     * @param array  $data    A set of data values. The metadata values
-     *                        corresponding to the keys of the array will
-     *                        be set to the values in the array.
-     * @param array  $options Additional options:
-     * <pre>
-     * 'nocapability' - (boolean) Do not check for the METADATA capability of
-     *                  the server ("true"). Otherwise the call will fail if
-     *                  the server does not announce the METADATA capability
-     *                  ("false").
-     *                  DEFAULT: false - Check the capability.
-     * 'annotatemore' - (boolean) Use the ANNOTATION command rather than the 
-     *                  METADATA command ("true"). This corresponds to
-     *                  an older draft version of the RFC 5464 that has been
-     *                  implemented in some servers (cyrus, dovecot).
-     *                  http://ietfreport.isoc.org/idref/draft-daboo-imap-annotatemore/
-     *                  DEFAULT: Use the newer METADATA command.
-     * </pre>
-     *
+     * @param string $mailbox  A mailbox. Either in UTF7-IMAP or UTF-8. If
+     *                         empty, sets a server annotation.
+     * @param array $data      A set of data values. The metadata values
+     *                         corresponding to the keys of the array will
+     *                         be set to the values in the array.
      *
      * @throws Horde_Imap_Client_Exception
      */
-    public function setMetadata($mailbox, $data, $options = array())
+    public function setMetadata($mailbox, $data)
     {
-        if (empty($options['nocapability'])) {
-            if (empty($options['annotatemore'])) {
-                $capability = 'METADATA';
-            } else {
-                $capability = 'ANNOTATEMORE';
-            }
-            if (!$this->queryCapability($capability)) {
-                throw new Horde_Imap_Client_Exception('Server does not support the METADATA extension.',
-                                                      Horde_Imap_Client_Exception::NOSUPPORTIMAPEXT);
-            }
-        }
-
-        return $this->_setMetadata(Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($mailbox), $data, $options);
+        $this->_setMetadata(Horde_Imap_Client_Utf7imap::Utf8ToUtf7Imap($mailbox), $data);
     }
 
     /**
      * Set metadata for a given mailbox/identifier.
      *
-     * @param string $mailbox A mailbox (UTF7-IMAP).
-     * @param array  $data    A set of data values. The metadata values
-     *                        corresponding to the keys of the array will
-     *                        be set to the values in the array.
-     * @param array  $options Additional options.
-     *
-     * @throws Horde_Imap_Client_Exception
-     */
-    abstract protected function _setMetadata($mailbox, $data, $options);
-
-    /**
-     * Split a name for the METADATA extension into the correct syntax for the
-     * older ANNOTATEMORE version (it is a predecessor of RFC 5464.
-     *
-     * @param string $name A name for a metadata entry.
-     *
-     * @return array A list of two elements: The entry name and the value type.
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $data      A set of data values. The metadata values
+     *                         corresponding to the keys of the array will
+     *                         be set to the values in the array.
      *
      * @throws Horde_Imap_Client_Exception
      */
-    protected function _getAnnotateMoreEntry($name)
-    {
-        if (substr($name, 0, 7) == '/shared') {
-            $entry = substr($name, 7);
-            $type  = 'value.shared';
-        } else if (substr($name, 0, 8) == '/private') {
-            $entry = substr($name, 8);
-            $type  = 'value.priv';
-        } else {
-            throw new Horde_Imap_Client_Exception('Invalid METADATA entry: ' . $name);
-        }
-        return array($entry, $type);
-    }
+    abstract protected function _setMetadata($mailbox, $data);
 
     /* Utility functions. */
 
index 92093ee..5ac8432 100644 (file)
@@ -1624,71 +1624,32 @@ class Horde_Imap_Client_Cclient extends Horde_Imap_Client_Base
     /**
      * Get metadata for a given mailbox.
      *
-     * @param string $mailbox A mailbox (UTF7-IMAP).
-     * @param array  $entries The entries to fetch.
-     * @param array  $options Additional options.
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $entries   The entries to fetch.
+     * @param array $options   Additional options.
      *
-     * @return array An array with identifiers as the keys and the
-     *               metadata as the values.
+     * @return array  An array with identifiers as the keys and the
+     *                metadata as the values.
      * @throws Horde_Imap_Client_Exception
      */
     protected function _getMetadata($mailbox, $entries, $options)
     {
-        if (!empty($options['annotatemore'])
-            && function_exists('imap_getannotation')) {
-            $result = array();
-            foreach ($entries as $md_entry) {
-                list($entry, $type) = $this->_getAnnotateMoreEntry($md_entry);
-                $old_error = error_reporting(0);
-                $res = imap_getannotation($this->_stream, $mailbox, $entry, $type);
-                error_reporting($old_error);
-                if (!$res) {
-                    throw new Horde_Imap_Client_Exception('Error when fetching METADATA: ' . imap_last_error());
-                }
-                foreach ($res as $key => $value) {
-                    switch ($type) {
-                    case 'value.priv':
-                        $result[$mailbox]['/private' . $entry] = $value;
-                        break;
-                    case 'value.shared':
-                        $result[$mailbox]['/shared' . $entry] = $value;
-                        break;
-                    }
-                }
-            }
-            return $result;
-        } else {
-            return $this->_getSocket()->getMetadata($mailbox, $entry, $options);
-        }
+        return $this->_getSocket()->getMetadata($mailbox, $entry, $options);
     }
 
     /**
      * Set metadata for a given mailbox/identifier.
      *
-     * @param string $mailbox A mailbox (UTF7-IMAP).
-     * @param array  $data    A set of data values. The metadata values
-     *                        corresponding to the keys of the array will
-     *                        be set to the values in the array.
-     * @param array  $options Additional options.
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $data      A set of data values. The metadata values
+     *                         corresponding to the keys of the array will
+     *                         be set to the values in the array.
      *
      * @throws Horde_Imap_Client_Exception
      */
-    protected function _setMetadata($mailbox, $data, $options)
+    protected function _setMetadata($mailbox, $data)
     {
-        if (!empty($options['annotatemore'])
-            && function_exists('imap_setannotation')) {
-            foreach ($data as $key => $value) {
-                list($entry, $type) = $this->_getAnnotateMoreEntry($key);
-                $old_error = error_reporting(0);
-                $res = imap_setannotation($this->_stream, $mailbox, $entry, $type, $value);
-                error_reporting($old_error);
-                if (!$res) {
-                    throw new Horde_Imap_Client_Exception('Error when setting METADATA: ' . imap_last_error());
-                }
-            }
-        } else {
-            return $this->_getSocket()->setMetadata($mailbox, $data, $options);
-        }
+        $this->_getSocket()->setMetadata($mailbox, $data);
     }
 
     /* Internal functions */
index 56df970..b03fac0 100644 (file)
@@ -468,4 +468,35 @@ class Horde_Imap_Client_Cclient_Pop3 extends Horde_Imap_Client_Cclient
         throw new Horde_Imap_Client_Exception('IMAP ACLs not supported on POP3 servers.', Horde_Imap_Client_Exception::POP3_NOTSUPPORTED);
     }
 
+    /**
+     * Get metadata for a given mailbox.
+     *
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $entries   The entries to fetch.
+     * @param array $options   Additional options.
+     *
+     * @return array  An array with identifiers as the keys and the
+     *                metadata as the values.
+     * @throws Horde_Imap_Client_Exception
+     */
+     protected function _getMetadata($mailbox, $entries, $options)
+     {
+        throw new Horde_Imap_Client_Exception('IMAP metadata not supported on POP3 servers.', Horde_Imap_Client_Exception::POP3_NOTSUPPORTED);
+     }
+
+    /**
+     * Set metadata for a given mailbox/identifier.
+     *
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $data      A set of data values. The metadata values
+     *                         corresponding to the keys of the array will
+     *                         be set to the values in the array.
+     *
+     * @throws Horde_Imap_Client_Exception
+     */
+    protected function _setMetadata($mailbox, $data)
+    {
+        throw new Horde_Imap_Client_Exception('IMAP metadata not supported on POP3 servers.', Horde_Imap_Client_Exception::POP3_NOTSUPPORTED);
+    }
+
 }
index 01c27d7..0b70a3a 100644 (file)
@@ -830,9 +830,9 @@ class Horde_Imap_Client_Mock extends Horde_Imap_Client_Base
     /**
      * Get metadata for a given mailbox.
      *
-     * @param string $mailbox A mailbox (UTF7-IMAP).
-     * @param array  $entries The entries to fetch.
-     * @param array  $options Additional options.
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $entries   The entries to fetch.
+     * @param array $options   Additional options.
      *
      * @return array  An array with identifiers as the keys and the
      *                metadata as the values.
@@ -840,19 +840,20 @@ class Horde_Imap_Client_Mock extends Horde_Imap_Client_Base
      */
     protected function _getMetadata($mailbox, $entries, $options)
     {
-        $folder   = $this->_getMailbox($mailbox);
+        $folder = $this->_getMailbox($mailbox);
         $metadata = array();
+
         foreach ($entries as $entry) {
             $result = false;
             if (isset(self::$storage[$folder]['annotations'])) {
-                $ref  = &self::$storage[$folder]['annotations'];
+                $ref = &self::$storage[$folder]['annotations'];
                 $path = split('/', $entry);
                 foreach ($path as $element) {
                     if (!isset($ref[$element])) {
                         $result = false;
                         break;
                     } else {
-                        $ref    = &$ref[$element];
+                        $ref = &$ref[$element];
                         $result = true;
                     }
                 }
@@ -862,35 +863,36 @@ class Horde_Imap_Client_Mock extends Horde_Imap_Client_Base
             }
             $metadata[$entry] = $result;
         }
+
         return $metadata;
     }
 
     /**
      * Set metadata for a given mailbox/identifier.
      *
-     * @param string $mailbox A mailbox (UTF7-IMAP).
-     * @param array  $data    A set of data values. The metadata values
-     *                        corresponding to the keys of the array will
-     *                        be set to the values in the array.
-     * @param array  $options Additional options.
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $data      A set of data values. The metadata values
+     *                         corresponding to the keys of the array will
+     *                         be set to the values in the array.
      *
      * @throws Horde_Imap_Client_Exception
      */
-    protected function _setMetadata($mailbox, $data, $options)
+    protected function _setMetadata($mailbox, $data)
     {
         $folder = $this->_getMailbox($mailbox);
+
         foreach ($data as $key => $value) {
             $path = split('/', $key);
             $ref  = &self::$storage[$folder]['annotations'];
             foreach ($path as $element) {
                 if (!isset($ref[$element])) {
                     $ref[$element] = array();
-
                     $ref = &$ref[$element];
                 }
             }
             $ref['/'] = $value;
         }
+
         return true;
     }
-}
\ No newline at end of file
+}
index e0a6f33..375d780 100644 (file)
@@ -3009,12 +3009,12 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base
     /**
      * Get metadata for a given mailbox.
      *
-     * @param string $mailbox A mailbox (UTF7-IMAP).
-     * @param array  $entries The entries to fetch.
-     * @param array  $options Additional options.
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $entries   The entries to fetch.
+     * @param array $options   Additional options.
      *
-     * @return array  An array with identifiers as the keys and the
-     *                metadata as the values.
+     * @return array  An array with metadata names as the keys and metadata
+     *                values as the values.
      * @throws Horde_Imap_Client_Exception
      */
     protected function _getMetadata($mailbox, $entries, $options)
@@ -3024,12 +3024,28 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base
         $this->_temp['metadata'] = array();
 
         $cmd_options = array();
-        $single_type = '';
+        $option_string = $single_type = '';
+        $use_rfc5464 = false;
+
+        if ($this->queryCapability('METADATA') ||
+            ((strlen($mailbox) == 0) &&
+             $this->queryCapability('METADATA-SERVER'))) {
+            $use_rfc5464 = true;
+        } elseif (!$this->queryCapability('ANNOTATEMORE') &&
+                  !$this->queryCapability('ANNOTATEMORE2')) {
+            throw new Horde_Imap_Client_Exception('Server does not support the METADATA extension.', Horde_Imap_Client_Exception::NOSUPPORTIMAPEXT);
+        }
 
-        if (!empty($options['annotatemore'])) {
-            if (!empty($options['maxsize']) || !empty($options['depth'])) {
-                throw new Horde_Imap_Client_Exception('ANNOTATEMORE does not support the "depth" and "maxsize" option.');
+        if ($use_rfc5464) {
+            $cmd = 'GETMETADATA ';
+
+            if (!empty($options['maxsize'])) {
+                $cmd_options[] = '(MAXSIZE ' . intval($options['maxsize']) . ')';
             }
+            if (!empty($options['depth'])) {
+                $cmd_options[] = '(DEPTH ' . $options['depth'] . ')';
+            }
+        } else {
             $cmd = 'GETANNOTATION ';
 
             $result = array();
@@ -3038,81 +3054,105 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base
                 if (empty($single_type)) {
                     $single_type = $type;
                 } else if ($single_type != $type) {
+                    // TODO: Recursive calls to _getMetadata()
                     throw new Horde_Imap_Client_Exception('Multiple value types may not be retrieved in one call when using ANNOTATEMORE.');
                 }
                 $result[] = $entry;
             }
             $entries = $result;
-        } else {
-            $cmd = 'GETMETADATA ';
-
-            if (!empty($options['maxsize'])) {
-                $cmd_options[] = '(MAXSIZE ' . $options['maxsize'] . ')';
-            }
-            if (!empty($options['depth'])) {
-                $cmd_options[] = '(DEPTH ' . $options['depth'] . ')';
-            }
         }
 
-        if (count($entries) == 1) {
-            $entry_string = $this->utils->escape($entries[0]) . ' ' . $this->utils->escape($single_type);
+        if (count($cmd_options) == 1) {
+            $option_string = $cmd_options[0];
         } else {
-            $entry_string = '(' . join(' ', $entries) . ') ' . $single_type;
+            $option_string = '(' . join(' ', $cmd_options) . ')';
         }
 
-        if (count($cmd_options) == 0) {
-            $option_string = ' ';
-        } else if (count($cmd_options) == 1) {
-            $option_string = ' ' . $cmd_options[0] . ' ';
-        } else {
-            $option_string = ' (' . join(' ', $cmd_options) . ') ';
+        $entry_string = (count($entries) == 1)
+            ? $this->utils->escape($entries[0]) . ' ' . $this->utils->escape($single_type)
+            : '(' . join(' ', $entries) . ') ' . $single_type;
+
+        $this->_sendLine($cmd . $this->utils->escape($mailbox) . ' ' . $option_string . ' ' . $entry_string);
+
+        if (!$use_rfc5464) {
+            // TODO: Honor maxsize and depth options.
         }
 
-        $this->_sendLine($cmd . $this->utils->escape($mailbox) . $option_string . $entry_string);
         return $this->_temp['metadata'];
     }
 
     /**
+     * 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');
+        }
+
+        throw new Horde_Imap_Client_Exception('Invalid METADATA entry: ' . $name);
+    }
+
+    /**
      * Set metadata for a given mailbox/identifier.
      *
-     * @param string $mailbox A mailbox (UTF7-IMAP).
-     * @param array  $data    A set of data values. The metadata values
-     *                        corresponding to the keys of the array will
-     *                        be set to the values in the array.
-     * @param array  $options Additional options.
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $data      A set of data values. The metadata values
+     *                         corresponding to the keys of the array will
+     *                         be set to the values in the array.
      *
      * @throws Horde_Imap_Client_Exception
      */
-    protected function _setMetadata($mailbox, $data, $options)
+    protected function _setMetadata($mailbox, $data)
     {
-        if (!empty($options['annotatemore'])) {
-            $cmd = 'SETANNOTATION ';
+        $data_elements = array();
+        $use_rfc5464 = false;
 
-            $data_elements = array();
-            foreach ($data as $md_entry => $value) {
-                list($entry, $type) = $this->_getAnnotateMoreEntry($md_entry);
-                $i_value = ($value === null) ? 'NIL' : $this->utils->escape($value);
-                $data_elements[] = $this->utils->escape($entry) . ' (' . $this->utils->escape($type) . ' ' . $i_value . ')';
-            }
-        } else {
+        if ($this->queryCapability('METADATA') ||
+            ((strlen($mailbox) == 0) &&
+             $this->queryCapability('METADATA-SERVER'))) {
+            $use_rfc5464 = true;
+        } elseif (!$this->queryCapability('ANNOTATEMORE') &&
+                  !$this->queryCapability('ANNOTATEMORE2')) {
+            throw new Horde_Imap_Client_Exception('Server does not support the METADATA extension.', Horde_Imap_Client_Exception::NOSUPPORTIMAPEXT);
+        }
+
+        if ($use_rfc5464) {
             $cmd = 'SETMETADATA ';
 
             foreach ($data as $key => $value) {
-                $i_value = ($value === null) ? 'NIL' : $this->utils->escape($value);
+                $i_value = is_null($value)
+                    ? 'NIL'
+                    : $this->utils->escape($value);
                 $data_elements[] = $this->utils->escape($key) . ' ' . $i_value;
             }
-        }
-
-        if (count($data_elements) == 1) {
-            $data_string = $data_elements[0];
         } else {
-            $data_string = '(' . join(' ', $data_elements) . ')';
+            $cmd = 'SETANNOTATION ';
+
+            foreach ($data as $md_entry => $value) {
+                list($entry, $type) = $this->_getAnnotateMoreEntry($md_entry);
+                $i_value = is_null($value)
+                    ? 'NIL'
+                    : $this->utils->escape($value);
+                $data_elements[] = $this->utils->escape($entry) . ' (' . $this->utils->escape($type) . ' ' . $i_value . ')';
+            }
         }
 
-        /**
-         * Disallow multi-line data for now.
-         * @todo: Support this with sending literal data.
-         */
+        $data_string = (count($data_elements) == 1)
+            ? $data_elements[0]
+            : '(' . join(' ', $data_elements) . ')';
+
+        /* Disallow multi-line data for now.
+         * @todo: Support this with sending literal data. */
         $data_string = str_replace("\n", '', $data_string);
 
         $this->_sendLine($cmd . $this->utils->escape($mailbox) . ' ' . $data_string);
@@ -3122,6 +3162,8 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base
      * Parse a METADATA response (RFC 5464 [4.4]).
      *
      * @param array $data  The server response.
+     *
+     * @throws Horde_Imap_Client_Exception
      */
     protected function _parseMetadata($data)
     {
@@ -3134,14 +3176,17 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base
                 case 'value.priv':
                     $this->_temp['metadata'][$data[1]]['/private' . $data[2]] = array_shift($values);
                     break;
+
                 case 'value.shared':
                     $this->_temp['metadata'][$data[1]]['/shared' . $data[2]] = array_shift($values);
                     break;
+
                 default:
                     throw new Horde_Imap_Client_Exception('Invalid METADATA value type ' . $type);
                 }
             }
             break;
+
         case 'METADATA':
             $values = $data[2];
             while (!empty($values)) {
@@ -3675,7 +3720,7 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base
 
             case 'ANNOTATION':
             case 'METADATA':
-                // Parse a ANNOTATEMORE/METADATA response (RFC 5464).
+                // Parse a ANNOTATEMORE/METADATA response.
                 $this->_parseMetadata($ob['token']);
                 break;
 
index 3e29685..0f7ccac 100644 (file)
@@ -1184,6 +1184,37 @@ class Horde_Imap_Client_Socket_Pop3 extends Horde_Imap_Client_Base
         throw new Horde_Imap_Client_Exception('IMAP ACLs not supported on POP3 servers.', Horde_Imap_Client_Exception::POP3_NOTSUPPORTED);
     }
 
+    /**
+     * Get metadata for a given mailbox.
+     *
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $entries   The entries to fetch.
+     * @param array $options   Additional options.
+     *
+     * @return array  An array with identifiers as the keys and the
+     *                metadata as the values.
+     * @throws Horde_Imap_Client_Exception
+     */
+     protected function _getMetadata($mailbox, $entries, $options)
+     {
+        throw new Horde_Imap_Client_Exception('IMAP metadata not supported on POP3 servers.', Horde_Imap_Client_Exception::POP3_NOTSUPPORTED);
+     }
+
+    /**
+     * Set metadata for a given mailbox/identifier.
+     *
+     * @param string $mailbox  A mailbox (UTF7-IMAP).
+     * @param array $data      A set of data values. The metadata values
+     *                         corresponding to the keys of the array will
+     *                         be set to the values in the array.
+     *
+     * @throws Horde_Imap_Client_Exception
+     */
+    protected function _setMetadata($mailbox, $data)
+    {
+        throw new Horde_Imap_Client_Exception('IMAP metadata not supported on POP3 servers.', Horde_Imap_Client_Exception::POP3_NOTSUPPORTED);
+    }
+
     /* Internal functions. */
 
     /**
index 8c628d7..6671f61 100644 (file)
@@ -760,10 +760,7 @@ try {
 
 print "\nSet METADATA on " . $test_mbox . ".\n";
 try {
-    $imap_client->setMetadata($test_mbox,
-                              array('/shared/comment' => 'test'),
-                              array('annotatemore' => true,
-                                    'nocapability' => true));
+    $imap_client->setMetadata($test_mbox, array('/shared/comment' => 'test'));
     print "Set Metadata: OK\n";
 } catch (Horde_Imap_Client_Exception $e) {
     print 'ERROR: ' . $e->getMessage() . "\n";
@@ -772,10 +769,7 @@ try {
 
 print "\nGet METADATA from " . $test_mbox . ".\n";
 try {
-    print_r($imap_client->getMetadata($test_mbox,
-                                      '/shared/comment',
-                                      array('annotatemore' => true,
-                                            'nocapability' => true)));
+    print_r($imap_client->getMetadata($test_mbox, '/shared/comment'));
     print "Get Metadata: OK\n";
 } catch (Horde_Imap_Client_Exception $e) {
     print 'ERROR: ' . $e->getMessage() . "\n";