Clean up the namespace handling and fix generating an IMAP name according to the...
authorGunnar Wrobel <p@rdus.de>
Fri, 17 Dec 2010 22:03:59 +0000 (23:03 +0100)
committerGunnar Wrobel <p@rdus.de>
Tue, 4 Jan 2011 07:54:10 +0000 (08:54 +0100)
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace/Config.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace/Element.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace/Element/Other.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace/Element/Personal.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace/Element/Shared.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace/Element/SharedWithPrefix.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace/Fixed.php
framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder/Namespace/Imap.php
framework/Kolab_Storage/test/Horde/Kolab/Storage/Unit/Folder/NamespaceTest.php

index 094e10a..6878145 100644 (file)
@@ -40,56 +40,35 @@ implements Iterator
      *
      * @var array
      */
-    protected $_namespaces = array();
+    private $_namespaces = array();
 
     /**
-     * A prefix in the shared namespaces that will be ignored/removed.
+     * The namespaces with a defined prefix.
      *
-     * @var string
-     */
-    protected $_sharedPrefix;
-
-    /**
-     * The namespace that matches any folder name not matching to another
-     * namespace.
-     *
-     * @var Horde_Kolab_Storage_Folder_Namespace_Element
+     * @var array
      */
-    protected $_any;
+    private $_prefix_namespaces = array();
 
     /**
-     * Indicates the personal namespace that the class will use to create new
-     * folders.
+     * The fallback namespace matching any path if no other namesace matches.
      *
      * @var Horde_Kolab_Storage_Folder_Namespace_Element
      */
-    protected $_primaryPersonalNamespace;
-
-    /**
-     * A helper for iteration over the namespaces.
-     *
-     * @var array
-     */
-    protected $_iteration;
+    private $_any;
 
     /**
      * Constructor.
+     *
+     * @param array $namespaces The namespaces.
      */
-    public function __construct()
+    public function __construct(array $namespaces)
     {
-        if (empty($this->_primaryPersonalNamespace)) {
-            $personal = null;
-            foreach ($this->_namespaces as $namespace) {
-                if ($namespace->getName() == 'INBOX') {
-                    $this->_primaryPersonalNamespace = $namespace;
-                    break;
-                }
-                if (empty($personal) && $namespace->getType() == self::PERSONAL) {
-                    $personal = $namespace;
-                }
-            }
-            if (empty($this->_primaryPersonalNamespace)) {
-                $this->_primaryPersonalNamespace = $personal;
+        $this->_namespaces = $namespaces;
+        foreach ($this->_namespaces as $namespace) {
+            if ($namespace->getName() == '') {
+                $this->_any = $namespace;
+            } else {
+                $this->_prefix_namespaces[] = $namespace;
             }
         }
     }
@@ -106,7 +85,7 @@ implements Iterator
      */
     public function matchNamespace($name)
     {
-        foreach ($this->_namespaces as $namespace) {
+        foreach ($this->_prefix_namespaces as $namespace) {
             if ($namespace->matches($name)) {
                 return $namespace;
             }
@@ -131,6 +110,32 @@ implements Iterator
     }
 
     /**
+     * Return the owner of a folder.
+     *
+     * @param string $name The name of the folder.
+     *
+     * @return string The owner of the folder.
+     */
+    public function getOwner($name)
+    {
+        $name = Horde_String::convertCharset($name, 'UTF7-IMAP', 'UTF-8');
+        return $this->matchNamespace($name)->getOwner($name);
+    }
+
+    /**
+     * Get the sub path for the given folder name.
+     *
+     * @param string $name The folder name.
+     *
+     * @return string The sub path.
+     */
+    public function getSubpath($name)
+    {
+        $name = Horde_String::convertCharset($name, 'UTF7-IMAP', 'UTF-8');
+        return $this->matchNamespace($name)->getSubpath($name);
+    }
+
+    /**
      * Return the title of a folder.
      *
      * @param string $name The name of the folder.
@@ -144,75 +149,129 @@ implements Iterator
     }
 
     /**
-     * Return the owner of a folder.
+     * Generate an IMAP folder name in the personal namespace.
      *
-     * @param string $name The name of the folder.
+     * @param string $title The new folder title.
      *
-     * @return string The owner of the folder.
+     * @return string The IMAP folder name.
      */
-    public function getOwner($name)
+    public function setTitle($title)
     {
-        $name = Horde_String::convertCharset($name, 'UTF7-IMAP', 'UTF-8');
-        return $this->matchNamespace($name)->getOwner($name);
+        return $this->_setTitle(self::PERSONAL, explode(':', $title));
     }
 
     /**
-     * Get the sub path for the given folder name.
+     * Generate an IMAP folder name in the other namespace.
      *
-     * @param string $name The folder name.
+     * @param string $title The new folder title.
+     * @param string $owner The new owner of the folder.
      *
-     * @return string The sub path.
+     * @return string The IMAP folder name.
      */
-    public function getSubpath($name)
+    public function setTitleInOther($title, $owner)
     {
-        $name = Horde_String::convertCharset($name, 'UTF7-IMAP', 'UTF-8');
-        return $this->matchNamespace($name)->getSubpath($name);
+        $path = explode(':', $title);
+        array_unshift($path, $owner);
+        return $this->_setTitle(self::OTHER, $path);
     }
 
     /**
-     * Generate an IMAP folder name.
+     * Generate an IMAP folder name in the shared namespace.
      *
-     * @param string $name The new folder name.
+     * @param string $title The new folder title.
      *
      * @return string The IMAP folder name.
      */
-    public function setName($name)
+    public function setTitleInShared($title)
     {
-        $namespace = $this->matchNamespace($name);
-        $path = explode(':', $name);
-        if (empty($this->_sharedPrefix)
-            || (strpos($path[0], $this->_sharedPrefix) === false
-                && $namespace->getType() != self::OTHER)) {
-            array_unshift($path, $this->_primaryPersonalNamespace->getName());
-            $namespace = $this->_primaryPersonalNamespace;
+        return $this->_setTitle(self::SHARED, explode(':', $title));
+    }
+
+    /**
+     * Generate an IMAP folder name in the specified namespace.
+     *
+     * @param string $type     The namespace type.
+     * @param array  $elements The new path elements.
+     *
+     * @return string The IMAP folder name.
+     */
+    private function _setTitle($type, array $elements)
+    {
+        $matching = array();
+        foreach ($this->_namespaces as $namespace) {
+            if ($namespace->getType() == $type) {
+                $matching[] = $namespace;
+            }
         }
-        return Horde_String::convertCharset($namespace->generateName($path), 'UTF-8', 'UTF7-IMAP');
+        if (count($matching) == 1) {
+            $selection = $matching[0];
+        } else if (count($matching) > 1) {
+            throw new Horde_Kolab_Storage_Exception(
+                'Specifying the folder path via title is not supported with multiple namespaces of the same type!'
+            );
+        } else {
+            throw new Horde_Kolab_Storage_Exception(
+                sprintf(
+                    'No namespace of the type %s!',
+                    $type
+                )
+            );
+        }
+        return Horde_String::convertCharset(
+            $selection->generateName($elements),
+            'UTF-8',
+            'UTF7-IMAP'
+        );
     }
 
-    function rewind()
+    /**
+     * Implementation of the Iterator rewind() method. Rewinds the namespace list.
+     *
+     * return NULL
+     */
+    public function rewind()
     {
-        $this->_iterator = $this->_namespaces;
-        $this->_iterator[] = $this->_any;
-        return reset($this->_iterator);
+        return reset($this->_namespaces);
     }
 
-    function current()
+    /**
+     * Implementation of the Iterator current(). Returns the current namespace.
+     *
+     * @return Horde_Kolab_Storage_Folder_Namespace_Element|null The current namespace.
+     */
+    public function current()
     {
-        return current($this->_iterator);
+        return current($this->_namespaces);
     }
 
-    function key()
+    /**
+     * Implementation of the Iterator key() method. Returns the key of the current namespace.
+     *
+     * @return mixed The key for the current position.
+     */
+    public function key()
     {
-        return key($this->_iterator);
+        return key($this->_namespaces);
     }
 
-    function next()
+    /**
+     * Implementation of the Iterator next() method. Returns the next namespace.
+     *
+     * @return Horde_Kolab_Storage_Folder_Namespace_Element|null The next
+     * namespace or null if there are no more namespaces.
+     */
+    public function next()
     {
-        return next($this->_iterator);
+        return next($this->_namespaces);
     }
 
-    function valid()
+    /**
+     * Implementation of the Iterator valid() method. Indicates if the current element is a valid element.
+     *
+     * @return boolean Whether the current element is valid
+     */
+    public function valid()
     {
-        return key($this->_iterator) !== null;
+        return key($this->_namespaces) !== null;
     }
 }
\ No newline at end of file
index 635a7ef..2d147a3 100644 (file)
@@ -16,7 +16,7 @@
  * The Horde_Kolab_Storage_Folder_Namespace_Config:: allows to configure the available
  * IMAP namespaces on the Kolab server.
  *
- * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
@@ -35,26 +35,19 @@ extends  Horde_Kolab_Storage_Folder_Namespace
      */
     public function __construct(array $configuration)
     {
-        parent::__construct();
+        $namespace = array();
         foreach ($configuration as $element) {
             if ($element['type'] == Horde_Kolab_Storage_Folder_Namespace::SHARED
                 && isset($element['prefix'])) {
                 $namespace_element = new Horde_Kolab_Storage_Folder_Namespace_Element_SharedWithPrefix(
                     $element['name'], $element['delimiter'], $element['prefix']
                 );
-                $this->_sharedPrefix = $element['prefix'];
             } else {
                 $class = 'Horde_Kolab_Storage_Folder_Namespace_Element_' . ucfirst($element['type']);
                 $namespace_element = new $class($element['name'], $element['delimiter']);
             }
-            if (empty($element['name'])) {
-                $this->_any = $namespace_element;
-            } else {
-                $this->_namespaces[] = $namespace_element;
-            }
-            if (isset($element['add'])) {
-                $this->_primaryPersonalNamespace = $namespace_element;
-            }
+            $namespaces[] = $namespace_element;
         }
+        parent::__construct($namespaces);
     }
 }
\ No newline at end of file
index 3b35bf1..67790f0 100644 (file)
@@ -1,5 +1,30 @@
 <?php
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element:: class represents a namespace type.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element:: class represents a namespace type.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 abstract class Horde_Kolab_Storage_Folder_Namespace_Element
 {
     /**
@@ -129,6 +154,9 @@ abstract class Horde_Kolab_Storage_Folder_Namespace_Element
      */
     public function generateName($path)
     {
+        if (!empty($this->_name)) {
+            array_unshift($path, $this->_name);
+        }
         return join($path, $this->_delimiter);
     }
 
index 10ddcb7..00258e8 100644 (file)
@@ -1,5 +1,32 @@
 <?php
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element_Other:: class represents the
+ * namespace for folders of other users.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element_Other:: class represents the
+ * namespace for folders of other users.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 class Horde_Kolab_Storage_Folder_Namespace_Element_Other
 extends Horde_Kolab_Storage_Folder_Namespace_Element
 {
index 97987f9..5c3156d 100644 (file)
@@ -1,5 +1,32 @@
 <?php
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element_Personal:: class represents
+ * the namespace for folders owned by the currently authenticated user.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element_Personal:: class represents
+ * the namespace for folders owned by the currently authenticated user.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 class Horde_Kolab_Storage_Folder_Namespace_Element_Personal
 extends Horde_Kolab_Storage_Folder_Namespace_Element
 {
index 4d8d532..feda5a0 100644 (file)
@@ -1,5 +1,32 @@
 <?php
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element_Shared:: class represents
+ * the shared namespace.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element_Shared:: class represents
+ * the shared namespace.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 class Horde_Kolab_Storage_Folder_Namespace_Element_Shared
 extends Horde_Kolab_Storage_Folder_Namespace_Element
 {
index df70727..70c9a58 100644 (file)
@@ -1,5 +1,32 @@
 <?php
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element_Shared:: class represents
+ * the shared namespace and hides the prefix of that shared namespace.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 
+/**
+ * The Horde_Kolab_Storage_Folder_Namespace_Element_Shared:: class represents
+ * the shared namespace and hides the prefix of that shared namespace.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Kolab
+ * @package  Kolab_Storage
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Storage
+ */
 class Horde_Kolab_Storage_Folder_Namespace_Element_SharedWithPrefix
 extends Horde_Kolab_Storage_Folder_Namespace_Element_Shared
 {
@@ -38,4 +65,16 @@ extends Horde_Kolab_Storage_Folder_Namespace_Element_Shared
         }
         return $path;
     }
+
+    /**
+     * Generate a folder path for the given path in this namespace.
+     *
+     * @param array $path The path of the folder.
+     *
+     * @return string The name of the folder.
+     */
+    public function generateName($path)
+    {
+        return $this->_prefix . parent::generateName($path);
+    }
 }
\ No newline at end of file
index fb20abf..338ba74 100644 (file)
@@ -16,7 +16,7 @@
  * The Horde_Kolab_Storage_Folder_Namespace_Fixed:: implements the default IMAP
  * namespaces on the Kolab server.
  *
- * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
@@ -31,27 +31,16 @@ class Horde_Kolab_Storage_Folder_Namespace_Fixed
 extends  Horde_Kolab_Storage_Folder_Namespace
 {
     /**
-     * Indicates the personal namespace that the class will use to create new
-     * folders.
-     *
-     * @var string
-     */
-    protected $_primaryPersonalNamespace = 'INBOX';
-
-    /**
      * Constructor.
      */
     public function __construct()
     {
-        parent::__construct();
-
-        $personal = new Horde_Kolab_Storage_Folder_Namespace_Element_Personal('INBOX/', '/');
-        $other    = new Horde_Kolab_Storage_Folder_Namespace_Element_Other('user/', '/');
-        $shared   = new Horde_Kolab_Storage_Folder_Namespace_Element_SharedWithPrefix('', '/', 'shared.');
-
-        $this->_namespaces = array($personal, $other);
-        $this->_any = $shared;
-        $this->_primaryPersonalNamespace = $personal;
-        $this->_sharedPrefix = 'shared.';
+        parent::__construct(
+            array(
+                new Horde_Kolab_Storage_Folder_Namespace_Element_Personal('INBOX/', '/'),
+                new Horde_Kolab_Storage_Folder_Namespace_Element_Other('user/', '/'),
+                new Horde_Kolab_Storage_Folder_Namespace_Element_SharedWithPrefix('', '/', 'shared.')
+            )
+        );
     }
 }
\ No newline at end of file
index c178b20..86ec1aa 100644 (file)
@@ -18,7 +18,7 @@
  * the IMAP NAMESPACE command to identify the IMAP namespaces on the Kolab
  * server.
  *
- * Copyright 2004-2010 The Horde Project (http://www.horde.org/)
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
index f8ae4d3..c14278c 100644 (file)
@@ -88,7 +88,7 @@ extends Horde_Kolab_Storage_TestCase
                 ->method('getAuth')
                 ->will($this->returnValue('test'));
             $folder = $this->_getFolder(null, $namespace);
-            $folder->setName('test');
+            $folder->setTitle('test');
             $this->assertEquals('test', $folder->getTitle());
         }
     }
@@ -146,7 +146,7 @@ extends Horde_Kolab_Storage_TestCase
                 ->method('getAuth')
                 ->will($this->returnValue('test'));
             $folder = $this->_getFolder(null, $namespace);
-            $folder->setName('test');
+            $folder->setTitle('test');
             $this->assertEquals('test', $folder->getOwner());
         }
     }
@@ -170,51 +170,51 @@ extends Horde_Kolab_Storage_TestCase
         }
     }
 
-    public function testSetnameDefaultPersonalNS()
+    public function testSettitleDefaultPersonalNS()
     {
         foreach ($this->_getNamespaces() as $namespace) {
             $folder = $this->_getFolder(null, $namespace);
-            $folder->setName('test:this');
-            $this->assertEquals('INBOX/test/this', $folder->getName());
+            $folder->setTitle('test:this');
+            $this->assertEquals('INBOX/test/this', $folder->getPath());
         }
     }
 
-    public function testSetnameSeparator()
+    public function testSettitleSeparator()
     {
         foreach ($this->_getNamespaces() as $namespace) {
             $folder = $this->_getFolder(null, $namespace);
-            $folder->setName('a:b:c');
-            $this->assertEquals('INBOX/a/b/c', $folder->getName());
+            $folder->setTitle('a:b:c');
+            $this->assertEquals('INBOX/a/b/c', $folder->getPath());
         }
     }
 
-    public function testSetnameUtf7()
+    public function testSettitleUtf7()
     {
         foreach ($this->_getNamespaces() as $namespace) {
             $folder = $this->_getFolder(null, $namespace);
-            $folder->setName('äöü');
+            $folder->setTitle('äöü');
             $this->assertEquals(
                 'INBOX/äöü',
-                Horde_String::convertCharset($folder->getName(), 'UTF7-IMAP', 'UTF8')
+                Horde_String::convertCharset($folder->getPath(), 'UTF7-IMAP', 'UTF8')
             );
         }
     }
 
-    public function testSetnameInSharedNS()
+    public function testSettitleInSharedNS()
     {
         foreach ($this->_getNamespaces() as $namespace) {
             $folder = $this->_getFolder(null, $namespace);
-            $folder->setName('shared.test');
-            $this->assertEquals('shared.test', $folder->getName());
+            $folder->setTitleInShared('test');
+            $this->assertEquals('shared.test', $folder->getPath());
         }
     }
 
-    public function testSetnameInOthersNS()
+    public function testSettitleInOthersNS()
     {
         foreach ($this->_getNamespaces() as $namespace) {
             $folder = $this->_getFolder(null, $namespace);
-            $folder->setName('user:test:test');
-            $this->assertEquals('user/test/test', $folder->getName());
+            $folder->setTitleInOther('test', 'test');
+            $this->assertEquals('user/test/test', $folder->getPath());
         }
     }
 
@@ -222,7 +222,7 @@ extends Horde_Kolab_Storage_TestCase
     {
         foreach ($this->_getNamespaces() as $namespace) {
             $folder = $this->_getFolder(null, $namespace);
-            $folder->setName('test');
+            $folder->setTitle('test');
             $this->assertEquals('test', $folder->getSubpath());
         }
     }