From 04e0e03ff9bbd7998c4d89d2e8407094755eb68e Mon Sep 17 00:00:00 2001 From: Gunnar Wrobel Date: Tue, 20 Oct 2009 09:49:57 +0200 Subject: [PATCH] Basic refactoring of Kolab_Server completed. Many tests still need fixing and some classes need to be completed too. --- framework/Kolab_Server/lib/Horde/Kolab/Server.php | 53 +- .../Kolab_Server/lib/Horde/Kolab/Server/Base.php | 327 ------ .../lib/Horde/Kolab/Server/Composite.php | 109 ++ .../lib/Horde/Kolab/Server/Exception.php | 16 +- .../Novalue.php} | 6 +- .../lib/Horde/Kolab/Server/Factory.php | 54 +- .../Kolab_Server/lib/Horde/Kolab/Server/Ldap.php | 133 ++- .../lib/Horde/Kolab/Server/Ldap/Changes.php | 99 ++ .../lib/Horde/Kolab/Server/{ => Ldap}/File.php | 0 .../lib/Horde/Kolab/Server/{ => Ldap}/Filtered.php | 19 +- .../Horde/Kolab/Server/{Test.php => Ldap/Mock.php} | 8 +- .../lib/Horde/Kolab/Server/{ => Ldap}/Standard.php | 15 +- .../Kolab_Server/lib/Horde/Kolab/Server/Logged.php | 80 +- .../Kolab_Server/lib/Horde/Kolab/Server/Mapped.php | 20 + .../Kolab_Server/lib/Horde/Kolab/Server/Object.php | 1132 +------------------- .../lib/Horde/Kolab/Server/Object/Attribute.php | 89 ++ .../Horde/Kolab/Server/Object/Attribute/Base.php | 130 +++ .../Server/Object/Attribute/Createtimestamp.php | 47 + .../Object/Attribute/Createtimestampdate.php | 40 + .../Kolab/Server/Object/Attribute/Decorator.php | 128 +++ .../Kolab/Server/Object/Attribute/Default.php | 70 ++ .../Horde/Kolab/Server/Object/Attribute/Empty.php | 42 + .../Kolab/Server/Object/Attribute/External.php | 53 + .../Horde/Kolab/Server/Object/Attribute/Field.php | 151 +++ .../Horde/Kolab/Server/Object/Attribute/Guid.php | 54 + .../lib/Horde/Kolab/Server/Object/Attribute/Id.php | 56 + .../Kolab/Server/Object/Attribute/Internal.php | 45 + .../Horde/Kolab/Server/Object/Attribute/Locked.php | 58 + .../Server/Object/Attribute/Modifytimestamp.php | 47 + .../Object/Attribute/Modifytimestampdate.php | 40 + .../Kolab/Server/Object/Attribute/Objectclass.php | 53 + .../Kolab/Server/Object/Attribute/Openldapaci.php | 47 + .../Kolab/Server/Object/Attribute/Required.php | 53 + .../Horde/Kolab/Server/Object/Attribute/Single.php | 47 + .../Horde/Kolab/Server/Object/Attribute/Value.php | 84 ++ .../Kolab/Server/Object/Attribute/Writelock.php | 53 + .../lib/Horde/Kolab/Server/Object/Base.php | 251 +++++ .../lib/Horde/Kolab/Server/Object/Factory.php | 73 ++ .../lib/Horde/Kolab/Server/Object/Groupofnames.php | 8 +- .../lib/Horde/Kolab/Server/Object/Hash.php | 203 ++++ .../Horde/Kolab/Server/Object/Inetorgperson.php | 6 +- .../Server/Object/Kolabgermanbankarrangement.php | 12 +- .../Kolab/Server/Object/Kolabgroupofnames.php | 4 +- .../Kolab/Server/Object/Kolabinetorgperson.php | 6 +- .../Horde/Kolab/Server/Object/Kolabpop3account.php | 10 +- .../lib/Horde/Kolab/Server/Object/Mcached.php | 288 +++++ .../lib/Horde/Kolab/Server/Object/Person.php | 6 +- .../Horde/Kolab/Server/Object/Search.php} | 20 +- .../Kolab/Server/Object/Search/Attributes.php | 48 + .../lib/Horde/Kolab/Server/Object/Search/Base.php | 62 ++ .../Horde/Kolab/Server/Object/Search/Children.php | 56 + .../Server/Object/Search/Constraint/Single.php | 59 + .../Server/Object/Search/Constraint/Strict.php | 68 ++ .../lib/Horde/Kolab/Server/Object/Search/Guid.php | 48 + .../lib/Horde/Kolab/Server/Object/Searches.php | 46 + .../lib/Horde/Kolab/Server/Object/Top.php | 136 +++ .../lib/Horde/Kolab/Server/Objects.php | 8 + .../lib/Horde/Kolab/Server/Objects/Base.php | 2 +- .../lib/Horde/Kolab/Server/Query/Ldap.php | 2 +- .../Kolab_Server/lib/Horde/Kolab/Server/Schema.php | 27 +- .../Kolab_Server/lib/Horde/Kolab/Server/Search.php | 8 + .../lib/Horde/Kolab/Server/Search/Base.php | 38 +- .../lib/Horde/Kolab/Server/Structure.php | 18 +- .../lib/Horde/Kolab/Server/Structure/Base.php | 108 +- .../lib/Horde/Kolab/Server/Structure/Kolab.php | 70 +- .../lib/Horde/Kolab/Server/Structure/Ldap.php | 75 +- framework/Kolab_Server/package.xml | 177 ++- .../test/Horde/Kolab/Server/AllTests.php | 7 +- .../test/Horde/Kolab/Server/Attribute/BaseTest.php | 109 ++ .../Horde/Kolab/Server/Attribute/ValueTest.php | 244 +++++ .../test/Horde/Kolab/Server/Autoload.php | 33 +- .../Kolab/Server/Connection/SplittedldapTest.php | 2 +- .../test/Horde/Kolab/Server/LdapBase.php | 7 + .../test/Horde/Kolab/Server/LdapTest.php | 230 ---- .../Server/{ => Object}/AddingObjectsTest.php | 4 +- .../Horde/Kolab/Server/{ => Object}/AdminTest.php | 4 +- .../test/Horde/Kolab/Server/Object/BaseTest.php | 359 +++++++ .../Server/{ => Object}/DistListHandlingTest.php | 4 +- .../Server/{ => Object}/GroupHandlingTest.php | 4 +- .../Horde/Kolab/Server/{ => Object}/GroupTest.php | 4 +- .../Server/{ => Object}/InetorgpersonTest.php | 4 +- .../KolabgermanbankarrangementTest.php | 4 +- .../Server/{ => Object}/KolabinetorgpersonTest.php | 4 +- .../Server/{ => Object}/Kolabpop3accountTest.php | 4 +- .../Horde/Kolab/Server/{ => Object}/ObjectTest.php | 4 +- .../Kolab/Server/{ => Object}/OrgPersonTest.php | 4 +- .../Horde/Kolab/Server/{ => Object}/PersonTest.php | 6 +- .../Kolab/Server/{ => Object}/UserHandlingTest.php | 4 +- .../Horde/Kolab/Server/{ => Object}/UserTest.php | 4 +- .../test/Horde/Kolab/Server/Query/ElementTest.php | 8 +- .../test/Horde/Kolab/Server/Query/LdapTest.php | 8 + .../test/Horde/Kolab/Server/Scenario.php | 1 + .../Kolab/Server/{Server => Search}/SearchTest.php | 14 +- .../test/Horde/Kolab/Server/Server/FactoryTest.php | 5 + .../Horde/Kolab/Server/Server/FilteredTest.php | 125 +++ .../test/Horde/Kolab/Server/Server/LdapTest.php | 511 +++++---- .../test/Horde/Kolab/Server/Server/LoggedTest.php | 34 +- .../Server/Server/{TestTest.php => MockTest.php} | 4 +- .../test/Horde/Kolab/Server/Server/ServerTest.php | 207 +--- .../Horde/Kolab/Server/Server/StandardTest.php | 124 +++ .../test/Horde/Kolab/Server/ServerTest.php | 328 ------ .../Horde/Kolab/Server/Structure/KolabTest.php | 349 ++++++ .../test/Horde/Kolab/Server/Structure/LdapTest.php | 140 +++ .../test/Horde/Kolab/Server/TestTest.php | 624 ----------- 104 files changed, 5481 insertions(+), 3451 deletions(-) delete mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Base.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Composite.php rename framework/Kolab_Server/lib/Horde/Kolab/Server/{MissingObjectException.php => Exception/Novalue.php} (76%) create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Changes.php rename framework/Kolab_Server/lib/Horde/Kolab/Server/{ => Ldap}/File.php (100%) rename framework/Kolab_Server/lib/Horde/Kolab/Server/{ => Ldap}/Filtered.php (77%) rename framework/Kolab_Server/lib/Horde/Kolab/Server/{Test.php => Ldap/Mock.php} (98%) rename framework/Kolab_Server/lib/Horde/Kolab/Server/{ => Ldap}/Standard.php (71%) create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Base.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Createtimestamp.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Createtimestampdate.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Decorator.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Default.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Empty.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/External.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Field.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Guid.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Id.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Internal.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Locked.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Modifytimestamp.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Modifytimestampdate.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Objectclass.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Openldapaci.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Required.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Single.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Value.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Writelock.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Base.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Factory.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Hash.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Mcached.php rename framework/Kolab_Server/{test/Horde/Kolab/Server/Server/InterfaceTest.php => lib/Horde/Kolab/Server/Object/Search.php} (70%) create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Attributes.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Base.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Children.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Constraint/Single.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Constraint/Strict.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Guid.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Searches.php create mode 100644 framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Top.php create mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/Attribute/BaseTest.php create mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/Attribute/ValueTest.php delete mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/LdapTest.php rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/AddingObjectsTest.php (90%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/AdminTest.php (96%) create mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/Object/BaseTest.php rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/DistListHandlingTest.php (89%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/GroupHandlingTest.php (99%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/GroupTest.php (96%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/InetorgpersonTest.php (98%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/KolabgermanbankarrangementTest.php (97%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/KolabinetorgpersonTest.php (99%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/Kolabpop3accountTest.php (98%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/ObjectTest.php (98%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/OrgPersonTest.php (98%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/PersonTest.php (98%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/UserHandlingTest.php (99%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{ => Object}/UserTest.php (95%) rename framework/Kolab_Server/test/Horde/Kolab/Server/{Server => Search}/SearchTest.php (95%) create mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/Server/FilteredTest.php rename framework/Kolab_Server/test/Horde/Kolab/Server/Server/{TestTest.php => MockTest.php} (99%) create mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/Server/StandardTest.php delete mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/ServerTest.php create mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/Structure/KolabTest.php create mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/Structure/LdapTest.php delete mode 100644 framework/Kolab_Server/test/Horde/Kolab/Server/TestTest.php diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server.php b/framework/Kolab_Server/lib/Horde/Kolab/Server.php index facd7fe44..32cdbff9d 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server.php @@ -37,7 +37,21 @@ interface Horde_Kolab_Server * * @throws Horde_Kolab_Server_Exception If the connection failed. */ - public function connectGuid($guid = null, $pass = null); + public function connectGuid($guid = '', $pass = ''); + + /** + * Get the current GUID + * + * @return string The GUID of the currently connected user. + */ + public function getGuid(); + + /** + * Get the base GUID of this server + * + * @return string The base GUID of this server. + */ + public function getBaseGuid(); /** * Low level access to reading object data. @@ -79,31 +93,31 @@ interface Horde_Kolab_Server /** * Finds object data matching a given set of criteria. * - * @param Horde_Kolab_Server_Query $query The criteria for the search. - * @param array $params Additional search parameters. + * @param Horde_Kolab_Server_Query_Element $criteria The criteria for the search. + * @param array $params Additional search parameters. * * @return Horde_Kolab_Server_Result The result object. * * @throws Horde_Kolab_Server_Exception */ public function find( - Horde_Kolab_Server_Query $query, + Horde_Kolab_Server_Query_Element $criteria, array $params = array() ); /** * Finds all object data below a parent matching a given set of criteria. * - * @param Horde_Kolab_Server_Query $query The criteria for the search. - * @param string $parent The parent to search below. - * @param array $params Additional search parameters. + * @param Horde_Kolab_Server_Query_Element $criteria The criteria for the search. + * @param string $parent The parent to search below. + * @param array $params Additional search parameters. * * @return Horde_Kolab_Server_Result The result object. * * @throws Horde_Kolab_Server_Exception */ public function findBelow( - Horde_Kolab_Server_Query $query, + Horde_Kolab_Server_Query_Element $criteria, $parent, array $params = array() ); @@ -111,26 +125,28 @@ interface Horde_Kolab_Server /** * Modify existing object data. * - * @param string $guid The GUID of the object to be added. - * @param array $data The attributes of the object to be stored. + * @param Horde_Kolab_Server_Object $object The object to be modified. + * @param array $data The attributes of the object + * to be stored. * * @return NULL * * @throws Horde_Kolab_Server_Exception */ - public function save($guid, array $data); + public function save(Horde_Kolab_Server_Object $object, array $data); /** * Add new object data. * - * @param string $guid The GUID of the object to be added. - * @param array $data The attributes of the object to be added. + * @param Horde_Kolab_Server_Object $object The object to be added. + * @param array $data The attributes of the object + * to be added. * * @return NULL * * @throws Horde_Kolab_Server_Exception */ - public function add($guid, array $data); + public function add(Horde_Kolab_Server_Object $object, array $data); /** * Delete an object. @@ -163,4 +179,13 @@ interface Horde_Kolab_Server * @throws Horde_Kolab_Server_Exception If retrieval of the schema failed. */ public function getSchema(); + + /** + * Get the parent GUID of this object. + * + * @param string $guid The GUID of the child. + * + * @return string the parent GUID of this object. + */ + public function getParentGuid($guid); } \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Base.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Base.php deleted file mode 100644 index 6f244cefe..000000000 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Base.php +++ /dev/null @@ -1,327 +0,0 @@ - - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ - -/** - * This class provides methods to deal with Kolab objects stored in - * the Kolab object db. - * - * Copyright 2008-2009 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_Server - * @author Gunnar Wrobel - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ -abstract class Horde_Kolab_Server_Base implements Horde_Kolab_Server, - Horde_Kolab_Server_Objects, - Horde_Kolab_Server_Schema, - Horde_Kolab_Server_Search, - Horde_Kolab_Server_Structure -{ - /** - * Server parameters. - * - * @var array - */ - protected $params = array(); - - /** - * The user name of the current user. - * - * @var string - */ - private $_user = null; - - /** - * The structure handler for this server. - * - * @var Horde_Kolab_Server_Structure - */ - protected $structure; - - /** - * The search handler for this server. - * - * @var Horde_Kolab_Server_Search - */ - protected $search; - - /** - * The object handler for this server. - * - * @var Horde_Kolab_Server_Objects - */ - protected $objects; - - /** - * The data cache. - * - * @var mixed - */ - protected $cache = null; - - /** - * Construct a new Horde_Kolab_Server object. - * - * @param array $params Parameter array. - */ - public function __construct( - Horde_Kolab_Server_Objects $objects, - Horde_Kolab_Server_Structure $structure, - Horde_Kolab_Server_Search $search, - Horde_Kolab_Server_Schema $schema - ) { - $objects->setServer($this); - $structure->setServer($this); - $search->setServer($this); - $schema->setServer($this); - - $this->objects = $objects; - $this->structure = $structure; - $this->search = $search; - $this->schema = $schema; - } - - /** - * Set configuration parameters. - * - * @param array $params The parameters. - * - * @return NULL - */ - public function setParams(array $params) - { - $this->params = array_merge($this->params, $params); - - if (isset($this->params['uid'])) { - $this->uid = $this->params['uid']; - } - } - - /** - * Set the cache handler. - * - * @param mixed $cache The cache handler. - * - * @return NULL - */ - public function setCache($cache) - { - $this->cache = $cache; - } - - /** - * Connect to the server. - * - * @param string $user The user name. - * @param string $pass The password. - * - * @return NULL. - * - * @throws Horde_Kolab_Server_Exception If the connection failed. - */ - public function connect($user = null, $pass = null) - { - /** Do we need to switch the user? */ - if ($user !== $this->_current_user) { - $this->user = $this->_connect($user, $pass); - } - } - - /** - * Connect to the server. - * - * @param string $uid The unique id of the user. - * @param string $pass The password. - * - * @return NULL. - * - * @throws Horde_Kolab_Server_Exception If the connection failed. - */ - public function connectUid($uid = null, $pass = null) - { - } - - /** - * Add a Kolab object. - * - * @param array $info The object to store. - * - * @return Kolab_Object The newly created Kolab object. - * - * @throws Horde_Kolab_Server_Exception If the type of the object to add has - * been left undefined or the object - * already exists. - */ - public function add(array $info) - { - return $this->objects->add($info); - } - - /** - * Fetch a Kolab object. - * - * @param string $uid The UID of the object to fetch. - * @param string $type The type of the object to fetch. - * - * @return Kolab_Object The corresponding Kolab object. - * - * @throws Horde_Kolab_Server_Exception - */ - public function fetch($uid = null, $type = null) - { - return $this->objects->fetch($uid = null, $type = null); - } - - /** - * List all objects of a specific type - * - * @param string $type The type of the objects to be listed - * @param array $params Additional parameters. - * - * @return array An array of Kolab objects. - * - * @throws Horde_Kolab_Server_Exception - */ - public function listObjects($type, $params = null) - { - return $this->objects->listObjects($type, $params = null); - } - - /** - * Generate a hash representation for a list of objects. - * - * @param string $type The type of the objects to be listed - * @param array $params Additional parameters. - * - * @return array An array of Kolab objects. - * - * @throws Horde_Kolab_Server_Exception - */ - public function listHash($type, $params = null) - { - return $this->objects->listHash($type, $params = null); - } - - /** - * Returns the set of objects supported by this server. - * - * @return array An array of supported objects. - */ - public function getSupportedObjects() - { - return $this->structure->getSupportedObjects(); - } - - /** - * Determine the type of an object by its tree position and other - * parameters. - * - * @param string $uid The UID of the object to examine. - * - * @return string The class name of the corresponding object type. - * - * @throws Horde_Kolab_Server_Exception If the object type is unknown. - */ - public function determineType($uid) - { - return $this->structure->determineType($uid); - } - - /** - * Generates a UID for the given information. - * - * @param string $type The class name of the object to create. - * @param string $id The id of the object. - * @param array $info Any additional information about the object to create. - * - * @return string The UID. - * - * @throws Horde_Kolab_Server_Exception - */ - public function generateServerUid($type, $id, $info) - { - return $this->structure->generateServerUid($type, $id, $info); - } - - /** - * Return the schema for the given objectClass. - * - * @param string $objectclass Fetch the schema for this objectClass. - * - * @return array The schema for the given objectClass. - * - * @throws Horde_Kolab_Server_Exception If retrieval of the schema failed. - */ - public function getObjectclassSchema($objectclass) - { - return $this->schema->getObjectclassSchema($objectclass); - } - - /** - * Return the schema for the given attribute. - * - * @param string $attribute Fetch the schema for this attribute. - * - * @return array The schema for the given attribute. - * - * @throws Horde_Kolab_Server_Exception If retrieval of the schema failed. - */ - public function getAttributeSchema($attribute) - { - return $this->schema->getAttributeSchema($attribute); - } - - /** - * Return the attributes supported by the given object class. - * - * @param string $class Determine the attributes for this class. - * - * @return array The supported attributes. - * - * @throws Horde_Kolab_Server_Exception If the schema analysis fails. - */ - public function &getAttributes($class) - { - return $this->schema->getAttributes($class); - } - - /** - * Returns the set of search operations supported by this server type. - * - * @return array An array of supported search operations. - */ - public function getSearchOperations() - { - return $this->search->getSearchOperations(); - } - - /** - * Capture undefined calls and assume they refer to a search operation. - * - * @param string $method The name of the called method. - * @param array $args Arguments of the call. - * - * @return NULL. - * - * @throws Horde_Kolab_Server_Exception - */ - public function __call($method, $args) - { - return $this->search->__call($method, $args); - } -} diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Composite.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Composite.php new file mode 100644 index 000000000..058af2500 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Composite.php @@ -0,0 +1,109 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * A simple composition of server functionality. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Composite +{ + /** + * The server. + * + * @var Horde_Kolab_Server + */ + public $server; + + /** + * The structure handler for this server. + * + * @var Horde_Kolab_Server_Structure + */ + public $structure; + + /** + * The search handler for this server. + * + * @var Horde_Kolab_Server_Search + */ + public $search; + + /** + * The object handler for this server. + * + * @var Horde_Kolab_Server_Objects + */ + public $objects; + + /** + * The schema handler for this server. + * + * @var Horde_Kolab_Server_Schema + */ + public $schema; + + /** + * Construct a new Horde_Kolab_Server object. + * + * @param array $params Parameter array. + */ + public function __construct( + Horde_Kolab_Server $server, + Horde_Kolab_Server_Objects $objects, + Horde_Kolab_Server_Structure $structure, + Horde_Kolab_Server_Search $search, + Horde_Kolab_Server_Schema $schema + ) { + $this->server = $server; + $this->objects = $objects; + $this->structure = $structure; + $this->search = $search; + $this->schema = $schema; + + $structure->setComposite($this); + $search->setComposite($this); + $schema->setComposite($this); + $objects->setComposite($this); + } + + /** + * Connect to the server. Use this method if the user name you can provide + * does not match a DN. In this case it will be required to map this user + * name first. + * + * @param string $user The user name. + * @param string $pass The password. + * + * @return NULL. + * + * @throws Horde_Kolab_Server_Exception If the connection failed. + */ + protected function _connect($user = null, $pass = null) + { + /** Bind anonymously first. */ + $this->connectUid(); + $guid = $this->structure->getGuidForUser($user); + $this->connectUid($guid, $pass); + return $this->structure->getUserForUser($user); + } +} diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Exception.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Exception.php index 44260dddc..1f86d5a93 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Exception.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Exception.php @@ -32,18 +32,22 @@ class Horde_Kolab_Server_Exception extends Horde_Exception */ /** Unknown error type */ - const SYSTEM = 1; + const SYSTEM = 1; /** The LDAP extension is missing */ - const MISSING_LDAP_EXTENSION = 2; + const MISSING_LDAP_EXTENSION = 2; /** Binding to the LDAP server failed */ - const BIND_FAILED = 3; + const BIND_FAILED = 3; - const EMPTY_RESULT = 4; + /** The resultset was empty */ + const EMPTY_RESULT = 4; - const INVALID_INFORMATION = 5; + const INVALID_INFORMATION = 5; - const INVALID_QUERY = 6; + /** The query was invalid */ + const INVALID_QUERY = 6; + /** The search yielded too many results */ + const SEARCH_CONSTRAINT_TOO_MANY = 7; } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/MissingObjectException.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Exception/Novalue.php similarity index 76% rename from framework/Kolab_Server/lib/Horde/Kolab/Server/MissingObjectException.php rename to framework/Kolab_Server/lib/Horde/Kolab/Server/Exception/Novalue.php index dac9f3b42..17caaeadb 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/MissingObjectException.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Exception/Novalue.php @@ -1,6 +1,6 @@ setInstance('Horde_Kolab_Server_Logger', $instance); } - if (empty($this->_ldap_read)) { - $this->handleError( - Net_LDAP2::checkLDAPExtension(), - Horde_Kolab_Server_Exception::MISSING_LDAP_EXTENSION - ); - - $this->_ldap_read = new Net_LDAP2($this->params); - - if (isset($this->params['host_master']) - && $this->params['host_master'] == $this->params['host'] - ) { - - $params = $this->params; - $params['host'] = $this->params['host_master']; - - $this->_ldap_write = new Net_LDAP2($params); - } else { - $this->_ldap_write = $this->_ldap_read; - } - } - - if ($write) { - return $this->_ldap_write; - } else { - return $this->_ldap_read; - } - /** * Setup the machinery to create a Horde_Kolab_Server. * @@ -319,6 +292,33 @@ class Horde_Kolab_Server_Factory ); } +/* if (empty($this->_ldap_read)) { */ +/* $this->handleError( */ +/* Net_LDAP2::checkLDAPExtension(), */ +/* Horde_Kolab_Server_Exception::MISSING_LDAP_EXTENSION */ +/* ); */ + +/* $this->_ldap_read = new Net_LDAP2($this->params); */ + +/* if (isset($this->params['host_master']) */ +/* && $this->params['host_master'] == $this->params['host'] */ +/* ) { */ + +/* $params = $this->params; */ +/* $params['host'] = $this->params['host_master']; */ + +/* $this->_ldap_write = new Net_LDAP2($params); */ +/* } else { */ +/* $this->_ldap_write = $this->_ldap_read; */ +/* } */ +/* } */ + +/* if ($write) { */ +/* return $this->_ldap_write; */ +/* } else { */ +/* return $this->_ldap_read; */ +/* } */ + return self::$_instances[$signature]; } } \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap.php index 8294e2e9b..0e76479ef 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap.php @@ -31,9 +31,9 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server /** * The GUID of the current user. * - * @var string + * @var string|boolean */ - private $_guid; + private $_guid = false; /** * LDAP connection handle. @@ -76,12 +76,10 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server * * @throws Horde_Kolab_Server_Exception If the connection failed. */ - public function connectGuid($guid = null, $pass = null) + public function connectGuid($guid = '', $pass = '') { /** Do we need to switch the user? */ - if ((empty($guid) && empty($this->_guid)) - || $guid !== $this->_guid - ) { + if ($guid !== $this->_guid) { $this->_handleError( $this->_conn->getRead()->bind($guid, $pass), Horde_Kolab_Server_Exception::BIND_FAILED @@ -91,6 +89,26 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server } /** + * Get the current GUID + * + * @return string The GUID of the connected user. + */ + public function getGuid() + { + return $this->_guid; + } + + /** + * Get the base GUID of this server + * + * @return string The base GUID of this server. + */ + public function getBaseGuid() + { + return $this->_base_dn; + } + + /** * Low level access to reading object data. * * @param string $guid The object to retrieve. @@ -103,14 +121,15 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server public function read($guid) { $params = array('scope' => 'base'); - $data = $this->_search(null, $params, $guid)->asArray(); + $data = $this->_search(null, $params, $guid); if ($data->count() == 0) { throw new Horde_Kolab_Server_Exception( 'Empty result!', Horde_Kolab_Server_Exception::EMPTY_RESULT ); - } - return array_pop($data->asArray()); + } + $result = $data->asArray(); + return array_pop($result); } /** @@ -136,59 +155,48 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server 'Empty result!', Horde_Kolab_Server_Exception::EMPTY_RESULT ); - } - return array_pop($data->asArray()); + } + $result = $data->asArray(); + return array_pop($result); } /** * Finds object data matching a given set of criteria. * - * @param Horde_Kolab_Server_Query $query The criteria for the search. - * @param array $params Additional search parameters. + * @param Horde_Kolab_Server_Query_Element $criteria The criteria for the search. + * @param array $params Additional search parameters. * * @return Horde_Kolab_Server_Result The result object. * * @throws Horde_Kolab_Server_Exception */ public function find( - Horde_Kolab_Server_Query $query, + Horde_Kolab_Server_Query_Element $criteria, array $params = array() ) { - $this->findBelow($query, $this->_base_dn, $params); + return $this->findBelow($criteria, $this->_base_dn, $params); } /** - * Finds all object data below a parent matching a given set of criteria. - * - * @param Horde_Kolab_Server_Query $query The criteria for the search. - * @param string $parent The parent to search below. - * @param array $params Additional search parameters. - * - * @return Horde_Kolab_Server_Result The result object. - * - * @throws Horde_Kolab_Server_Exception - */ - abstract public function findBelow( - Horde_Kolab_Server_Query $query, - $parent, - array $params = array() - ); - - /** * Modify existing object data. * - * @param string $guid The GUID of the object to be added. - * @param array $data The attributes of the object to be stored. + * @param Horde_Kolab_Server_Object $object The object to be modified. + * @param array $data The attributes of the object + * to be stored. * * @return NULL * * @throws Horde_Kolab_Server_Exception */ - public function save($guid, array $data) + public function save(Horde_Kolab_Server_Object $object, array $data) { - $entry = $this->_conn->getWrite()->getEntry($guid, $data['attributes']); + $entry = $this->_conn->getWrite()->getEntry( + $object->getGuid(), array_keys($data) + ); + $this->_handleError($entry, Horde_Kolab_Server_Exception::SYSTEM); + $changes = new Horde_Kolab_Server_Ldap_Changes($object, $data); $this->_handleError( - $this->_conn->getWrite()->modify($entry, $data), + $this->_conn->getWrite()->modify($entry, $changes->getChangeset()), Horde_Kolab_Server_Exception::SYSTEM ); } @@ -196,16 +204,17 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server /** * Add new object data. * - * @param string $guid The GUID of the object to be added. - * @param array $data The attributes of the object to be added. + * @param Horde_Kolab_Server_Object $object The object to be added. + * @param array $data The attributes of the object + * to be added. * * @return NULL * * @throws Horde_Kolab_Server_Exception */ - public function add($guid, array $data) + public function add(Horde_Kolab_Server_Object $object, array $data) { - $entry = Net_LDAP2_Entry::createFresh($guid, $data); + $entry = Net_LDAP2_Entry::createFresh($object->getGuid(), $data); $this->_handleError($entry, Horde_Kolab_Server_Exception::SYSTEM); $this->_handleError( $this->_conn->getWrite()->add($entry), @@ -243,7 +252,7 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server public function rename($guid, $new) { $this->_handleError( - $this->_conn->getWrite()->move($old, $new), + $this->_conn->getWrite()->move($guid, $new), Horde_Kolab_Server_Exception::SYSTEM ); } @@ -263,6 +272,32 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server } /** + * Get the parent GUID of this object. + * + * @param string $guid The GUID of the child. + * + * @return string the parent GUID of this object. + */ + public function getParentGuid($guid) + { + $base = Net_LDAP2_Util::ldap_explode_dn( + $guid, + array( + 'casefold' => 'none', + 'reverse' => false, + 'onlyvalues' => false + ) + ); + $this->_handleError($base); + $id = array_shift($base); + $parent = Net_LDAP2_Util::canonical_dn( + $base, array('casefold' => 'none') + ); + $this->_handleError($parent); + return $parent; + } + + /** * Check for a PEAR Error and convert it to an exception if necessary. * * @param mixed $result The result to be tested. @@ -276,7 +311,7 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server $result, $code = Horde_Kolab_Server_Exception::SYSTEM ) { - if (is_a($result, 'PEAR_Error')) { + if ($result instanceOf PEAR_Error) { throw new Horde_Kolab_Server_Exception($result, $code); } } @@ -293,14 +328,10 @@ abstract class Horde_Kolab_Server_Ldap implements Horde_Kolab_Server * @throws Horde_Kolab_Server_Exception If the search operation encountered * a problem. */ - private function _search($filter, array $params, $base) + protected function _search($filter, array $params, $base) { - $this->_lastSearch = &$this->_conn->getRead()->search( - $base, $filter, $params - ); - $this->_handleError( - $this->_lastSearch, Horde_Kolab_Server_Exception::SYSTEM - ); - return new Horde_Kolab_Server_Result_Ldap($this->_lastSearch); + $search = $this->_conn->getRead()->search($base, $filter, $params); + $this->_handleError($search, Horde_Kolab_Server_Exception::SYSTEM); + return new Horde_Kolab_Server_Result_Ldap($search); } } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Changes.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Changes.php new file mode 100644 index 000000000..8664f1f85 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Changes.php @@ -0,0 +1,99 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * A helper class to determine an LDAP changeset. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Ldap_Changes +{ + + /** + * The object to be modified. + * + * @var Horde_Kolab_Server_Object + */ + private $_object; + + /** + * The new dataset. + * + * @var array + */ + private $_data; + + /** + * Constructor. + * + * @param Horde_Kolab_Server_Object $object The object to be modified. + * @param array $data The attributes of the object + * to be stored. + */ + public function __construct(Horde_Kolab_Server_Object $object, array $data) + { + $this->_object = $object; + $this->_data = $data; + } + + /** + * Return an LDAP changeset from the difference between the current object + * data and the new dataset. + * + * @return array The LDAP changeset. + */ + public function getChangeset() + { + $cs = array(); + $old = $this->_object->readInternal(); + $new = $this->_data; + $attributes = array_merge(array_keys($old), array_keys($new)); + foreach ($attributes as $attribute) { + if (!isset($old[$attribute])) { + $cs['add'][] = array($attribute => $new[$attribute]); + continue; + } + if (!isset($new[$attribute])) { + $cs['delete'][] = $attribute; + continue; + } + if (count($new[$attribute]) == 1 + && count($old[$attribute]) == 1) { + if ($new[$attribute][0] == $old[$attribute][0]) { + continue; + } else { + $cs['replace'][$attribute] = $new[$attribute][0]; + continue; + } + } + $adds = array_diff($new[$attribute], $old[$attribute]); + if (!empty($adds)) { + $cs['add'][$attribute] = array_values($adds); + } + $deletes = array_diff($old[$attribute], $new[$attribute]); + if (!empty($deletes)) { + $cs['delete'][$attribute] = array_values($deletes); + } + } + return $cs; + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/File.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/File.php similarity index 100% rename from framework/Kolab_Server/lib/Horde/Kolab/Server/File.php rename to framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/File.php diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Filtered.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Filtered.php similarity index 77% rename from framework/Kolab_Server/lib/Horde/Kolab/Server/Filtered.php rename to framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Filtered.php index ab77cbede..2858c9f82 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Filtered.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Filtered.php @@ -26,7 +26,7 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Filtered extends Horde_Kolab_Server_Ldap +class Horde_Kolab_Server_Ldap_Filtered extends Horde_Kolab_Server_Ldap { /** * A global filter to add to each query. @@ -55,21 +55,22 @@ class Horde_Kolab_Server_Filtered extends Horde_Kolab_Server_Ldap /** * Finds all object data below a parent matching a given set of criteria. * - * @param array $criteria The criteria for the search. - * @param string $parent The parent to search below. - * @param array $params Additional search parameters. + * @param Horde_Kolab_Server_Query_Element $criteria The criteria for the search. + * @param string $parent The parent to search below. + * @param array $params Additional search parameters. * * @return Horde_Kolab_Server_Result The result object. * * @throws Horde_Kolab_Server_Exception */ - public function findBelow(array $criteria, $parent, array $params = array()) - { + public function findBelow( + Horde_Kolab_Server_Query_Element $criteria, + $parent, + array $params = array() + ) { $query = new Horde_Kolab_Server_Query_Ldap($criteria); $query_string = (string) $query; - if (!empty($this->_filter)) { - $query_string = '(&(' . $this->_filter . ')' . $query_string . ')'; - } + $query_string = '(&(' . $this->_filter . ')' . $query_string . ')'; return $this->_search($query_string, $params, $parent); } } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Test.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Mock.php similarity index 98% rename from framework/Kolab_Server/lib/Horde/Kolab/Server/Test.php rename to framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Mock.php index 461ccc17f..ddcbc322f 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Test.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Mock.php @@ -25,7 +25,7 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Test extends Horde_Kolab_Server_Ldap +class Horde_Kolab_Server_Ldap_Mock extends Horde_Kolab_Server_Ldap_Standard { /** @@ -418,7 +418,7 @@ class Horde_Kolab_Server_Test extends Horde_Kolab_Server_Ldap } break; default: - throw new Horde_Kolab_Server_Exception(_("Not implemented!")); + throw new Horde_Kolab_Server_Exception("Not implemented!"); } } } @@ -477,7 +477,7 @@ class Horde_Kolab_Server_Test extends Horde_Kolab_Server_Ldap } return $result; default: - throw new Horde_Kolab_Server_Exception(_("Not implemented!")); + throw new Horde_Kolab_Server_Exception("Not implemented!"); } } } @@ -864,7 +864,7 @@ class Horde_Kolab_Server_Test extends Horde_Kolab_Server_Ldap switch ($restrict) { case self::RESULT_STRICT: if (count($dns) > 1) { - throw new Horde_Kolab_Server_Exception(sprintf(_("Found %s results when expecting only one!"), + throw new Horde_Kolab_Server_Exception(sprintf("Found %s results when expecting only one!", $count)); } case self::RESULT_SINGLE: diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Standard.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Standard.php similarity index 71% rename from framework/Kolab_Server/lib/Horde/Kolab/Server/Standard.php rename to framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Standard.php index d4e94370e..dd448dbf0 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Standard.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap/Standard.php @@ -26,21 +26,24 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Standard extends Horde_Kolab_Server_Ldap +class Horde_Kolab_Server_Ldap_Standard extends Horde_Kolab_Server_Ldap { /** * Finds all object data below a parent matching a given set of criteria. * - * @param array $criteria The criteria for the search. - * @param string $parent The parent to search below. - * @param array $params Additional search parameters. + * @param Horde_Kolab_Server_Query_Element $criteria The criteria for the search. + * @param string $parent The parent to search below. + * @param array $params Additional search parameters. * * @return Horde_Kolab_Server_Result The result object. * * @throws Horde_Kolab_Server_Exception */ - public function findBelow(array $criteria, $parent, array $params = array()) - { + public function findBelow( + Horde_Kolab_Server_Query_Element $criteria, + $parent, + array $params = array() + ) { $query = new Horde_Kolab_Server_Query_Ldap($criteria); return $this->_search((string) $query, $params, $parent); } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Logged.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Logged.php index 072642bc1..fdd194b32 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Logged.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Logged.php @@ -67,7 +67,27 @@ class Horde_Kolab_Server_Logged implements Horde_Kolab_Server */ public function connectGuid($guid = null, $pass = null) { - $this->_server->connectGuid($guid, $pass); + $this->_server->connectGuid($guid, $pass); + } + + /** + * Get the current GUID + * + * @return string The GUID of the connected user. + */ + public function getGuid() + { + $this->_server->getGuid(); + } + + /** + * Get the base GUID of this server + * + * @return string The base GUID of this server. + */ + public function getBaseGuid() + { + $this->_server->getBaseGuid(); } /** @@ -106,72 +126,80 @@ class Horde_Kolab_Server_Logged implements Horde_Kolab_Server /** * Finds object data matching a given set of criteria. * - * @param Horde_Kolab_Server_Query $query The criteria for the search. - * @param array $params Additional search parameters. + * @param Horde_Kolab_Server_Query_Element $criteria The criteria for the search. + * @param array $params Additional search parameters. * * @return Horde_Kolab_Server_Result The result object. * * @throws Horde_Kolab_Server_Exception */ public function find( - Horde_Kolab_Server_Query $query, + Horde_Kolab_Server_Query_Element $criteria, array $params = array() ) { - return $this->_server->find($query, $params); + return $this->_server->find($criteria, $params); } /** * Finds all object data below a parent matching a given set of criteria. * - * @param Horde_Kolab_Server_Query $query The criteria for the search. - * @param string $parent The parent to search below. - * @param array $params Additional search parameters. + * @param Horde_Kolab_Server_Query_Element $criteria The criteria for the search. + * @param string $parent The parent to search below. + * @param array $params Additional search parameters. * * @return Horde_Kolab_Server_Result The result object. * * @throws Horde_Kolab_Server_Exception */ public function findBelow( - Horde_Kolab_Server_Query $query, + Horde_Kolab_Server_Query_Element $criteria, $parent, array $params = array() ) { - return $this->_server->findBelow($query, $parent, $params); + return $this->_server->findBelow($criteria, $parent, $params); } /** * Modify existing object data. * - * @param string $guid The GUID of the object to be added. - * @param array $data The attributes of the object to be added. + * @param Horde_Kolab_Server_Object $object The object to be modified. + * @param array $data The attributes of the object + * to be stored. * * @return NULL * * @throws Horde_Kolab_Server_Exception */ - public function save($guid, array $data) + public function save(Horde_Kolab_Server_Object $object, array $data) { - $this->_server->save($guid, $data); + $this->_server->save($object, $data); $this->_logger->info( - sprintf("The object \"%s\" has been successfully saved!", $guid) + sprintf( + "The object \"%s\" has been successfully saved!", + $object->getGuid() + ) ); } /** * Add new object data. * - * @param string $guid The GUID of the object to be added. - * @param array $data The attributes of the object to be added. + * @param Horde_Kolab_Server_Object $object The object to be added. + * @param array $data The attributes of the object + * to be added. * * @return NULL * * @throws Horde_Kolab_Server_Exception */ - public function add($guid, array $data) + public function add(Horde_Kolab_Server_Object $object, array $data) { - $this->_server->add($guid, $data); + $this->_server->add($object, $data); $this->_logger->info( - sprintf("The object \"%s\" has been successfully added!", $guid) + sprintf( + "The object \"%s\" has been successfully added!", + $object->getGuid() + ) ); } @@ -224,4 +252,16 @@ class Horde_Kolab_Server_Logged implements Horde_Kolab_Server { return $this->_server->getSchema(); } + + /** + * Get the parent GUID of this object. + * + * @param string $guid The GUID of the child. + * + * @return string the parent GUID of this object. + */ + public function getParentGuid($guid) + { + return $this->_server->getParentGuid($guid); + } } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Mapped.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Mapped.php index 5287b592d..456653edb 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Mapped.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Mapped.php @@ -86,6 +86,26 @@ class Horde_Kolab_Server_Mapped implements Horde_Kolab_Server } /** + * Get the current GUID + * + * @return string The GUID of the connected user. + */ + public function getGuid() + { + $this->_server->getGuid(); + } + + /** + * Get the base GUID of this server + * + * @return string The base GUID of this server. + */ + public function getBaseGuid() + { + $this->_server->getBaseGuid(); + } + + /** * Low level access to reading object data. * * @param string $guid The object to retrieve. diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php index 193c4cac9..93248fb65 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php @@ -1,7 +1,6 @@ array( - self::ATTRIBUTE_OC, - self::ATTRIBUTE_CREATIONDATE, - self::ATTRIBUTE_MODIFICATIONDATE, - self::ATTRIBUTE_ACI, - ), - /** - * Derived attributes are calculated based on other attribute values. - */ - 'derived' => array( - self::ATTRIBUTE_UID => array( - 'method' => 'getUid', - ), - self::ATTRIBUTE_ID => array( - 'method' => 'getId', - ), - self::ATTRDATE_CREATIONDATE => array( - 'method' => 'getDate', - 'args' => array( - self::ATTRIBUTE_CREATIONDATE, - ), - ), - self::ATTRDATE_MODIFICATIONDATE => array( - 'method' => 'getDate', - 'args' => array( - self::ATTRIBUTE_MODIFICATIONDATE, - ), - ), - ), - /** - * Attributes that are written using the information from several other - * attributes. - */ - 'collapsed' => array( - ), - /** - * Attributes that are required for this object type. It is not - * guaranteed that this setting takes effect as this module can be - * configured to only trust the schema returned from the server. - */ - 'required' => array( - self::ATTRIBUTE_OC, - ), - /** - * Default values for attributes without a value. - */ - 'defaults' => array( - ), - /** - * Locked attributes. These are fixed after the object has been stored - * once. They may not be modified again. - */ - 'locked' => array( - self::ATTRIBUTE_ID, - self::ATTRIBUTE_OC, - ), - /** - * The object classes representing this object. - */ - 'object_classes' => array( - self::OBJECTCLASS_TOP, - ), - ); - - /** - * Sort by this attributes (must be a LDAP attribute). - * - * @var string - */ - var $sort_by = self::ATTRIBUTE_UID; - - /** - * Initialize the Kolab Object. Provide either the UID or a - * LDAP search result. - * - * @param Horde_Kolab_Server &$server The link into the Kolab server. - * @param string $uid UID of the object. - * @param array $data A possible array of data for the object - */ - public function __construct(&$server, $uid = null, $data = false) - { - $this->server = &$server; - if (empty($uid)) { - if (isset($data[self::ATTRIBUTE_UID])) { - if (is_array($data[self::ATTRIBUTE_UID])) { - $this->uid = $data[self::ATTRIBUTE_UID][0]; - } else { - $this->uid = $data[self::ATTRIBUTE_UID]; - } - } else { - $this->uid = $this->server->generateServerUid(get_class($this), - $this->generateId($data), - $data); - } - } else { - $this->uid = $uid; - } - $this->_cache = $data; - - list($this->attributes, $this->attribute_map) = $server->getAttributes(get_class($this)); - } - - /** - * Attempts to return a concrete Horde_Kolab_Server_Object instance based on - * $type. - * - * @param mixed $type The type of the Horde_Kolab_Server_Object subclass - * to return. - * @param string $uid UID of the object - * @param array &$storage A link to the Kolab_Server class handling read/write. - * @param array $data A possible array of data for the object - * - * @return Horde_Kolab_Server_Object|PEAR_Error The newly created concrete - * Horde_Kolab_Server_Object instance. - */ - static public function &factory($type, $uid, &$storage, $data = null) - { - $result = Horde_Kolab_Server_Object::loadClass($type); - - if (class_exists($type)) { - $object = new $type($storage, $uid, $data); - } else { - throw new Horde_Kolab_Server_Exception('Class definition of ' . $type . ' not found.'); - } - - return $object; - } + public function getGuid(); /** - * Attempts to load the concrete Horde_Kolab_Server_Object class based on - * $type. - * - * @param mixed $type The type of the Horde_Kolab_Server_Object subclass. + * Get the external attributes supported by this object. * - * @static - * - * @return true|PEAR_Error True if successfull. + * @return array The external attributes supported by this object. This is a + * list of abbreviated attribute class names. */ - static public function loadClass($type) - { - if (!class_exists($type)) { - throw new Horde_Kolab_Server_Exception('Class definition of ' . $type . ' not found.'); - } - } + public function getExternalAttributes(); /** - * Return the filter string to retrieve this object type. - * - * @static + * Get the internal attributes supported by this object. * - * @return string The filter to retrieve this object type from the server - * database. + * @return array The internal attributes supported by this object. This is + * an association of internal attribute names an the correspodning attribute + * class names. */ - public static function getFilter() - { - $criteria = array('AND' => array(array('field' => self::ATTRIBUTE_OC, - 'op' => '=', - 'test' => self::OBJECTCLASS_TOP), - ), - ); - return $criteria; - } + public function getInternalAttributes(); /** * Does the object exist? * - * @return NULL + * @return boolean True if the object exists, false otherwise. */ - public function exists() - { - try { - return $this->read(); - } catch (Horde_Kolab_Server_Exception $e) { - return false; - } - } + public function exists(); /** * Read the object into the cache * - * @return NULL + * @return array The read data. */ - protected function read() - { - if (empty($this->uid)) { - return false; - } - if (empty($this->_exists)) { - if (!empty($this->attributes)) { - $attributes = array_keys($this->attributes); - } else { - $attributes = null; - } - $result = $this->server->read($this->uid, - $attributes); - /** - * If reading the server data was unsuccessfull we should keep the - * initial data in our cache. If reading was successfull we should - * merge with the initial cache setting. - */ - if (is_array($this->_cache) && is_array($result)) { - $this->_cache = array_merge($this->_cache, $result); - } else if (!is_array($this->_cache)) { - $this->_cache = $result; - } - $this->_exists = true; - } - return $this->_exists; - } - - /** - * Get the specified attribute of this object - * - * @param string $attr The attribute to read - * @param boolean $single Should only a single attribute be returned? - * - * @return string the value of this attribute - * - * @todo: This needs to be magic - */ - public function get($attr, $single = true) - { - if (!empty($this->attributes) - && !in_array($attr, array_keys($this->attributes)) - && !empty($this->attribute_map['derived']) - && !in_array($attr, $this->attribute_map['derived'])) { - throw new Horde_Kolab_Server_Exception(sprintf(_("Attribute \"%s\" not supported!"), - $attr)); - } - - $this->exists(); - - if (!empty($this->attribute_map['derived']) - && in_array($attr, $this->attribute_map['derived'])) { - return $this->derive($attr); - } - - return $this->_get($attr, $single); - } + public function readInternal(); /** * Get the specified attribute of this object * - * @param string $attr The attribute to read - * @param boolean $single Should a single value be returned - * or are multiple values allowed? - * - * @return string the value of this attribute - */ - protected function _get($attr, $single = true) - { - if (isset($this->_cache[$attr])) { - if (empty($this->_cache[$attr])) { - return false; - } else if ($single && is_array($this->_cache[$attr])) { - return $this->_cache[$attr][0]; - } else { - return $this->_cache[$attr]; - } - } - return false; - } - - /** - * Derive an attribute value. - * - * @param string $attr The attribute to derive. - * - * @return mixed The value of the attribute. - */ - protected function derive($attr) - { - if (isset($this->attributes[$attr]['method'])) { - if (isset($this->attributes[$attr]['args'])) { - $args = $this->attributes[$attr]['args']; - } else { - $args = array(); - } - //FIXME: Fill the cache here - return call_user_func_array(array($this, - $this->attributes[$attr]['method']), - $args); - } - return false; - } - - /** - * Collapse derived values back into the main attributes. - * - * @param string $key The attribute to collapse into. - * @param array $attributes The attributes to collapse. - * @param array $info The information currently working on. - * - * @return NULL. - */ - protected function collapse($key, $attributes, &$info) - { - $changes = false; - foreach ($attributes['base'] as $attribute) { - if (isset($info[$attribute])) { - $changes = true; - break; - } - } - if ($changes) { - if (isset($attributes['method'])) { - $args = array($key, $attributes['base'], &$info); - if (isset($attributes['args'])) { - $args = array_merge($args, $attributes['args']); - } - //FIXME: Fill the cache here - return call_user_func_array(array($this, - $attributes['method']), - $args); - } - } - } - - /** - * Quote field separators within a LDAP value. - * - * @param string $string The string that should be quoted. - * - * @return string The quoted string. - */ - protected function quote($string) - { - return str_replace(array('\\', '$',), - array('\\5c', '\\24',), - $string); - } - - /** - * Unquote a LDAP value. - * - * @param string $string The string that should be unquoted. - * - * @return string The unquoted string. - */ - protected function unquote($string) - { - return str_replace(array('\\5c', '\\24',), - array('\\', '$',), - $string); - } - - /** - * Convert the object attributes to a hash. - * - * @param string $attrs The attributes to return. - * @param boolean $single Should only a single attribute be returned? - * - * @return array|PEAR_Error The hash representing this object. - */ - public function toHash($attrs = null, $single = true) - { - $result = array(); - - /** - * Return all supported attributes if no specific attributes were - * requested. - */ - if (empty($attrs)) { - $attrs = array_keys($this->attributes); - } - - foreach ($attrs as $key) { - $value = $this->get($key, $single); - $result[$key] = $value; - } - - return $result; - } - - /** - * Get the UID of this object - * - * @return string the UID of this object - */ - public function getUid() - { - return $this->uid; - } - - /** - * Get the parent UID of this object - * - * @return string the parent UID of this object - */ - public function getParentUid($level = 1, $uid = null) - { - if (empty($uid)) { - $uid = $this->uid; - } - - $base = Net_LDAP2_Util::ldap_explode_dn($uid, - array('casefold' => 'none', - 'reverse' => false, - 'onlyvalues' => false)); - if ($base instanceOf PEAR_Error) { - throw new Horde_Kolab_Server_Exception($base, - Horde_Kolab_Server_Exception::SYSTEM); - } - $id = array_shift($base); - $parent = Net_LDAP2_Util::canonical_dn($base, array('casefold' => 'none')); - if ($parent instanceOf PEAR_Error) { - throw new Horde_Kolab_Server_Exception($parent, - Horde_Kolab_Server_Exception::SYSTEM); - } - $level--; - if ($level == 0) { - return $parent; - } else { - return $this->getParentUid($level, $parent); - } - } - - /** - * Get the ID of this object - * - * @return string the ID of this object - */ - public function getId() - { - return substr($this->uid, 0, - strlen($this->uid) - strlen($this->server->getBaseUid()) - 1); - } - - /** - * Get a derived attribute value by returning a given position in a - * delimited string. - * - * @param string $basekey Name of the attribute that holds the - * delimited string. - * @param string $field The position of the field to retrieve. - * @param string $separator The field separator. - * @param int $max_count The maximal number of fields. - * - * @return mixed The value of the attribute. - */ - protected function getField($basekey, $field = 0, $separator = '$', $max_count = null) - { - $base = $this->_get($basekey); - if (empty($base)) { - return; - } - if (!empty($max_count)) { - $fields = explode($separator, $base, $max_count); - } else { - $fields = explode($separator, $base); - } - return isset($fields[$field]) ? $this->unquote($fields[$field]) : null; - } - - /** - * Get a derived attribute date by converting it into a Horde_Date object. - * - * @param string $key Name of the attribute that holds the - * date. - * - * @return mixed A Horde_Date object or false if the date was not - * converted successfully. - */ - protected function getDate($key) - { - $date = $this->_get($key); - if (empty($date) || !class_exists('Horde_Date')) { - return false; - } - - $result = new Horde_Date($date); - return $result; - } - - /** - * Set a collapsed attribute value. - * - * @param string $key The attribute to collapse into. - * @param array $attributes The attributes to collapse. - * @param array $info The information currently working on. - * @param string $separator Separate the fields using this character. - * @param boolean $unset Unset the base values. + * @param string $attr The attribute to read * - * @return NULL. + * @return array The value(s) of this attribute */ - protected function setField($key, $attributes, &$info, $separator = '$', $unset = true) - { - /** - * Check how many empty entries we have at the end of the array. We - * may omit these together with their field separators. - */ - krsort($attributes); - $empty = true; - $end = count($attributes); - foreach ($attributes as $attribute) { - /** - * We do not expect the callee to always provide all attributes - * required for a collapsed attribute. So it is necessary to check - * for old values here. - */ - if (!isset($info[$attribute])) { - $old = $this->get($attribute); - if (!empty($old)) { - $info[$attribute] = $old; - } - } - if ($empty && empty($info[$attribute])) { - $end--; - } else { - $empty = false; - } - } - if ($empty) { - return; - } - ksort($attributes); - $unset = $attributes; - $result = ''; - for ($i = 0; $i < $end; $i++) { - $akey = array_shift($attributes); - $value = $info[$akey]; - if (is_array($value)) { - $value = $value[0]; - } - $result .= $this->quote($value); - if ($i != ($end - 1)) { - $result .= $separator; - } - } - if ($unset === true) { - foreach ($unset as $attribute) { - unset($info[$attribute]); - } - } - $info[$key] = $result; - } + public function getInternal($attr); /** - * Simply remove an attribute so that it does not get transported - * to the server (it might have been needed before e.g. ID - * generation). - * - * @param string $key The attribute to collapse into. - * @param array $attributes The attributes to collapse. - * @param array $info The information currently working on. + * Get the specified attribute of this object. * - * @return NULL. - */ - protected function removeAttribute($key, $attributes, &$info) - { - foreach ($attributes as $attribute) { - unset($info[$attribute]); - } - } - - /** - * Get an empty value + * @param string $attr The attribute to read. * - * @return string An empty string. + * @return mixed The value of this attribute. */ - public function getEmpty() - { - return ''; - } - - /** - * Generates an ID for the given information. - * - * @param array &$info The data of the object. - * - * @return string The ID. - */ - public function generateId(&$info) - { - if (!empty($info[self::ATTRIBUTE_ID])) { - if (is_array($info[self::ATTRIBUTE_ID])) { - $id = $info[self::ATTRIBUTE_ID][0]; - } else { - $id = $info[self::ATTRIBUTE_ID]; - } - return $this->server->structure->quoteForUid($id); - } - return $this->server->structure->quoteForUid(hash('sha256', uniqid(mt_rand(), true))); - } + public function getExternal($attr); /** * Saves object information. This may either create a new entry or modify an @@ -728,457 +93,46 @@ class Horde_Kolab_Server_Object * * @param array $info The information about the object. * - * @return boolean True on success. + * @return NULL * * @throws Horde_Kolab_Server_Exception If saving the data failed. */ - public function save($info = null) - { - $info = $this->prepareInformation($info); - - $changes = $this->prepareChanges($info); - - $server = $this->server->getMaster(); - - $result = $server->save($this->uid, $changes, $this->exists()); - - if (!$this->_exists) { - $this->_exists = true; - $this->_cache = $info; - } else { - $this->_cache = array_merge($this->_cache, $info); - } - - return $result; - } + public function save(array $info); /** * Delete this object. * - * @return boolean True if deleting the object succeeded. + * @return NULL * - * @throws Horde_Kolab_Server_Exception + * @throws Horde_Kolab_Server_Exception If deleting the object failed. */ - public function delete() - { - $server = $this->server->getMaster(); - - return $server->delete($this->uid); - } + public function delete(); /** - * Distill the server side object information to save. - * - * @param array $info The information about the object. - * - * @return array The set of information. + * Returns the set of actions supported by this object type. * - * @throws Horde_Kolab_Server_Exception If the given information contains errors. + * @return array An array of supported actions. */ - public function prepareInformation($info) - { - if (empty($info)) { - /** - * If no data to save has been provided the object might have been - * created with initial data. This would have been stored in the - * cache and should be written now. - */ - if (!empty($this->_cache)) { - $info = $this->_cache; - $this->_cache = false; - } else { - return; - } - } - - $this->prepareObjectInformation($info); - - if (!empty($this->attributes)) { - foreach ($info as $key => $value) { - if (!in_array($key, array_keys($this->attributes))) { - throw new Horde_Kolab_Server_Exception(sprintf(_("Attribute \"%s\" not supported!"), - $key)); - } - } - } - - if (!$this->exists()) { - foreach ($this->attribute_map['required'] as $key) { - if (!in_array($key, array_keys($info)) || $info[$key] === null - || $info[$key] === '') { - if (empty($this->attributes[$key]['default'])) { - throw new Horde_Kolab_Server_Exception(sprintf(_("The value for \"%s\" is empty but required!"), - $key)); - } else { - $info[$key] = $this->attributes[$key]['default']; - } - } - } - - $submitted = $info; - foreach ($submitted as $key => $value) { - if ($value === null || $info[$key] === '') { - unset($info[$key]); - } - } - } else { - $all_keys = array_keys($this->attributes); - $submitted = $info; - foreach ($submitted as $key => $value) { - /** - * Empty values are ignored in case there is no old value stored - * or the value is locked. If there is an old value we must - * assume the value was removed. - */ - $old = $this->get($key, false); - if (($value === null || $info[$key] === '') - && (empty($old) - || in_array($key, $this->attribute_map['locked']))) { - unset($info[$key]); - continue; - } - - if (in_array($key, $all_keys)) { - if (!is_array($value) && !is_array($old)) { - if ($value === $old) { - // Unchanged value - unset($info[$key]); - } - } else { - if (!is_array($value)) { - $value = array($value); - $info[$key] = $value; - } - if (!is_array($old)) { - $old = array($old); - } - $changes = $this->getArrayChanges($old, $value); - if (empty($changes)) { - // Unchanged value - unset($info[$key]); - } - } - } - } - - /** - * This ensures that we did not change anything that is locked after creating the element. - */ - foreach ($info as $key => $value) { - if (in_array($key, $this->attribute_map['locked'])) { - throw new Horde_Kolab_Server_Exception(sprintf(_("The value for \"%s\" may not be modified on an existing object!"), - $key)); - } - } - - /* Check for potential renaming of the object here */ - $new_id = $this->generateId($info); - if ($new_id !== false) { - $new_uid = $this->server->generateServerUid(get_class($this), - $new_id, - $info); - if ($new_uid != $this->uid) { - $this->server->rename($this->uid, $new_uid); - $this->uid = $new_uid; - } - } - } - - foreach ($this->attribute_map['collapsed'] as $key => $attributes) { - if ($attributes !== false) { - $this->collapse($key, $attributes, $info); - } - } - return $info; - } + public function getActions(); /** - * Distill the server side object information to save. - * - * @param array $info The information about the object. + * Generates an ID for the given information. * - * @return NULL. + * @param array &$info The data of the object. * - * @throws Horde_Kolab_Server_Exception If the given information contains errors. + * @return string The ID. */ - public function prepareObjectInformation(&$info) - { - } + public function generateId(array &$info); /** - * Prepare the server changes before saving. + * Distill the server side object information to save. * - * @param array $info The information to store. + * @param array &$info The information about the object. * - * @return array The set of changes. Ready for saving. + * @return NULL. * * @throws Horde_Kolab_Server_Exception If the given information contains errors. */ - public function prepareChanges($info) - { - $changes = array(); - - if (!empty($this->attributes)) { - foreach ($info as $key => $value) { - if (!in_array($key, array_keys($this->attributes))) { - throw new Horde_Kolab_Server_Exception(sprintf(_("Attribute \"%s\" not supported!"), - $key)); - } - } - } - - $changes = array(); - if (!$this->exists()) { - $changes['add'] = $info; - } else { - $all_keys = array_keys($this->attributes); - foreach ($info as $key => $value) { - $old = $this->_get($key, false); - if (is_array($value) && count($value) == 1) { - $value = $value[0]; - } - if (is_array($old) && count($old) == 1) { - $old = $old[0]; - } - if ($old === false && !($value === null || $value === '' || $value === array())) { - $changes['add'][$key] = $value; - $changes['attributes'][] = $key; - } else if ($old !== false && ($value === null || $value === '' || $value === array())) { - $changes['delete'][] = $key; - $changes['attributes'][] = $key; - } else if (is_array($old) || is_array($value)) { - if (!is_array($old)) { - $old = array($old); - } - if (!is_array($value)) { - $value = array($value); - } - $adds = array_diff($value, $old); - if (!empty($adds)) { - $changes['add'][$key] = $adds; - $changes['attributes'][] = $key; - } - $deletes = array_diff($old, $value); - if (!empty($deletes)) { - $changes['delete'][$key] = $deletes; - $changes['attributes'][] = $key; - } - } else { - $changes['replace'][$key] = $value; - $changes['attributes'][] = $key; - } - } - } - - if (!empty($changes['attributes'])) { - $changes['attributes'] = array_unique($changes['attributes']); - } - - return $changes; - } - - /** - * Identify changes between two arrays. - * - * @param array $a1 The first array. - * @param array $a2 The second array. - * - * @return array The differences between both arrays. - */ - public function getArrayChanges($a1, $a2) - { - if (empty($a1) || empty($a2)) { - return !empty($a1) ? $a1 : $a2; - } - if (count($a1) != count($a2)) { - $intersection = array_intersect($a1, $a2); - return array_merge(array_diff_assoc($a1, $intersection), - array_diff_assoc($a2, $intersection)); - } - $ar = array(); - foreach ($a2 as $k => $v) { - if (!is_array($v) || !is_array($a1[$k])) { - if ($v !== $a1[$k]) { - $ar[$k] = $v; - } - } else { - if ($arr = $this->getArrayChanges($a1[$k], $a2[$k])) { - $ar[$k] = $arr; - } - } - } - return $ar; - } - - /** - * Identify the UID(s) of the result entry(s). - * - * @param array $result The LDAP search result. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result restriction. - * - * @return boolean|string|array The UID(s) or false if there was no result. - * - * @throws Horde_Kolab_Server_Exception If the number of results did not - * meet the expectations. - */ - static protected function uidFromResult($result, - $restrict = Horde_Kolab_Server_Object::RESULT_SINGLE) - { - if (empty($result)) { - return false; - } - $uids = array_keys($result); - - switch ($restrict) { - case self::RESULT_STRICT: - if (count($uids) > 1) { - throw new Horde_Kolab_Server_Exception(sprintf(_("Found %s results when expecting only one!"), - $count)); - } - case self::RESULT_SINGLE: - return array_pop($uids); - case self::RESULT_MANY: - return $uids; - } - } - - /** - * Get the attributes of the result entry(s). - * - * @param array $result The LDAP search result. - * @param array $attrs The attributes to retrieve. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result restriction. - * - * @return array The attributes of the entry(s) found. - * - * @throws Horde_Kolab_Server_Exception If the number of results did not - * meet the expectations. - */ - static protected function attrsFromResult($result, $attrs, - $restrict = Horde_Kolab_Server_Object::RESULT_SINGLE) - { - switch ($restrict) { - case self::RESULT_STRICT: - if (count($result) > 1) { - throw new Horde_Kolab_Server_Exception(sprintf(_("Found %s results when expecting only one!"), - $count)); - } - case self::RESULT_SINGLE: - if (count($result) > 0) { - return array_pop($result); - } - return array(); - case self::RESULT_MANY: - return $result; - } - return array(); - } - - /** - * Returns the set of search operations supported by this object type. - * - * @return array An array of supported search operations. - */ - static public function getSearchOperations() - { - $searches = array( - 'basicUidForSearch', - 'attrsForSearch', - 'objectsForUid', - ); - return $searches; - } - - /** - * Identify the UID for the first object found using the specified - * search criteria. - * - * @param Horde_Kolab_Server $server The server to query. - * @param array $criteria The search parameters as array. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result - * restriction. - * - * @return boolean|string|array The UID(s) or false if there was no result. - * - * @throws Horde_Kolab_Server_Exception - */ - static public function basicUidForSearch($server, $criteria, - $restrict = Horde_Kolab_Server_Object::RESULT_SINGLE) - { - $params = array('attributes' => self::ATTRIBUTE_UID); - $filter = $server->searchQuery($criteria); - $data = $server->search($filter, $params, $server->getBaseUid()); - return self::uidFromResult($data, $restrict); - } - - /** - * Identify attributes for the objects found using a filter. - * - * @param Horde_Kolab_Server $server The server to query. - * @param array $criteria The search parameters as array. - * @param array $attrs The attributes to retrieve. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result - * restriction. - * - * @return array The results. - * - * @throws Horde_Kolab_Server_Exception - */ - static public function attrsForSearch($server, $criteria, $attrs, - $restrict = Horde_Kolab_Server_Object::RESULT_SINGLE) - { - $params = array('attributes' => $attrs); - $filter = $server->searchQuery($criteria); - $data = $server->search($filter, $params, $server->getBaseUid()); - return self::attrsFromResult($data, $attrs, $restrict); - } - - /** - * Returns the UIDs of the sub objects of the given object class for the - * object with the given uid. - * - * @param Horde_Kolab_Server $server The server to query. - * @param string $uid Returns subobjects for this uid. - * @param string $oc Objectclass of the objects to search. - * - * @return mixed The UIDs or false if there was no result. - * - * @throws Horde_Kolab_Server_Exception - */ - static public function objectsForUid($server, $uid, $oc) - { - $params = array('attributes' => self::ATTRIBUTE_UID); - $criteria = array('AND' => array(array('field' => self::ATTRIBUTE_OC, - 'op' => '=', - 'test' => $oc), - ), - ); - $filter = $server->searchQuery($criteria); - $result = $server->search($filter, $params, $uid); - return self::uidFromResult($result, Horde_Kolab_Server_Object::RESULT_MANY); - } - - /** - * Returns the set of actions supported by this object type. - * - * @return array An array of supported actions. - */ - public function getActions() - { - if (!isset($this->_actions)) { - $this->_actions = $this->_getActions(); - } - return $this->_actions; - } - - /** - * Returns the set of actions supported by this object type. - * - * @return array An array of supported actions. - */ - protected function _getActions() - { - return array(); - } + public function prepareObjectInformation(array &$info); -}; +} diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute.php new file mode 100644 index 000000000..6d6b38ec5 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute.php @@ -0,0 +1,89 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The interface representing Kolab object attributes. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +interface Horde_Kolab_Server_Object_Attribute +{ + /** + * Return the value of this attribute. + * + * @return array The value(s) of this attribute. + * + * @throws Horde_Kolab_Server_Exception If retrieval of the value failed. + */ + public function value(); + + /** + * Return the new internal state for this attribute. + * + * @param array $changes The object data that should be updated. + * + * @return array The resulting internal state. + * + * @throws Horde_Kolab_Server_Exception If storing the value failed. + */ + public function update(array $changes); + + /** + * Return the object this attribute belongs to. + * + * @return Horde_Kolab_Server_Object The object. + */ + public function getObject(); + + /** + * Return the internal name of this attribute. + * + * @return string The name of this object. + */ + public function getInternalName(); + + /** + * Return the external name of this attribute. + * + * @return string The name of this object. + */ + public function getExternalName(); + + /** + * Return if this attribute is undefined in the given data array. + * + * @param array $changes The data array to test. + * + * @return string The name of this object. + */ + public function isEmpty(array $changes); + + /** + * Indicate that a value will be saved by deleting it from the original data + * array. + * + * @param array &$changes The object data that should be changed. + * + * @return NULL + */ + public function consume(array &$changes); +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Base.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Base.php new file mode 100644 index 000000000..f579dffec --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Base.php @@ -0,0 +1,130 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The base class representing Kolab object attributes. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +abstract class Horde_Kolab_Server_Object_Attribute_Base +implements Horde_Kolab_Server_Object_Attribute +{ + /** + * The attribute name on the internal side. + * + * @param string + */ + protected $_internal; + + /** + * The attribute name on the external side. + * + * @param string + */ + private $_external; + + /** + * The object this attribute belongs to. + * + * @param Horde_Kolab_Server_Object + */ + protected $_object; + + /** + * Link to the Kolab server. + * + * @var Horde_Kolab_Server_Composite + */ + protected $_composite; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Object $object The object this attribute + * belongs to. + * @param Horde_Kolab_Server_Composite $composite The link to the server. + * @param string $name The name of this attribute. + */ + public function __construct( + Horde_Kolab_Server_Object $object, + Horde_Kolab_Server_Composite $composite, + $internal, + $external = null + ) { + $this->_internal = $internal; + $this->_object = $object; + $this->_composite = $composite; + $this->_external = $external; + } + + /** + * Return the object this attribute belongs to. + * + * @return Horde_Kolab_Server_Object The object. + */ + public function getObject() + { + return $this->_object; + } + + /** + * Return the internal name of this attribute. + * + * @return string The name of this object. + */ + public function getInternalName() + { + return $this->_internal; + } + + /** + * Return the external name of this attribute. + * + * @return string The name of this object. + */ + public function getExternalName() + { + if (empty($this->_external)) { + $this->_external = substr(get_class($this), 36); + } + return $this->_external; + } + + /** + * Return if this attribute is undefined in the given data array. + * + * @param array $changes The data array to test. + * + * @return string The name of this object. + */ + public function isEmpty(array $changes) + { + $name = $this->getExternalName(); + if ((!in_array($name, array_keys($changes)) + || $changes[$name] === null + || $changes[$name] === '' + || $changes[$name] === array())) { + return true; + } + return false; + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Createtimestamp.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Createtimestamp.php new file mode 100644 index 000000000..c671e8f66 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Createtimestamp.php @@ -0,0 +1,47 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The "createTimestamp" attribute. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Createtimestamp +extends Horde_Kolab_Server_Object_Attribute_External +{ + /** The attribute name */ + const NAME = 'createTimestamp'; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Object $object The object this attribute + * belongs to. + * @param Horde_Kolab_Server_Composite $composite The link to the server. + */ + public function __construct( + Horde_Kolab_Server_Object $object, + Horde_Kolab_Server_Composite $composite + ) { + parent::__construct($object, $composite, self::NAME); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Createtimestampdate.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Createtimestampdate.php new file mode 100644 index 000000000..d1a42ec36 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Createtimestampdate.php @@ -0,0 +1,40 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The "createTimestamp" attribute converted to Horde_Date. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Createtimestampdate +extends Horde_Kolab_Server_Object_Attribute_Createtimestamp +{ + /** + * Return the value of this attribute. + * + * @return mixed The value of this attribute. + */ + public function value() + { + return new Horde_Date(parent::value()); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Decorator.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Decorator.php new file mode 100644 index 000000000..2142c5e37 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Decorator.php @@ -0,0 +1,128 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * A base class for attribute decorators. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Decorator +implements Horde_Kolab_Server_Object_Attribute +{ + /** + * The decorated attribute. + * + * @param Horde_Kolab_Server_Object_Attribute + */ + protected $_attribute; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Object_Attribute $attribute The decorated + * attribute. + */ + public function __construct( + Horde_Kolab_Server_Object_Attribute $attribute + ) { + $this->_attribute = $attribute; + } + + /** + * Return the value of this attribute. + * + * @return array The value(s) of this attribute. + */ + public function value() + { + return $this->_attribute->value(); + } + + /** + * Return the new internal state for this attribute. + * + * @param array $changes The object data that should be updated. + * + * @return array The resulting internal state. + * + * @throws Horde_Kolab_Server_Exception If storing the value failed. + */ + public function update(array $changes) + { + return $this->_attribute->update($changes); + } + + /** + * Return the object this attribute belongs to. + * + * @return Horde_Kolab_Server_Object The object. + */ + public function getObject() + { + return $this->_attribute->getObject(); + } + + /** + * Return the internal name of this attribute. + * + * @return string The name of this object. + */ + public function getInternalName() + { + return $this->_attribute->getInternalName(); + } + + /** + * Return the external name of this attribute. + * + * @return string The name of this object. + */ + public function getExternalName() + { + return $this->_attribute->getExternalName(); + } + + /** + * Return if this attribute is undefined in the given data array. + * + * @param array $changes The data array to test. + * + * @return string The name of this object. + */ + public function isEmpty(array $changes) + { + return $this->_attribute->isEmpty($changes); + } + + /** + * Indicate that a value will be saved by deleting it from the original data + * array. + * + * @param array &$changes The object data that should be changed. + * + * @return NULL + */ + public function consume(array &$changes) + { + return $this->_attribute->consume($changes); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Default.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Default.php new file mode 100644 index 000000000..c9e7608cd --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Default.php @@ -0,0 +1,70 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * A decorator to represent an object attribute with a default. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Default +extends Horde_Kolab_Server_Object_Attribute_Decorator +{ + /** + * The default value for the attribute. + * + * @param mixed + */ + private $_default; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Object_Attribute $attribute The decorated + * attribute. + * @param mixed $default The default value. + */ + public function __construct( + Horde_Kolab_Server_Object_Attribute $attribute, + $default + ) { + $this->_default = $default; + parent::__construct($attribute); + } + + /** + * Return the new internal state for this attribute. + * + * @param array $changes The object data that should be updated. + * + * @return array The resulting internal state. + * + * @throws Horde_Kolab_Server_Exception If storing the value failed. + */ + public function update(array $changes) + { + if (!$this->_attribute->getObject()->exists() + && !$this->_attribute->isEmpty($changes)) { + $changes[$this->_attribute->getExternalName()] = $this->_default; + } + return $this->_attribute->changes($changes); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Empty.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Empty.php new file mode 100644 index 000000000..5ae3057cc --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Empty.php @@ -0,0 +1,42 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The base class representing Kolab object attributes. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Value +extends Horde_Kolab_Server_Object_Attribute_Empty +{ + /** + * Return the value of this attribute. + * + * @return mixed The value of this attribute. + */ + public function value() + { + return ''; + } + + +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/External.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/External.php new file mode 100644 index 000000000..fa1c088d2 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/External.php @@ -0,0 +1,53 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The class represents external-only object attributes. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_External +extends Horde_Kolab_Server_Object_Attribute_Value +{ + /** + * Return the new internal state for this attribute. + * + * @param array $changes The object data that should be updated. + * + * @return array The resulting internal state. + * + * @throws Horde_Kolab_Server_Exception If storing the value failed. + */ + public function update(array $changes) + { + $changes = parent::update($changes); + if (!empty($changes)) { + throw new Horde_Kolab_Server_Exception( + sprintf( + "The value for \"%s\" may not be modified!", + $this->_name + ) + ); + } + return $changes; + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Field.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Field.php new file mode 100644 index 000000000..22afb8ebf --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Field.php @@ -0,0 +1,151 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The base class representing Kolab object attributes. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +abstract class Horde_Kolab_Server_Object_Attribute_Value +extends Horde_Kolab_Server_Object_Attribute_Base +{ + + + /** + * Quote field separators within a LDAP value. + * + * @param string $string The string that should be quoted. + * + * @return string The quoted string. + */ + protected function quote($string) + { + return str_replace(array('\\', '$',), + array('\\5c', '\\24',), + $string); + } + + /** + * Unquote a LDAP value. + * + * @param string $string The string that should be unquoted. + * + * @return string The unquoted string. + */ + protected function unquote($string) + { + return str_replace(array('\\5c', '\\24',), + array('\\', '$',), + $string); + } + + + /** + * Get a derived attribute value by returning a given position in a + * delimited string. + * + * @param string $basekey Name of the attribute that holds the + * delimited string. + * @param string $field The position of the field to retrieve. + * @param string $separator The field separator. + * @param int $max_count The maximal number of fields. + * + * @return mixed The value of the attribute. + */ + protected function getField($basekey, $field = 0, $separator = '$', $max_count = null) + { + $base = $this->_get($basekey); + if (empty($base)) { + return; + } + if (!empty($max_count)) { + $fields = explode($separator, $base, $max_count); + } else { + $fields = explode($separator, $base); + } + return isset($fields[$field]) ? $this->unquote($fields[$field]) : null; + } + + + /** + * Set a collapsed attribute value. + * + * @param string $key The attribute to collapse into. + * @param array $attributes The attributes to collapse. + * @param array $info The information currently working on. + * @param string $separator Separate the fields using this character. + * @param boolean $unset Unset the base values. + * + * @return NULL. + */ + protected function setField($key, $attributes, &$info, $separator = '$', $unset = true) + { + /** + * Check how many empty entries we have at the end of the array. We + * may omit these together with their field separators. + */ + krsort($attributes); + $empty = true; + $end = count($attributes); + foreach ($attributes as $attribute) { + /** + * We do not expect the callee to always provide all attributes + * required for a collapsed attribute. So it is necessary to check + * for old values here. + */ + if (!isset($info[$attribute])) { + $old = $this->get($attribute); + if (!empty($old)) { + $info[$attribute] = $old; + } + } + if ($empty && empty($info[$attribute])) { + $end--; + } else { + $empty = false; + } + } + if ($empty) { + return; + } + ksort($attributes); + $unset = $attributes; + $result = ''; + for ($i = 0; $i < $end; $i++) { + $akey = array_shift($attributes); + $value = $info[$akey]; + if (is_array($value)) { + $value = $value[0]; + } + $result .= $this->quote($value); + if ($i != ($end - 1)) { + $result .= $separator; + } + } + if ($unset === true) { + foreach ($unset as $attribute) { + unset($info[$attribute]); + } + } + $info[$key] = $result; + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Guid.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Guid.php new file mode 100644 index 000000000..8db4feee4 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Guid.php @@ -0,0 +1,54 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The GUID attribute. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Guid +extends Horde_Kolab_Server_Object_Attribute_External +{ + /** + * Constructor + * + * @param Horde_Kolab_Server_Object $object The object this attribute + * belongs to. + * @param Horde_Kolab_Server_Composite $composite The link to the server. + */ + public function __construct( + Horde_Kolab_Server_Object $object, + Horde_Kolab_Server_Composite $composite + ) { + parent::__construct($object, $composite, 'Guid'); + } + + /** + * Return the value of this attribute. + * + * @return array The value(s) of this attribute. + */ + public function value() + { + return $this->_object->getGuid(); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Id.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Id.php new file mode 100644 index 000000000..48d0aab0b --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Id.php @@ -0,0 +1,56 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The id part of the GUID of this object. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Id +extends Horde_Kolab_Server_Object_Attribute_External +{ + /** + * Constructor + * + * @param Horde_Kolab_Server_Object $object The object this attribute + * belongs to. + * @param Horde_Kolab_Server_Composite $composite The link to the server. + */ + public function __construct( + Horde_Kolab_Server_Object $object, + Horde_Kolab_Server_Composite $composite + ) { + parent::__construct($object, $composite, 'Id'); + } + + /** + * Return the value of this attribute. + * + * @return array The value(s) of this attribute. + */ + public function value() + { + $guid = $this->_object->getGuid(); + $base = $this->_composite->server->getBaseUid(); + return substr($guid, 0, strlen($guid) - strlen($base) - 1); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Internal.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Internal.php new file mode 100644 index 000000000..cf352e345 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Internal.php @@ -0,0 +1,45 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The class represents internal-only object attributes. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Internal +extends Horde_Kolab_Server_Object_Attribute_Value +{ + /** + * Return the value of this attribute. + * + * @return array The value(s) of this attribute. + */ + public function value() + { + throw new Horde_Kolab_Server_Exception( + sprintf( + "Attribute \"%s\" is not visible!", + $this->_name + ) + ); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Locked.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Locked.php new file mode 100644 index 000000000..a3eee68de --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Locked.php @@ -0,0 +1,58 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * A decorator to represent a Kolab object attribute that can only be written on + * object creation and is immutable afterwards. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Locked +extends Horde_Kolab_Server_Object_Attribute_Decorator +{ + /** + * Return the new internal state for this attribute. + * + * @param array $changes The object data that should be updated. + * + * @return array The resulting internal state. + * + * @throws Horde_Kolab_Server_Exception If storing the value failed. + */ + public function update(array $changes) + { + if ($this->_attribute->isEmpty($changes)) { + return array(); + } + $changes = $this->_attribute->update($changes); + if (!empty($changes) && $this->getObject()->exists()) { + throw new Horde_Kolab_Server_Exception( + sprintf( + "The value for \"%s\" may not be modified on an existing object!", + $this->_attribute->getExternalName() + ) + ); + } + return $changes; + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Modifytimestamp.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Modifytimestamp.php new file mode 100644 index 000000000..1b47f0b3c --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Modifytimestamp.php @@ -0,0 +1,47 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The "modifyTimestamp" attribute. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Modifytimestamp +extends Horde_Kolab_Server_Object_Attribute_External +{ + /** The attribute name */ + const NAME = 'modifyTimestamp'; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Object $object The object this attribute + * belongs to. + * @param Horde_Kolab_Server_Composite $composite The link to the server. + */ + public function __construct( + Horde_Kolab_Server_Object $object, + Horde_Kolab_Server_Composite $composite + ) { + parent::__construct($object, $composite, self::NAME); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Modifytimestampdate.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Modifytimestampdate.php new file mode 100644 index 000000000..8402edd7b --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Modifytimestampdate.php @@ -0,0 +1,40 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The "modifyTimestamp" attribute converted to Horde_Date. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Modifytimestampdate +extends Horde_Kolab_Server_Object_Attribute_Modifytimestamp +{ + /** + * Return the value of this attribute. + * + * @return mixed The value of this attribute. + */ + public function value() + { + return new Horde_Date(parent::value()); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Objectclass.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Objectclass.php new file mode 100644 index 000000000..effb2d1d1 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Objectclass.php @@ -0,0 +1,53 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The "objectClass" attribute. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Objectclass +extends Horde_Kolab_Server_Object_Attribute_Decorator +{ + /** The internal attribute name */ + const INTERNAL = 'objectClass'; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Object $object The object this attribute + * belongs to. + * @param Horde_Kolab_Server_Composite $composite The link to the server. + */ + public function __construct( + Horde_Kolab_Server_Object $object, + Horde_Kolab_Server_Composite $composite + ) { + $this->_attribute = new Horde_Kolab_Server_Object_Attribute_Required( + new Horde_Kolab_Server_Object_Attribute_Locked( + new Horde_Kolab_Server_Object_Attribute_Value( + $object, $composite, self::INTERNAL, 'Objectclass' + ) + ) + ); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Openldapaci.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Openldapaci.php new file mode 100644 index 000000000..309447796 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Openldapaci.php @@ -0,0 +1,47 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The "OpenLDAPaci" attribute. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Openldapaci +extends Horde_Kolab_Server_Object_Attribute_Value +{ + /** The attribute name */ + const NAME = 'OpenLDAPaci'; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Object $object The object this attribute + * belongs to. + * @param Horde_Kolab_Server_Composite $composite The link to the server. + */ + public function __construct( + Horde_Kolab_Server_Object $object, + Horde_Kolab_Server_Composite $composite + ) { + parent::__construct($object, $composite, self::NAME); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Required.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Required.php new file mode 100644 index 000000000..c3cc302e7 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Required.php @@ -0,0 +1,53 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * A decorator to represent required Kolab object attributes. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Required +extends Horde_Kolab_Server_Object_Attribute_Decorator +{ + /** + * Return the new internal state for this attribute. + * + * @param array $changes The object data that should be updated. + * + * @return array The resulting internal state. + * + * @throws Horde_Kolab_Server_Exception If storing the value failed. + */ + public function update(array $changes) + { + $changes = $this->_attribute->update($changes); + if (empty($changes) && !$this->_attribute->getObject()->exists()) { + throw new Horde_Kolab_Server_Exception( + sprintf( + "The value for \"%s\" is empty but required!", + $this->_attribute->getExternalName() + ) + ); + } + return $changes; + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Single.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Single.php new file mode 100644 index 000000000..f26a3d08a --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Single.php @@ -0,0 +1,47 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * A decorator to represent a Kolab object attribute that can only be written on + * object creation and is immutable afterwards. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Single +extends Horde_Kolab_Server_Object_Attribute_Decorator +{ + /** + * Return the value of this attribute. + * + * @return array The value(s) of this attribute. + */ + public function value() + { + $value = $this->_attribute->value(); + if (is_array($value)) { + return array_pop($value); + } else { + return $value; + } + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Value.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Value.php new file mode 100644 index 000000000..ca478865f --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Value.php @@ -0,0 +1,84 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * The base class representing Kolab object attributes. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Value +extends Horde_Kolab_Server_Object_Attribute_Base +{ + /** + * Return the value of this attribute. + * + * @return array The value(s) of this attribute. + * + * @throws Horde_Kolab_Server_Exception If retrieval of the value failed. + */ + public function value() + { + return $this->_object->getInternal($this->getInternalName()); + } + + /** + * Indicate that a value will be saved by deleting it from the original data + * array. + * + * @param array &$changes The object data that should be changed. + * + * @return NULL + */ + public function consume(array &$changes) + { + if (isset($changes[$this->getExternalName()])) { + unset($changes[$this->getExternalName()]); + } + } + + /** + * Return the new internal state for this attribute. + * + * @param array $changes The object data that should be updated. + * + * @return array The resulting internal state. + * + * @throws Horde_Kolab_Server_Exception If storing the value failed. + */ + public function update(array $changes) + { + if (!$this->isEmpty($changes)) { + $value = $changes[$this->getExternalName()]; + if (!is_array($value)) { + $value = array($value); + } + return array($this->getInternalName() => $value); + } + try { + $old = $this->_object->getInternal($this->getInternalName()); + return array($this->getInternalName() => array()); + } catch (Horde_Kolab_Server_Exception_Novalue $e) { + return array(); + } + } + +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Writelock.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Writelock.php new file mode 100644 index 000000000..2b4c1a80d --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Attribute/Writelock.php @@ -0,0 +1,53 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * A decorator to represent a Kolab object attribute that can never be written. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Attribute_Writelock +extends Horde_Kolab_Server_Object_Attribute_Decorator +{ + /** + * Return the new internal state for this attribute. + * + * @param array $changes The object data that should be updated. + * + * @return array The resulting internal state. + * + * @throws Horde_Kolab_Server_Exception If storing the value failed. + */ + public function update(array $changes) + { + $changes = $this->_attribute->update($changes); + if (!empty($changes)) { + throw new Horde_Kolab_Server_Exception( + sprintf( + "The value for \"%s\" may not be modified!", + $this->_attribute->getExternalName() + ) + ); + } + return $changes; + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Base.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Base.php new file mode 100644 index 000000000..e56315e52 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Base.php @@ -0,0 +1,251 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * This class provides methods to deal with Kolab objects stored in + * the Kolab db. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +abstract class Horde_Kolab_Server_Object_Base +implements Horde_Kolab_Server_Object +{ + /** + * Link to the Kolab server. + * + * @var Horde_Kolab_Server_Composite + */ + private $_composite; + + /** + * GUID of this object on the Kolab server. + * + * @var string + */ + protected $guid; + + /** + * Initialize the Kolab Object. Provide either the GUID + * + * @param Horde_Kolab_Server_Composite $composite The link to the Kolab server. + * @param string $guid GUID of the object. + */ + public function __construct( + Horde_Kolab_Server_Composite $composite, + $guid = null + ) { + $this->_composite = $composite; + $this->guid = $guid; + } + + /** + * Get the GUID of this object + * + * @return string the GUID of this object + */ + public function getGuid() + { + if (empty($this->guid)) { + throw new Horde_Kolab_Server_Exception( + 'Uninitialized object is missing GUID!' + ); + } + return $this->guid; + } + + /** + * Get the external attributes supported by this object. + * + * @return array The external attributes supported by this object. This is a + * list of abbreviated attribute class names. + */ + public function getExternalAttributes() + { + return $this->_composite->schema->getExternalAttributes($this); + } + + /** + * Get the internal attributes supported by this object. + * + * @return array The internal attributes supported by this object. This is + * an association of internal attribute names an the correspodning attribute + * class names. + */ + public function getInternalAttributes() + { + return $this->_composite->schema->getInternalAttributes($this); + } + + /** + * Does the object exist? + * + * @return boolean True if the object exists, false otherwise. + */ + public function exists() + { + try { + $this->readInternal(); + return true; + } catch (Horde_Kolab_Server_Exception $e) { + return false; + } + } + + /** + * Read the object data. + * + * @return array The read data. + */ + public function readInternal() + { + return $this->_composite->server->readAttributes( + $this->getGuid(), array_keys($this->getInternalAttributes()) + ); + } + + /** + * Get the specified attribute of this object + * + * @param string $attr The attribute to read + * + * @return array The value(s) of this attribute + */ + public function getInternal($attr) + { + if (!in_array($attr, array_keys($this->getInternalAttributes()))) { + throw new Horde_Kolab_Server_Exception( + sprintf("Attribute \"%s\" not supported!", $attr) + ); + } + $result = $this->readInternal(); + if (!isset($result[$attr])) { + throw new Horde_Kolab_Server_Exception_Novalue( + sprintf("No value for attribute \"%s\"!", $attr) + ); + } + return $result[$attr]; + } + + /** + * Get the specified attribute of this object. + * + * @param string $attr The attribute to read. + * + * @return mixed The value of this attribute. + */ + public function getExternal($attr) + { + $attr = ucfirst($attr); + $class = 'Horde_Kolab_Server_Object_Attribute_' . $attr; + if (!in_array($attr, $this->getExternalAttributes()) + || !class_exists($class)) { + throw new Horde_Kolab_Server_Exception( + sprintf("Attribute \"%s\" not supported!", $attr) + ); + } + $attribute = new $class($this, $this->_composite); + return $attribute->value(); + } + + /** + * Saves object information. This may either create a new entry or modify an + * existing entry. + * + * Please note that fields with multiple allowed values require the callee + * to provide the full set of values for the field. Any old values that are + * not resubmitted will be considered to be deleted. + * + * @param array $info The information about the object. + * + * @return NULL + * + * @throws Horde_Kolab_Server_Exception If saving the data failed. + */ + public function save(array $info) + { + /** Handle all class specific transformations of the provided data */ + $this->prepareObjectInformation($info); + + $internal = $this->getNewInternal($info); + + $guid = $this->_composite->structure->generateServerGuid( + get_class($this), $this->generateId($internal), $internal + ); + + if ($this->exists()) { + if ($guid != $this->guid) { + $this->_composite->server->rename($this->guid, $guid); + $this->guid = $guid; + } + $result = $this->_composite->server->save($this, $internal); + } else { + $this->guid = $guid; + $this->_composite->server->add($this, $internal); + } + } + + /** + * Transform the given data array into the new internal dataset. + * + * @param array $info The information about the object. + * + * @return NULL + * + * @throws Horde_Kolab_Server_Exception If transforming the data failed. + */ + protected function getNewInternal($info) + { + $internal = array(); + $consumed = $info; + $attributes = $this->getInternalAttributes(); + foreach (array_values($attributes) as $class) { + $attribute = new $class($this, $this->_composite); + $internal = array_merge($internal, $attribute->update($info)); + $attribute->consume($consumed); + } + + /** Check if all given data would be used for saving */ + if (!empty($consumed)) { + throw new Horde_Kolab_Server_Exception( + sprintf( + "Not all data would be saved. Leftover keys: %s.", + join(',', array_keys($consumed)) + ) + ); + } + + return $internal; + } + + /** + * Delete this object. + * + * @return NULL + * + * @throws Horde_Kolab_Server_Exception If deleting the object failed. + */ + public function delete() + { + $this->_composite->server->delete($this->getGuid()); + } +} diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Factory.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Factory.php new file mode 100644 index 000000000..01150765e --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Factory.php @@ -0,0 +1,73 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Factory methods for Horde_Kolab_Server_Object instances. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Factory +{ + /** + * Attempts to return a concrete Horde_Kolab_Server_Object instance based on + * $type. + * + * @param mixed $type The type of the Horde_Kolab_Server_Object subclass + * to return. + * @param string $uid UID of the object + * @param array &$storage A link to the Kolab_Server class handling read/write. + * @param array $data A possible array of data for the object + * + * @return Horde_Kolab_Server_Object|PEAR_Error The newly created concrete + * Horde_Kolab_Server_Object instance. + */ + static public function &factory($type, $uid, &$storage, $data = null) + { + $result = Horde_Kolab_Server_Object::loadClass($type); + + if (class_exists($type)) { + $object = new $type($storage, $uid, $data); + } else { + throw new Horde_Kolab_Server_Exception('Class definition of ' . $type . ' not found.'); + } + + return $object; + } + + /** + * Attempts to load the concrete Horde_Kolab_Server_Object class based on + * $type. + * + * @param mixed $type The type of the Horde_Kolab_Server_Object subclass. + * + * @static + * + * @return true|PEAR_Error True if successfull. + */ + static public function loadClass($type) + { + if (!class_exists($type)) { + throw new Horde_Kolab_Server_Exception('Class definition of ' . $type . ' not found.'); + } + } + +} diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Groupofnames.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Groupofnames.php index 908c3f6f5..588478a22 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Groupofnames.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Groupofnames.php @@ -25,7 +25,7 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Object_Groupofnames extends Horde_Kolab_Server_Object +class Horde_Kolab_Server_Object_Groupofnames extends Horde_Kolab_Server_Object_Top { /** Define attributes specific to this object type */ @@ -79,7 +79,7 @@ class Horde_Kolab_Server_Object_Groupofnames extends Horde_Kolab_Server_Object * * @return string|PEAR_Error The ID. */ - public function generateId(&$info) + public function generateId(array &$info) { $id = $info[self::ATTRIBUTE_CN]; if (is_array($id)) { @@ -110,7 +110,7 @@ class Horde_Kolab_Server_Object_Groupofnames extends Horde_Kolab_Server_Object if (!in_array($member, $this->getMembers())) { $this->_cache[self::ATTRIBUTE_MEMBER][] = $member; } else { - throw new Horde_Kolab_Server_Exception(_("The UID %s is already a member of the group %s!"), + throw new Horde_Kolab_Server_Exception("The UID %s is already a member of the group %s!", $member, $this->_uid); } return $this->save($this->_cache); @@ -132,7 +132,7 @@ class Horde_Kolab_Server_Object_Groupofnames extends Horde_Kolab_Server_Object array_diff($this->_cache[self::ATTRIBUTE_MEMBER], array($member)); } else { - throw new Horde_Kolab_Server_Exception(_("The UID %s is no member of the group %s!"), + throw new Horde_Kolab_Server_Exception("The UID %s is no member of the group %s!", $member, $this->_uid); } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Hash.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Hash.php new file mode 100644 index 000000000..ca38459a8 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Hash.php @@ -0,0 +1,203 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Provides array access to Kolab objects. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Hash +implements Horde_Kolab_Server_Object, ArrayAccess +{ + /** + * Link to the decorated object. + * + * @var Horde_Kolab_Server_Object + */ + private $_object; + + /** + * Initialize the Kolab Object. Provide either the GUID + * + * @param Horde_Kolab_Server_Object $object The represented object. + */ + public function __construct( + Horde_Kolab_Server_Object $object + ) { + $this->_object = $object; + } + + /** + * Get the GUID of this object + * + * @return string the GUID of this object + */ + public function getGuid() + { + return $this->_object->getGuid(); + } + + /** + * Get the external attributes supported by this object. + * + * @return array The external attributes supported by this object. This is + * an association of attribute names and attribute handler class names. + */ + public function getExternalAttributes() + { + return $this->_object->getExternalAttributes(); + } + + /** + * Get the internal attributes supported by this object. + * + * @return array The internal attributes supported by this object. This is + * an association of attribute names and attribute handler class names. + */ + public function getInternalAttributes() + { + return $this->_object->getInternalAttributes(); + } + + /** + * Does the object exist? + * + * @return NULL + */ + public function exists() + { + return $this->_object->exists(); + } + + /** + * Read the object into the cache + * + * @return array The read data. + */ + public function readInternal() + { + return $this->_object->readInternal(); + } + + /** + * Get the specified attribute of this object + * + * @param string $attr The attribute to read + * + * @return array The value(s) of this attribute + */ + public function getInternal($attr) + { + return $this->_object->getInternal($attr); + } + + /** + * Get the specified attribute of this object. + * + * @param string $attr The attribute to read. + * + * @return mixed The value of this attribute. + */ + public function getExternal($attr) + { + return $this->_object->getExternal($attr); + } + + /** + * Get the specified attribute of this object and ensure that only a single + * value is being returned. + * + * @param string $attr The attribute to read. + * + * @return mixed The value of this attribute. + */ + public function getSingle($attr) + { + $value = $this->getExternal($attr); + if (is_array($value)) { + return array_pop($value); + } else { + return $value; + } + } + + /** + * Convert the object attributes to a hash. + * + * @param array $attrs The attributes to return. + * @param boolean $single Should only a single attribute be returned? + * + * @return array|PEAR_Error The hash representing this object. + */ + public function toHash(array $attrs = array(), $single = true) + { + $result = array(); + + /** + * Return all supported attributes if no specific attributes were + * requested. + */ + if (empty($attrs)) { + $attrs = array_keys($this->attributes); + } + + foreach ($attrs as $key) { + if ($single) { + $result[$key] = $this->getSingle($key); + } else { + $result[$key] = $this->getExternal($key); + } + } + return $result; + } + + /** + * Saves object information. This may either create a new entry or modify an + * existing entry. + * + * Please note that fields with multiple allowed values require the callee + * to provide the full set of values for the field. Any old values that are + * not resubmitted will be considered to be deleted. + * + * @param array $info The information about the object. + * + * @return NULL + * + * @throws Horde_Kolab_Server_Exception If saving the data failed. + */ + public function save(array $info) + { + $this->_object->save($info); + } + + /** + * Delete this object. + * + * @return NULL + * + * @throws Horde_Kolab_Server_Exception If deleting the object failed. + */ + public function delete() + { + $this->_object->delete(); + } +} diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Inetorgperson.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Inetorgperson.php index 22357abb1..408f995b6 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Inetorgperson.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Inetorgperson.php @@ -299,7 +299,7 @@ class Horde_Kolab_Server_Object_Inetorgperson extends Horde_Kolab_Server_Object_ foreach ($addresses as $address) { list($name_segment, $street_segment, $postal_address, $postal_code, $city) = sscanf('%s$%s$%s$%s %s', $address); - if ($name_segment == _("Post office box")) { + if ($name_segment == "Post office box") { $result[] = array( self::ATTRIBUTE_POSTOFFICEBOX => $street_segment, self::ATTRIBUTE_POSTALADDRESS => $postal_address, @@ -374,7 +374,7 @@ class Horde_Kolab_Server_Object_Inetorgperson extends Horde_Kolab_Server_Object_ $postal_data['name_segment'] = $db_postal_data[self::ATTRIBUTE_GIVENNAME] . ' ' . $db_postal_data[self::ATTRIBUTE_SN]; } else { $postal_data['street_segment'] = $postal_data[self::ATTRIBUTE_POSTOFFICEBOX]; - $postal_data['name_segment'] = _("Post office box"); + $postal_data['name_segment'] = "Post office box"; } $result[] = sprintf('%s$%s$%s$%s %s', $postal_data['name_segment'], @@ -396,7 +396,7 @@ class Horde_Kolab_Server_Object_Inetorgperson extends Horde_Kolab_Server_Object_ * * @return string|PEAR_Error The ID. */ - public function generateId(&$info) + public function generateId(array &$info) { if ($this->exists()) { if (!isset($info[self::ATTRIBUTE_GIVENNAME]) diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabgermanbankarrangement.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabgermanbankarrangement.php index 65b27b894..036574f64 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabgermanbankarrangement.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabgermanbankarrangement.php @@ -26,7 +26,7 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Object_Kolabgermanbankarrangement extends Horde_Kolab_Server_Object +class Horde_Kolab_Server_Object_Kolabgermanbankarrangement extends Horde_Kolab_Server_Object_Top { /** Define attributes specific to this object type */ @@ -98,12 +98,12 @@ class Horde_Kolab_Server_Object_Kolabgermanbankarrangement extends Horde_Kolab_S * * @return string|PEAR_Error The ID. */ - public function generateId(&$info) + public function generateId(array &$info) { if (!isset($info[self::ATTRIBUTE_OWNERUID])) { $uid = $this->get(self::ATTRIBUTE_OWNERUID); if (empty($uid)) { - throw new Horde_Kolab_Server_Exception(_("No parent object provided!"), + throw new Horde_Kolab_Server_Exception("No parent object provided!", Horde_Kolab_Server_Exception::INVALID_INFORMATION); } } else { @@ -116,7 +116,7 @@ class Horde_Kolab_Server_Object_Kolabgermanbankarrangement extends Horde_Kolab_S $object = $this->server->fetch($uid); if (!$object->exists()) { - throw new Horde_Kolab_Server_Exception(sprintf(_("The parent object %s does not exist!"), + throw new Horde_Kolab_Server_Exception(sprintf("The parent object %s does not exist!", $uid), Horde_Kolab_Server_Exception::INVALID_INFORMATION); } @@ -124,7 +124,7 @@ class Horde_Kolab_Server_Object_Kolabgermanbankarrangement extends Horde_Kolab_S if (!isset($info[self::ATTRIBUTE_NUMBER])) { $number = $this->get(self::ATTRIBUTE_NUMBER); if (empty($number)) { - throw new Horde_Kolab_Server_Exception(_("No account number given!"), + throw new Horde_Kolab_Server_Exception("No account number given!", Horde_Kolab_Server_Exception::INVALID_INFORMATION); } } else { @@ -138,7 +138,7 @@ class Horde_Kolab_Server_Object_Kolabgermanbankarrangement extends Horde_Kolab_S if (!isset($info[self::ATTRIBUTE_BANKCODE])) { $bankcode = $this->get(self::ATTRIBUTE_BANKCODE); if (empty($bankcode)) { - throw new Horde_Kolab_Server_Exception(_("No bankcode given!"), + throw new Horde_Kolab_Server_Exception("No bankcode given!", Horde_Kolab_Server_Exception::INVALID_INFORMATION); } } else { diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabgroupofnames.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabgroupofnames.php index 8604e8922..bfc88bfc3 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabgroupofnames.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabgroupofnames.php @@ -106,7 +106,7 @@ class Horde_Kolab_Server_Object_Kolabgroupofnames extends Horde_Kolab_Server_Obj * * @return string|PEAR_Error The ID. */ - public function generateId(&$info) + public function generateId(array &$info) { if ($this->exists()) { if (!isset($info[self::ATTRIBUTE_MAIL]) @@ -141,7 +141,7 @@ class Horde_Kolab_Server_Object_Kolabgroupofnames extends Horde_Kolab_Server_Obj * * @throws Horde_Kolab_Server_Exception If the given information contains errors. */ - public function prepareObjectInformation(&$info) + public function prepareObjectInformation(array &$info) { if (!$this->exists()) { if (!isset($info[self::ATTRIBUTE_CN])) { diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabinetorgperson.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabinetorgperson.php index 9dee91bd9..9e891a9a6 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabinetorgperson.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabinetorgperson.php @@ -230,7 +230,7 @@ class Horde_Kolab_Server_Object_Kolabinetorgperson extends Horde_Kolab_Server_Ob * * @return string|PEAR_Error The ID. */ - public function generateId(&$info) + public function generateId(array &$info) { /** * Never rename the object, even if the components of the CN attribute @@ -292,12 +292,12 @@ class Horde_Kolab_Server_Object_Kolabinetorgperson extends Horde_Kolab_Server_Ob * * @throws Horde_Kolab_Server_Exception If the given information contains errors. */ - public function prepareObjectInformation(&$info) + public function prepareObjectInformation(array &$info) { if (!$this->exists()) { if (!isset($info[self::ATTRIBUTE_CN])) { if (!isset($info[self::ATTRIBUTE_SN]) || !isset($info[self::ATTRIBUTE_GIVENNAME])) { - throw new Horde_Kolab_Server_Exception(_("Either the last name or the given name is missing!")); + throw new Horde_Kolab_Server_Exception("Either the last name or the given name is missing!"); } else { $info[self::ATTRIBUTE_CN] = $this->generateCn($info); } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabpop3account.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabpop3account.php index aef56f1a7..00c615e9e 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabpop3account.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Kolabpop3account.php @@ -25,7 +25,7 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Object_Kolabpop3account extends Horde_Kolab_Server_Object +class Horde_Kolab_Server_Object_Kolabpop3account extends Horde_Kolab_Server_Object_Top { /** Define attributes specific to this object type */ @@ -118,12 +118,12 @@ class Horde_Kolab_Server_Object_Kolabpop3account extends Horde_Kolab_Server_Obje * * @return string|PEAR_Error The ID. */ - public function generateId(&$info) + public function generateId(array &$info) { if (!isset($info[self::ATTRIBUTE_OWNERUID])) { $uid = $this->get(self::ATTRIBUTE_OWNERUID); if (empty($uid)) { - throw new Horde_Kolab_Server_Exception(_("No parent object provided!"), + throw new Horde_Kolab_Server_Exception("No parent object provided!", Horde_Kolab_Server_Exception::INVALID_INFORMATION); } } else { @@ -136,7 +136,7 @@ class Horde_Kolab_Server_Object_Kolabpop3account extends Horde_Kolab_Server_Obje $object = $this->server->fetch($uid); if (!$object->exists()) { - throw new Horde_Kolab_Server_Exception(sprintf(_("The parent object %s does not exist!"), + throw new Horde_Kolab_Server_Exception(sprintf("The parent object %s does not exist!", $uid), Horde_Kolab_Server_Exception::INVALID_INFORMATION); } @@ -144,7 +144,7 @@ class Horde_Kolab_Server_Object_Kolabpop3account extends Horde_Kolab_Server_Obje if (!isset($info[self::ATTRIBUTE_MAIL])) { $mail = $this->get(self::ATTRIBUTE_MAIL); if (empty($mail)) { - throw new Horde_Kolab_Server_Exception(_("No mail given!"), + throw new Horde_Kolab_Server_Exception("No mail given!", Horde_Kolab_Server_Exception::INVALID_INFORMATION); } } else { diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Mcached.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Mcached.php new file mode 100644 index 000000000..b798a1b7a --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Mcached.php @@ -0,0 +1,288 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Low level caching for the Kolab object. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Mcached +implements Horde_Kolab_Server_Object +{ + /** + * Link to the decorated object. + * + * @var Horde_Kolab_Server_Object + */ + private $_object; + + /** + * The external attributes supported by this class. + * + * @var array + */ + protected $_attributes_ext; + + /** + * The internal attributes required for this class. + * + * @var array + */ + protected $_attributes_int; + + /** + * Does the object exist? + * + * @return boolean True if the object exists, false otherwise. + */ + private $_exists; + + /** + * The cached internal result + * + * @var array + */ + private $_cache_int = array(); + + /** + * The cached external attribute values + * + * @var array + */ + private $_cache_ext = array(); + + /** + * A cache for the list of actions this object supports. + * + * @var array + */ + protected $_actions; + + /** + * Initialize the Kolab Object. Provide either the GUID + * + * @param Horde_Kolab_Server_Composite $composite The link to the Kolab server. + * @param string $guid GUID of the object. + */ + public function __construct( + Horde_Kolab_Server_Object $object + ) { + $this->_object = $object; + } + + /** + * Get the GUID of this object + * + * @return string the GUID of this object + */ + public function getGuid() + { + return $this->_object->getGuid(); + } + + /** + * Get the external attributes supported by this object. + * + * @return array The external attributes supported by this object. This is a + * list of abbreviated attribute class names. + */ + public function getExternalAttributes() + { + if (empty($this->_attributes_ext)) { + $this->_attributes_ext = $this->_object->getExternalAttributes(); + } + return $this->_attributes_ext; + } + + /** + * Get the internal attributes supported by this object. + * + * @return array The internal attributes supported by this object. This is + * an association of internal attribute names an the correspodning attribute + * class names. + */ + public function getInternalAttributes() + { + if (empty($this->_attributes_int)) { + $this->_attributes_int = $this->_object->getInternalAttributes(); + } + return $this->_attributes_int; + } + + /** + * Set the internal data of this object. + * + * @param array $data A data array for the object. + * + * @return NULL + */ + public function setInternalData(array $data) + { + $this->_cache_int = $data; + } + + /** + * Does the object exist? + * + * @return NULL + */ + public function exists() + { + if ($this->_exists === null) { + $this->_exists = $this->_object->exists(); + } + return $this->_exists; + } + + /** + * Get the specified attribute of this object + * + * @param string $attr The attribute to read + * @param boolean $single Should a single value be returned + * or are multiple values allowed? + * + * @return string the value of this attribute + */ + public function getInternal($attr) + { + if (!isset($this->_cache_int[$attr])) { + if (!in_array($attr, array_keys($this->getInternalAttributes()))) { + throw new Horde_Kolab_Server_Exception(sprintf("Attribute \"%s\" not supported!", + $attr)); + } + $this->_cache_int = array_merge( + $this->_cache_int, + $this->_object->readInternal() + ); + if (!isset($this->_cache_int[$attr])) { + throw new Horde_Kolab_Server_Exception(sprintf("Failed to read attribute \"%s\"!", + $attr)); + } + } + return $this->_cache_int[$attr]; + } + + /** + * Get the specified attribute of this object. + * + * @param string $attr The attribute to read. + * + * @return mixed The value of this attribute. + */ + public function getExternal($attr) + { + if (!isset($this->_cache_ext[$attr])) { + $this->_cache_ext[$attr] = $this->_object->getExternal($attr); + } + return $this->_cache_ext[$attr]; + } + + /** + * Get the specified attribute of this object and ensure that only a single + * value is being returned. + * + * @param string $attr The attribute to read. + * + * @return mixed The value of this attribute. + */ + public function getSingle($attr) + { + return $this->_object->getSingle($attr); + } + + /** + * Convert the object attributes to a hash. + * + * @param array $attrs The attributes to return. + * @param boolean $single Should only a single attribute be returned? + * + * @return array|PEAR_Error The hash representing this object. + */ + public function toHash(array $attrs = array(), $single = true) + { + return $this->_object->toHash($attrs, $single); + } + + /** + * Saves object information. This may either create a new entry or modify an + * existing entry. + * + * Please note that fields with multiple allowed values require the callee + * to provide the full set of values for the field. Any old values that are + * not resubmitted will be considered to be deleted. + * + * @param array $info The information about the object. + * + * @return NULL + * + * @throws Horde_Kolab_Server_Exception If saving the data failed. + */ + public function save(array $info) + { + $this->_object->save($info); + + /** Mark the object as existing */ + $this->_exists = true; + + /** + * Throw away the cache data to ensure it gets refetched in case we need + * to access it again + */ + $this->_cache_ext = array(); + $this->_cache_int = array(); + } + + /** + * Delete this object. + * + * @return NULL + * + * @throws Horde_Kolab_Server_Exception If deleting the object failed. + */ + public function delete() + { + $this->_object->delete(); + + /** Mark the object as missing */ + $this->_exists = false; + + /** + * Throw away the cache data to ensure it gets refetched in case we need + * to access it again + */ + $this->_cache_ext = array(); + $this->_cache_int = array(); + } + + /** + * Returns the set of actions supported by this object type. + * + * @return array An array of supported actions. + */ + public function getActions() + { + if (!isset($this->_actions)) { + $this->_actions = $this->_object->getActions(); + } + return $this->_actions; + } +} diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Person.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Person.php index 2c1c4ba18..0344eb539 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Person.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Person.php @@ -25,7 +25,7 @@ * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Object_Person extends Horde_Kolab_Server_Object +class Horde_Kolab_Server_Object_Person extends Horde_Kolab_Server_Object_Top { /** Define attributes specific to this object type */ @@ -182,7 +182,7 @@ class Horde_Kolab_Server_Object_Person extends Horde_Kolab_Server_Object * * @return string The ID. */ - public function generateId(&$info) + public function generateId(array &$info) { if ($this->exists()) { if (!isset($info[self::ATTRIBUTE_CN]) @@ -217,7 +217,7 @@ class Horde_Kolab_Server_Object_Person extends Horde_Kolab_Server_Object * * @throws Horde_Kolab_Server_Exception If the given information contains errors. */ - public function prepareObjectInformation(&$info) + public function prepareObjectInformation(array &$info) { if (!$this->exists() && empty($info[self::ATTRIBUTE_CN]) diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/InterfaceTest.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search.php similarity index 70% rename from framework/Kolab_Server/test/Horde/Kolab/Server/Server/InterfaceTest.php rename to framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search.php index c8fe1649a..4c612b4b9 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/InterfaceTest.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search.php @@ -1,6 +1,6 @@ + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Basic attributes search. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Search_Guid +extends Horde_Kolab_Server_Object_Search_Base +{ + /** + * Perform the search. + * + * @param Horde_Kolab_Server_Query_Element $criteria The search criteria. + * @param array $attributes The attributes to + * retrieve. + * + * @return mixed The search result. + */ + public function search() + { + $criteria = func_get_arg(0); + $attributes = func_get_arg(1); + + $params = array('attributes' => $attributes); + return $this->_composite->server->find($criteria, $params); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Base.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Base.php new file mode 100644 index 000000000..fd970c5b4 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Base.php @@ -0,0 +1,62 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * An interface marking object class search operations. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +abstract class Horde_Kolab_Server_Object_Search_Base implements Horde_Kolab_Server_Object_Search +{ + /** + * A link to the composite server handler. + * + * @var Horde_Kolab_Server_Composite + */ + private $_composite; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Composite $composite A link to the composite + * server handler. + */ + public function __construct(Horde_Kolab_Server_Composite $composite) + { + $this->_composite = $composite; + } + + /** + * Identify the GUID(s) of the result entry(s). + * + * @param array $result The LDAP search result. + * + * @return boolean|array The GUID(s) or false if there was no result. + */ + protected function guidFromResult($result) + { + if (empty($result)) { + return false; + } + return array_keys($result); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Children.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Children.php new file mode 100644 index 000000000..3deb3b8bd --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Children.php @@ -0,0 +1,56 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Basic GUID search. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Search_Children +extends Horde_Kolab_Server_Object_Search_Guid +{ + /** + * Perform the search. + * + * @param Horde_Kolab_Server_Query_Element $criteria The search criteria. + * @param string $objectclass The type of children + * to return. + * + * @return mixed The search result. + */ + public function search() + { + $criteria = func_get_arg(0); + $objectclass = func_get_arg(1); + + $criteria = new Horde_Kolab_Server_Query_Element_And( + array( + new Horde_Kolab_Server_Query_Element_Equals( + Horde_Kolab_Server_Object_Top::ATTRIBUTE_OC, + $objectclass + ), + $criteria + ) + ); + return parent::search($criteria); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Constraint/Single.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Constraint/Single.php new file mode 100644 index 000000000..82e2ed37c --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Constraint/Single.php @@ -0,0 +1,59 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Return only a single search result. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Search_Constraint_Single +implements Horde_Kolab_Server_Object_Search +{ + /** + * A link to the search. + * + * @var Horde_Kolab_Server_Search + */ + private $_search; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Search $search The search being restricted. + */ + public function __construct(Horde_Kolab_Server_Search $search) + { + $this->_search = $search; + } + + /** + * Perform the search. + * + * @return mixed The search result. + */ + public function search() + { + $args = func_get_args(); + $result = call_user_func_array(array($this->_search, 'search'), $args); + return array_pop($result); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Constraint/Strict.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Constraint/Strict.php new file mode 100644 index 000000000..65f9e3c12 --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Constraint/Strict.php @@ -0,0 +1,68 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Ensures that a search yields only a single return value. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Search_Constraint_Strict +implements Horde_Kolab_Server_Object_Search +{ + /** + * A link to the search. + * + * @var Horde_Kolab_Server_Search + */ + private $_search; + + /** + * Constructor + * + * @param Horde_Kolab_Server_Search $search The search being restricted. + */ + public function __construct(Horde_Kolab_Server_Search $search) + { + $this->_search = $search; + } + + /** + * Perform the search. + * + * @return mixed The search result. + */ + public function search() + { + $args = func_get_args(); + $result = call_user_func_array(array($this->_search, 'search'), $args); + if (count($result) > 1) { + throw new Horde_Kolab_Server_Exception( + sprintf( + "Found %s results when expecting only one!", + count($result) + ), + Horde_Kolab_Server_Exception::SEARCH_CONSTRAINT_TOO_MANY + ); + } + return $result; + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Guid.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Guid.php new file mode 100644 index 000000000..0a105495f --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Search/Guid.php @@ -0,0 +1,48 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Basic GUID search. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Search_Guid +extends Horde_Kolab_Server_Object_Search_Base +{ + /** + * Perform the search. + * + * @param Horde_Kolab_Server_Query_Element $criteria The search criteria. + * + * @return mixed The search result. + */ + public function search() + { + $criteria = func_get_arg(0); + + $params = array( + 'attributes' => Horde_Kolab_Server_Object_Top::ATTRIBUTE_GUID + ); + $data = $this->_composite->server->find($criteria, $params); + return self::guidFromResult($data); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Searches.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Searches.php new file mode 100644 index 000000000..bb60d7d5b --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Searches.php @@ -0,0 +1,46 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * An interface indicating that an object class provides additional search + * operations. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +interface Horde_Kolab_Server_Object_Searches +{ + /** + * Return the filter string to retrieve this object type. + * + * @return string The filter to retrieve this object type from the server + * database. + */ + public static function getFilter(); + + /** + * Returns the set of search operations supported by this object type. + * + * @return array An array of supported search operations. + */ + public static function getSearchOperations(); +} \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Top.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Top.php new file mode 100644 index 000000000..bac365bad --- /dev/null +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object/Top.php @@ -0,0 +1,136 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * This class provides methods to deal with Kolab objects stored in + * the Kolab db. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_Top +extends Horde_Kolab_Server_Object_Base +implements Horde_Kolab_Server_Object_Searches +{ + /** Define the possible Kolab object classes */ + const OBJECTCLASS_TOP = 'top'; + + /** + * The attributes defined for this class. + * + * @var array + */ + static public $attributes = array( + 'Objectclass', 'Openldapaci', 'Guid', 'Id', + 'Createtimestamp', 'Modifyimestamp', + 'Createtimestampdate', 'Modifyimestampdate', + ); + + static public $object_classes = array( + self::OBJECTCLASS_TOP, + ); + + /** + * Sort by this attributes. + * + * @var string + */ + public $sort_by = 'Guid'; + + /** + * Return the filter string to retrieve this object type. + * + * @static + * + * @return string The filter to retrieve this object type from the server + * database. + */ + public static function getFilter() + { + return new Horde_Kolab_Server_Query_Element_Equals( + Horde_Kolab_Server_Object_Attribute_Objectclass::NAME, + self::OBJECTCLASS_TOP + ); + } + + /** + * Generates an ID for the given information. + * + * @param array &$info The data of the object. + * + * @return string The ID. + */ + public function generateId(array &$info) + { + if ($this->exists() && empty($info['Id'])) { + return false; + } + + if (!empty($info['Id'])) { + if (is_array($info['Id'])) { + $id = $info['Id'][0]; + } else { + $id = $info['Id']; + } + return $this->_composite->server->quoteForGuid($id); + } + return $this->composite->server->quoteForGuid(hash('sha256', uniqid(mt_rand(), true))); + } + + /** + * Distill the server side object information to save. + * + * @param array &$info The information about the object. + * + * @return NULL. + * + * @throws Horde_Kolab_Server_Exception If the given information contains errors. + */ + public function prepareObjectInformation(array &$info) + { + } + + /** + * Returns the set of search operations supported by this object type. + * + * @return array An array of supported search operations. + */ + static public function getSearchOperations() + { + $searches = array( + 'Guid', + 'Attributes', + 'Children', + ); + return $searches; + } + + /** + * Returns the set of actions supported by this object type. + * + * @return array An array of supported actions. + */ + public function getActions() + { + return array(); + } +} diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Objects.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Objects.php index 92aa7ce66..5b941e5cd 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Objects.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Objects.php @@ -28,6 +28,14 @@ interface Horde_Kolab_Server_Objects { /** + * Set the composite server reference for this object. + * + * @param Horde_Kolab_Server_Composite $composite A link to the composite + * server handler. + */ + public function setComposite(Horde_Kolab_Server_Composite $composite); + + /** * Add a Kolab object. * * @param array $info The object to store. diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Objects/Base.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Objects/Base.php index 63636e547..d2edfca77 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Objects/Base.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Objects/Base.php @@ -109,7 +109,7 @@ class Horde_Kolab_Server_Objects_Base implements Horde_Kolab_Server_Objects $object = &Horde_Kolab_Server_Object::factory($type, null, $this, $info); if ($object->exists()) { throw new Horde_Kolab_Server_Exception( - sprintf(_("The object with the uid \"%s\" does already exist!"), + sprintf("The object with the uid \"%s\" does already exist!", $object->get(Horde_Kolab_Server_Object::ATTRIBUTE_UID))); } $object->save(); diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Query/Ldap.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Query/Ldap.php index e90f995ec..f6c6fb6ee 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Query/Ldap.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Query/Ldap.php @@ -260,7 +260,7 @@ class Horde_Kolab_Server_Query_Ldap implements Horde_Kolab_Server_Query $result, $code = Horde_Kolab_Server_Exception::INVALID_QUERY ) { - if (is_a($result, 'PEAR_Error')) { + if ($result instanceOf PEAR_Error) { throw new Horde_Kolab_Server_Exception($result, $code); } } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Schema.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Schema.php index 07792a217..0d2dda9d0 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Schema.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Schema.php @@ -28,6 +28,14 @@ interface Horde_Kolab_Server_Schema { /** + * Set the composite server reference for this object. + * + * @param Horde_Kolab_Server_Composite $composite A link to the composite + * server handler. + */ + public function setComposite(Horde_Kolab_Server_Composite $composite); + + /** * Return the schema for the given objectClass. * * @param string $objectclass Fetch the schema for this objectClass. @@ -50,13 +58,26 @@ interface Horde_Kolab_Server_Schema public function getAttributeSchema($attribute); /** - * Return the attributes supported by the given object class. + * Return the external attributes supported by the given object class. + * + * @param Horde_Kolab_Server_Object $object Determine the external + * attributes for this class. + * + * @return array The supported attributes. + * + * @throws Horde_Kolab_Server_Exception If the schema analysis fails. + */ + public function getExternalAttributes($object); + + /** + * Return the internal attributes supported by the given object class. * - * @param string $class Determine the attributes for this class. + * @param Horde_Kolab_Server_Object $object Determine the internal + * attributes for this class. * * @return array The supported attributes. * * @throws Horde_Kolab_Server_Exception If the schema analysis fails. */ - public function &getAttributes($class); + public function getInternalAttributes($object); } \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Search.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Search.php index 6f72f7bf0..51137f3d9 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Search.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Search.php @@ -28,6 +28,14 @@ interface Horde_Kolab_Server_Search { /** + * Set the composite server reference for this object. + * + * @param Horde_Kolab_Server_Composite $composite A link to the composite + * server handler. + */ + public function setComposite(Horde_Kolab_Server_Composite $composite); + + /** * Returns the set of search operations supported by this server type. * * @return array An array of supported search operations. diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Search/Base.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Search/Base.php index caf111f67..f49121f83 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Search/Base.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Search/Base.php @@ -29,32 +29,33 @@ class Horde_Kolab_Server_Search_Base implements Horde_Kolab_Server_Search { /** - * A link to the server handler. + * A link to the composite server handler. * - * @var Horde_Kolab_Server + * @var Horde_Kolab_Server_Composite */ - protected $server; + private $_composite; /** - * Set the server reference for this object. + * The search methods offered by the object defined for this server. * - * @param Horde_Kolab_Server &$server A link to the server handler. + * @var array */ - public function setServer($server) - { - $this->server = $server; - } + private $_searches; /** - * The search methods offered by the object defined for this server. + * Set the composite server reference for this object. * - * @var array + * @param Horde_Kolab_Server_Composite $composite A link to the composite + * server handler. */ - protected $searches; + public function setComposite(Horde_Kolab_Server_Composite $composite) + { + $this->_composite = $composite; + $this->_searches = $this->getSearchOperations(); + } /*__construct /** Initialize the search operations supported by this server. * - $this->searches = $this->getSearchOperations(); */ /** @@ -65,7 +66,7 @@ class Horde_Kolab_Server_Search_Base implements Horde_Kolab_Server_Search public function getSearchOperations() { $server_searches = array(); - foreach ($this->getSupportedObjects() as $sobj) { + foreach ($this->_composite->structure->getSupportedObjects() as $sobj) { if (in_array('getSearchOperations', get_class_methods($sobj))) { $searches = call_user_func(array($sobj, 'getSearchOperations')); foreach ($searches as $search) { @@ -96,8 +97,13 @@ class Horde_Kolab_Server_Search_Base implements Horde_Kolab_Server_Search } } throw new Horde_Kolab_Server_Exception( - sprintf("The server type \"%s\" does not support method \"%s\"!", - get_class($this), $method)); + sprintf( + "The server type \"%s\" with structure \"%s\" does not support method \"%s\"!", + get_class($this->_composite->server), + get_class($this->_composite->structure), + $method + ) + ); } } \ No newline at end of file diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure.php index 68f854046..17ccd6a51 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure.php @@ -29,6 +29,16 @@ interface Horde_Kolab_Server_Structure { /** + * Set the composite server reference for this object. + * + * @param Horde_Kolab_Server_Composite $composite A link to the composite + * server handler. + * + * @return NULL + */ + public function setComposite(Horde_Kolab_Server_Composite $composite); + + /** * Returns the set of objects supported by this structure. * * @return array An array of supported objects. @@ -39,13 +49,13 @@ interface Horde_Kolab_Server_Structure * Determine the type of an object by its tree position and other * parameters. * - * @param string $uid The UID of the object to examine. + * @param string $guid The GUID of the object to examine. * * @return string The class name of the corresponding object type. * * @throws Horde_Kolab_Server_Exception If the object type is unknown. */ - public function determineType($uid); + public function determineType($guid); /** * Generates a UID for the given information. @@ -54,9 +64,9 @@ interface Horde_Kolab_Server_Structure * @param string $id The id of the object. * @param array $info Any additional information about the object to create. * - * @return string The UID. + * @return string The GUID. * * @throws Horde_Kolab_Server_Exception If the given type is unknown. */ - public function generateServerUid($type, $id, $info); + public function generateServerGuid($type, $id, array $info); } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Base.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Base.php index bf58f7406..0c18a4ea6 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Base.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Base.php @@ -28,112 +28,22 @@ abstract class Horde_Kolab_Server_Structure_Base implements Horde_Kolab_Server_Structure { /** - * A link to the server handler. + * A link to the composite server handler. * - * @var Horde_Kolab_Server + * @var Horde_Kolab_Server_Composite */ - protected $server; + protected $composite; /** - * Set the server reference for this object. + * Set the composite server reference for this object. * - * @param Horde_Kolab_Server &$server A link to the server handler. - */ - public function setServer($server) - { - $this->server = $server; - } - - /** - * Returns the set of objects supported by this structure. - * - * @return array An array of supported objects. - */ - public function getSupportedObjects() - { - } - - /** - * Determine the type of an object by its tree position and other - * parameters. - * - * @param string $uid The UID of the object to examine. - * - * @return string The class name of the corresponding object type. - * - * @throws Horde_Kolab_Server_Exception If the object type is unknown. - */ - public function determineType($uid) - { - } - - /** - * Generates a UID for the given information. - * - * @param string $type The class name of the object to create. - * @param string $id The id of the object. - * @param array $info Any additional information about the object to create. + * @param Horde_Kolab_Server_Composite $composite A link to the composite + * server handler. * - * @return string The UID. - * - * @throws Horde_Kolab_Server_Exception If the given type is unknown. - */ - public function generateServerUid($type, $id, $info) - { - } - - /** - * Get the LDAP object classes for the given DN. - * - * This is meant to be a shortcut for the structure handler. It should be - * used when determining the object type. - * - * @param string $uid DN of the object. - * - * @return array An array of object classes. - * - * @throws Horde_Kolab_Server_Exception If the object has no - * object classes. + * @return NULL */ - public function getObjectClasses($uid) + public function setComposite(Horde_Kolab_Server_Composite $composite) { - $object = $this->read($uid, array(Horde_Kolab_Server_Object::ATTRIBUTE_OC)); - if (!isset($object[Horde_Kolab_Server_Object::ATTRIBUTE_OC])) { - throw new Horde_Kolab_Server_Exception( - sprintf( - "The object %s has no %s attribute!", - $uid, Horde_Kolab_Server_Object::ATTRIBUTE_OC - ), - Horde_Kolab_Server_Exception::SYSTEM - ); - } - $result = array_map( - 'strtolower', - $object[Horde_Kolab_Server_Object::ATTRIBUTE_OC] - ); - return $result; + $this->composite = $composite; } - - /** - * Connect to the server. Use this method if the user name you can provide - * does not match a DN. In this case it will be required to map this user - * name first. - * - * @param string $user The user name. - * @param string $pass The password. - * - * @return NULL. - * - * @throws Horde_Kolab_Server_Exception If the connection failed. - */ - protected function _connect($user = null, $pass = null) - { - /** Bind anonymously first. */ - $this->connectUid(); - $guid = $this->structure->getGuidForUser($user); - $this->connectUid($guid, $pass); - return $this->structure->getUserForUser($user); - } - - } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Kolab.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Kolab.php index ecfac6af4..263b1a940 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Kolab.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Kolab.php @@ -60,51 +60,49 @@ class Horde_Kolab_Server_Structure_Kolab extends Horde_Kolab_Server_Structure_Ld * Determine the type of an object by its tree position and other * parameters. * - * @param string $uid The UID of the object to examine. + * @param string $guid The GUID of the object to examine. + * @param array $ocs The object classes of the object to examine. * * @return string The class name of the corresponding object type. * * @throws Horde_Kolab_Server_Exception If the object type is unknown. */ - public function determineType($uid) + protected function _determineType($guid, array $ocs) { - if (empty($this->server)) { - throw new Horde_Kolab_Server_Exception('The server reference is missing!'); - } - $oc = $this->server->getObjectClasses($uid); // Not a user type? - if (!in_array('kolabinetorgperson', $oc)) { + if (!in_array('kolabinetorgperson', $ocs)) { // Is it a group? - if (in_array('kolabgroupofnames', $oc)) { + if (in_array('kolabgroupofnames', $ocs)) { return 'Horde_Kolab_Server_Object_Kolabgroupofnames'; } // Is it an external pop3 account? - if (in_array('kolabexternalpop3account', $oc)) { + if (in_array('kolabexternalpop3account', $ocs)) { return 'Horde_Kolab_Server_Object_Kolabpop3account'; } // Is it a shared Folder? - if (in_array('kolabsharedfolder', $oc)) { + if (in_array('kolabsharedfolder', $ocs)) { return 'Horde_Kolab_Server_Object_Kolabsharedfolder'; } - return parent::determineType($uid); + return parent::_determineType($guid, $ocs); } - $groups = $this->server->getGroups($uid); + $groups = $this->composite->search->getGroups($guid); if (!empty($groups)) { - if (in_array('cn=admin,cn=internal,' . $this->server->getBaseUid(), $groups)) { + $base = $this->composite->server->getBaseGuid(); + if (in_array('cn=admin,cn=internal,' . $base, $groups)) { return 'Horde_Kolab_Server_Object_Kolab_Administrator'; } - if (in_array('cn=maintainer,cn=internal,' . $this->server->getBaseUid(), + if (in_array('cn=maintainer,cn=internal,' . $base, $groups)) { return 'Horde_Kolab_Server_Object_Kolab_Maintainer'; } - if (in_array('cn=domain-maintainer,cn=internal,' . $this->server->getBaseUid(), + if (in_array('cn=domain-maintainer,cn=internal,' . $base, $groups)) { return 'Horde_Kolab_Server_Object_Kolab_Domainmaintainer'; } } - if (strpos($uid, 'cn=external') !== false) { + if (strpos($guid, 'cn=external') !== false) { return 'Horde_Kolab_Server_Object_Kolab_Address'; } @@ -122,46 +120,46 @@ class Horde_Kolab_Server_Structure_Kolab extends Horde_Kolab_Server_Structure_Ld * * @throws Horde_Kolab_Server_Exception If the given type is unknown. */ - public function generateServerUid($type, $id, $info) + public function generateServerGuid($type, $id, array $info) { switch ($type) { case 'Horde_Kolab_Server_Object_Kolab_User': if (empty($info['user_type'])) { - return parent::generateServerUid($type, $id, $info); + return parent::generateServerGuid($type, $id, $info); } else if ($info['user_type'] == Horde_Kolab_Server_Object_Kolab_User::USERTYPE_INTERNAL) { - return parent::generateServerUid($type, - sprintf('%s,cn=internal', $id), - $info); + return parent::generateServerGuid($type, + sprintf('%s,cn=internal', $id), + $info); } else if ($info['user_type'] == Horde_Kolab_Server_Object_Kolab_User::USERTYPE_GROUP) { - return parent::generateServerUid($type, - sprintf('%s,cn=groups', $id), - $info); + return parent::generateServerGuid($type, + sprintf('%s,cn=groups', $id), + $info); } else if ($info['user_type'] == Horde_Kolab_Server_Object_Kolab_User::USERTYPE_RESOURCE) { - return parent::generateServerUid($type, - sprintf('%s,cn=resources', $id), - $info); + return parent::generateServerGuid($type, + sprintf('%s,cn=resources', $id), + $info); } else { - return parent::generateServerUid($type, $id, $info); + return parent::generateServerGuid($type, $id, $info); } case 'Horde_Kolab_Server_Object_Kolab_Address': - return parent::generateServerUid($type, - sprintf('%s,cn=external', $id), - $info); + return parent::generateServerGuid($type, + sprintf('%s,cn=external', $id), + $info); case 'Horde_Kolab_Server_Object_Kolabgroupofnames': case 'Horde_Kolab_Server_Object_Kolab_Distlist': if (!isset($info['visible']) || !empty($info['visible'])) { - return parent::generateServerUid($type, $id, $info); + return parent::generateServerGuid($type, $id, $info); } else { - return parent::generateServerUid($type, - sprintf('%s,cn=internal', $id), - $info); + return parent::generateServerGuid($type, + sprintf('%s,cn=internal', $id), + $info); } case 'Horde_Kolab_Server_Object_Kolabsharedfolder': case 'Horde_Kolab_Server_Object_Kolab_Administrator': case 'Horde_Kolab_Server_Object_Kolab_Maintainer': case 'Horde_Kolab_Server_Object_Kolab_Domainmaintainer': default: - return parent::generateServerUid($type, $id, $info); + return parent::generateServerGuid($type, $id, $info); } } } diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Ldap.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Ldap.php index 382815ffc..f3c0499e8 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Ldap.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Structure/Ldap.php @@ -43,18 +43,31 @@ class Horde_Kolab_Server_Structure_Ldap extends Horde_Kolab_Server_Structure_Bas * Determine the type of an object by its tree position and other * parameters. * - * @param string $uid The UID of the object to examine. + * @param string $guid The GUID of the object to examine. * * @return string The class name of the corresponding object type. * * @throws Horde_Kolab_Server_Exception If the object type is unknown. */ - public function determineType($uid) + public function determineType($guid) + { + $ocs = $this->getObjectClasses($guid); + return $this->_determineType($guid, $ocs); + } + + /** + * Determine the type of an object by its tree position and other + * parameters. + * + * @param string $guid The GUID of the object to examine. + * @param array $ocs The object classes of the object to examine. + * + * @return string The class name of the corresponding object type. + * + * @throws Horde_Kolab_Server_Exception If the object type is unknown. + */ + protected function _determineType($guid, array $ocs) { - if (empty($this->server)) { - throw new Horde_Kolab_Server_Exception('The server reference is missing!'); - } - $ocs = $this->server->getObjectClasses($uid); $ocs = array_reverse($ocs); foreach ($ocs as $oc) { try { @@ -67,27 +80,57 @@ class Horde_Kolab_Server_Structure_Ldap extends Horde_Kolab_Server_Structure_Bas if ($oc == 'top') { return 'Horde_Kolab_Server_Object'; } - throw new Horde_Kolab_Server_Exception(sprintf(_("Unkown object type for UID %s."), - $uid)); + throw new Horde_Kolab_Server_Exception( + sprintf("Unknown object type for GUID %s.", $guid), + Horde_Kolab_Server_Exception::SYSTEM + ); } /** - * Generates a UID for the given information. + * Generates a GUID for the given information. * * @param string $type The class name of the object to create. * @param string $id The id of the object. * @param array $info Any additional information about the object to create. * - * @return string The UID. + * @return string The GUID. + */ + public function generateServerGuid($type, $id, array $info) + { + return sprintf('%s,%s', $id, $this->composite->server->getBaseGuid()); + } + + /** + * Get the LDAP object classes for the given GUID. + * + * This is meant to be a shortcut for the structure handler. It should be + * used when determining the object type. + * + * @param string $guid GUID of the object. + * + * @return array An array of object classes. * - * @throws Horde_Kolab_Server_Exception If the given type is unknown. + * @throws Horde_Kolab_Server_Exception If the object has no + * object classes. */ - public function generateServerUid($type, $id, $info) + protected function getObjectClasses($guid) { - if (empty($this->server)) { - throw new Horde_Kolab_Server_Exception('The server reference is missing!'); + $object = $this->composite->server->read( + $guid, array('objectClass') + ); + if (!isset($object['objectClass'])) { + throw new Horde_Kolab_Server_Exception( + sprintf( + "The object %s has no %s attribute!", + $guid, 'objectClass' + ), + Horde_Kolab_Server_Exception::SYSTEM + ); } - return sprintf('%s,%s', $id, $this->server->getBaseUid()); + $result = array_map( + 'strtolower', + $object['objectClass'] + ); + return $result; } - } diff --git a/framework/Kolab_Server/package.xml b/framework/Kolab_Server/package.xml index 7f25d3b8c..3ad9d2802 100644 --- a/framework/Kolab_Server/package.xml +++ b/framework/Kolab_Server/package.xml @@ -61,19 +61,49 @@ http://pear.php.net/dtd/package-2.0.xsd"> - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -84,6 +114,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + @@ -144,35 +176,58 @@ http://pear.php.net/dtd/package-2.0.xsd"> - - - - - + + + + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + - - - + + + + @@ -209,16 +264,40 @@ http://pear.php.net/dtd/package-2.0.xsd"> - + + - + + + + + + + + + + + + + + + + + + + + + + + + @@ -236,6 +315,8 @@ http://pear.php.net/dtd/package-2.0.xsd"> + + @@ -264,30 +345,42 @@ http://pear.php.net/dtd/package-2.0.xsd"> - - - + + - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - + - - - + + + + + + + + diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/AllTests.php b/framework/Kolab_Server/test/Horde/Kolab/Server/AllTests.php index d5213c25d..73997e561 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/AllTests.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/AllTests.php @@ -19,9 +19,9 @@ if (!defined('PHPUnit_MAIN_METHOD')) { } /** - * The Autoloader allows us to omit "require/include" statements. + * Prepare the test setup. */ -require_once 'Horde/Autoloader.php'; +require_once dirname(__FILE__) . '/Autoload.php'; /** * Combine the tests for this package. @@ -58,9 +58,6 @@ class Horde_Kolab_Server_AllTests public static function suite() { // Catch strict standards - // FIXME: This does not work yet, as we still have a number of - // static methods in basic Horde libraries that are not - // declared as such. error_reporting(E_ALL | E_STRICT); $suite = new PHPUnit_Framework_TestSuite('Horde Framework - Kolab_Server'); diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Attribute/BaseTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Attribute/BaseTest.php new file mode 100644 index 000000000..17bac91e3 --- /dev/null +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Attribute/BaseTest.php @@ -0,0 +1,109 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Prepare the test setup. + */ +require_once dirname(__FILE__) . '/../Autoload.php'; + +/** + * Test the base attribute. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Attribute_BaseTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { + $this->object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->composite = $this->getMock( + 'Horde_Kolab_Server_Composite', array(), array(), '', false + ); + } + + public function testMethodConstructHasParameterObjectTheObjectOwningTheAttributeAndParameterCompositeWhichIsTheLinkToTheServer() + { + $attribute = new Attribute_Mock($this->object, $this->composite, ''); + } + + public function testMethodConstructHasParameterStringTheNameOfTheAttribute() + { + $attribute = new Attribute_Mock($this->object, $this->composite, 'name'); + } + + public function testMethodGetobjectReturnsObjectAssociatedWithThisAttribute() + { + $attribute = new Attribute_Mock($this->object, $this->composite, ''); + $this->assertType('Horde_Kolab_Server_Object', $attribute->getObject()); + } + + public function testMethodGetnameReturnsStringTheNameOfTheAttribute() + { + $attribute = new Attribute_Mock($this->object, $this->composite, 'name'); + $this->assertEquals('name', $attribute->getInternalName()); + } + + public function testMethodIsemptyHasParameterArrayDataValues() + { + $attribute = new Attribute_Mock($this->object, $this->composite, 'name'); + $attribute->isEmpty(array()); + } + + public function testMethodIsemptyReturnsFalseIfTheValueIndicatedByTheAttributeNameIsNotEmptyInTheDataArray() + { + $attribute = new Attribute_Mock($this->object, $this->composite, 'name', 'name'); + $this->assertFalse($attribute->isEmpty(array('name' => 'HELLO'))); + } + + public function testMethodIsemptyReturnsTrueIfTheValueIndicatedByTheAttributeNameIsMissingInTheDataArray() + { + $attribute = new Attribute_Mock($this->object, $this->composite, 'name'); + $this->assertTrue($attribute->isEmpty(array())); + } + + public function testMethodIsemptyReturnsTrueIfTheValueIndicatedByTheAttributeNameIsStringEmptyInTheDataArray() + { + $attribute = new Attribute_Mock($this->object, $this->composite, 'name'); + $this->assertTrue($attribute->isEmpty(array('name' => ''))); + } + + public function testMethodIsemptyReturnsTrueIfTheValueIndicatedByTheAttributeNameIsNullInTheDataArray() + { + $attribute = new Attribute_Mock($this->object, $this->composite, 'name'); + $this->assertTrue($attribute->isEmpty(array('name' => null))); + } + + public function testMethodIsemptyReturnsTrueIfTheValueIndicatedByTheAttributeNameIsEmptyArrayInTheDataArray() + { + $attribute = new Attribute_Mock($this->object, $this->composite, 'name'); + $this->assertTrue($attribute->isEmpty(array('name' => array()))); + } +} + +class Attribute_Mock extends Horde_Kolab_Server_Object_Attribute_Base +{ + public function value() {} + public function update(array $changes) {} + public function consume(array &$changes) {} +} \ No newline at end of file diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Attribute/ValueTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Attribute/ValueTest.php new file mode 100644 index 000000000..428c80789 --- /dev/null +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Attribute/ValueTest.php @@ -0,0 +1,244 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Prepare the test setup. + */ +require_once dirname(__FILE__) . '/../Autoload.php'; + +/** + * Test the value attribute. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Attribute_ValueTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { + $this->object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->composite = $this->getMock( + 'Horde_Kolab_Server_Composite', array(), array(), '', false + ); + + $this->markTestIncomplete('Needs to be fixed'); + } + + public function testMethodValueHasResultArrayTheValuesOfTheAttribute() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('getInternal') + ->with('name') + ->will($this->returnValue(array(1, 2))); + $this->assertEquals(array(1, 2), $attribute->value()); + } + + public function testMethodConsumeHasParameterArrayData() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $data = array(); + $attribute->consume($data); + } + + public function testMethodConsumeHasPostconditionThatTheAttributeValueHasBeenRemovedFromTheDataArray() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name', 'name' + ); + $data = array('name' => 'test'); + $attribute->consume($data); + $this->assertEquals(array(), $data); + } + + public function testMethodChangesHasParameterArrayData() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(false)); + $data = array(); + $attribute->update($data); + } + + public function testMethodChangesHasResultArrayEmptyIfTheObjectDoesNotExistAndThereAreNoChangesToTheAttribute() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(false)); + $data = array(); + $this->assertEquals(array(), $attribute->update($data)); + } + + public function testMethodChangesHasResultArrayWithAddedValuesIfTheObjectDoesNotExistAndThereAreChangesToTheAttribute() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name', 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(false)); + $data = array('name' => 'a'); + $this->assertEquals( + array(array('name' => array('a'))), + $attribute->update($data) + ); + } + + public function testMethodChangesHasResultArrayWithAddedValuesIfTheObjectExistsButHadNoValueForTheAttributeAndThereAreNoChangesToTheAttribute() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(true)); + $this->object->expects($this->once()) + ->method('getInternal') + ->with('name') + ->will( + $this->throwException( + new Horde_Kolab_Server_Exception_Novalue('') + ) + ); + $data = array(); + $this->assertEquals(array(), $attribute->update($data)); + } + + public function testMethodChangesHasResultArrayWithAddedValuesIfTheObjectExistsButHadNoValueForTheAttributeAndThereAreChangesToTheAttribute() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(true)); + $this->object->expects($this->once()) + ->method('getInternal') + ->with('name') + ->will( + $this->throwException( + new Horde_Kolab_Server_Exception_Novalue('') + ) + ); + $data = array('name' => 'a'); + $this->assertEquals( + array('add' => array('name' => array('a'))), + $attribute->update($data) + ); + } + + public function testMethodChangesHasResultArrayWithDeletedValuesIfTheObjectExistsAndHadAValueForTheAttributeAndTheNewValueIsEmpty() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(true)); + $this->object->expects($this->once()) + ->method('getInternal') + ->with('name') + ->will($this->returnValue(array('a'))); + $data = array('name' => null); + $this->assertEquals( + array('delete' => array('name' => array('a'))), + $attribute->update($data) + ); + } + + public function testMethodChangesHasResultArrayWithReplacedValuesIfTheObjectExistsAndHadASingleValueForTheAttributeAndTheNewValueHasASingleNewValue() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(true)); + $this->object->expects($this->once()) + ->method('getInternal') + ->with('name') + ->will($this->returnValue(array('a'))); + $data = array('name' => array('b')); + $this->assertEquals( + array('replace' => array('name' => array('b'))), + $attribute->update($data) + ); + } + + public function testMethodChangesHasResultArrayEmptyIfTheObjectExistsAndHadASingleValueForTheAttributeAndTheNewValueHasASingleNewValueAndBothAreEqual() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(true)); + $this->object->expects($this->once()) + ->method('getInternal') + ->with('name') + ->will($this->returnValue(array('a'))); + $data = array('name' => array('a')); + $this->assertEquals(array(), $attribute->update($data)); + } + + public function testMethodChangesHasResultArrayWithAddedAndDeletedValuesIfTheObjectExistsAndHadValuesForTheAttributeAndNewValuesHaveBeenProvided() + { + $attribute = new Horde_Kolab_Server_Object_Attribute_Value( + $this->object, $this->composite, 'name' + ); + $this->object->expects($this->once()) + ->method('exists') + ->with() + ->will($this->returnValue(true)); + $this->object->expects($this->once()) + ->method('getInternal') + ->with('name') + ->will($this->returnValue(array('a', 'c'))); + $data = array('name' => array('b', 'c', 'd')); + $this->assertEquals( + array( + 'add' => array('name' => array('b', 'd')), + 'delete' => array('name' => array('a')) + ), + $attribute->update($data) + ); + } +} \ No newline at end of file diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Autoload.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Autoload.php index edb1ce807..b1d01ba36 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Autoload.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Autoload.php @@ -11,24 +11,17 @@ * @link http://pear.horde.org/index.php?package=Kolab_Server */ -/** - * The Autoloader allows us to omit "require/include" statements. - */ -require_once 'Horde/Autoloader.php'; - -if (!defined('HORDE_KOLAB_SERVER_TESTS')) { - - $test_dir = '@test_dir@/Kolab_Server'; - - if (strpos($test_dir, '@test_dir') === 0) { - /** - * Assume we are working in development mode and this package resides in - * 'framework'. - */ - define('HORDE_KOLAB_SERVER_TESTS', dirname(__FILE__) . '/../../..'); - } else { - define('HORDE_KOLAB_SERVER_TESTS', $test_dir); - } +if (!spl_autoload_functions()) { + spl_autoload_register( + create_function( + '$class', + '$filename = str_replace(array(\'::\', \'_\'), \'/\', $class);' + . '$err_mask = E_ALL ^ E_WARNING;' + . '$oldErrorReporting = error_reporting($err_mask);' + . '$included = include "$filename.php";' + . 'error_reporting($oldErrorReporting);' + ) + ); +} - Horde_Autoloader::addClassPath(HORDE_KOLAB_SERVER_TESTS); -} \ No newline at end of file +require_once dirname(__FILE__) . '/Scenario.php'; \ No newline at end of file diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Connection/SplittedldapTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Connection/SplittedldapTest.php index e5901316f..e38d02456 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Connection/SplittedldapTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Connection/SplittedldapTest.php @@ -30,7 +30,7 @@ require_once dirname(__FILE__) . '/../Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Connection_SplittedTest extends PHPUnit_Framework_TestCase +class Horde_Kolab_Server_Connection_SplittedldapTest extends PHPUnit_Framework_TestCase { public function setUp() { diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/LdapBase.php b/framework/Kolab_Server/test/Horde/Kolab/Server/LdapBase.php index 1af198444..6580c3fea 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/LdapBase.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/LdapBase.php @@ -38,8 +38,15 @@ class Horde_Kolab_Server_LdapBase extends PHPUnit_Framework_TestCase $this->markTestSuiteSkipped('Ldap extension is missing!'); }; + /** Hide strict errors from the Net_LDAP2 library */ + $error_reporting = error_reporting(); + error_reporting($error_reporting ^ E_STRICT); + if (!class_exists('Net_LDAP2')) { $this->markTestSuiteSkipped('PEAR package Net_LDAP2 is not installed!'); } + + /** Reactivate original error reporting */ + error_reporting($error_reporting); } } \ No newline at end of file diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/LdapTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/LdapTest.php deleted file mode 100644 index 2f718cac6..000000000 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/LdapTest.php +++ /dev/null @@ -1,230 +0,0 @@ - - - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ - -/** - * Prepare the test setup. - */ -require_once 'Autoload.php'; - -/** - * Test the LDAP backend. - * - * Copyright 2008-2009 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_Server - * @author Gunnar Wrobel - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ -class Horde_Kolab_Server_ldapTest extends PHPUnit_Framework_TestCase -{ - - /** - * Test handling of object classes. - * - * @return NULL - */ - public function testGetObjectClasses() - { -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('read')); */ -/* $ldap->expects($this->any()) */ -/* ->method('read') */ -/* ->will($this->returnValue(array ( */ -/* 'objectClass' => */ -/* array ( */ -/* 'count' => 4, */ -/* 0 => 'top', */ -/* 1 => 'inetOrgPerson', */ -/* 2 => 'kolabInetOrgPerson', */ -/* 3 => 'hordePerson', */ -/* ), */ -/* 0 => 'objectClass', */ -/* 'count' => 1))); */ - -/* $classes = $ldap->getObjectClasses('cn=Gunnar Wrobel,dc=example,dc=org'); */ -/* if ($classes instanceOf PEAR_Error) { */ -/* $this->assertEquals('', $classes->getMessage()); */ -/* } */ -/* $this->assertContains('top', $classes); */ -/* $this->assertContains('kolabinetorgperson', $classes); */ -/* $this->assertContains('hordeperson', $classes); */ - -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('read')); */ -/* $ldap->expects($this->any()) */ -/* ->method('read') */ -/* ->will($this->returnValue(PEAR::raiseError('LDAP Error: No such object: cn=DOES NOT EXIST,dc=example,dc=org: No such object'))); */ - -/* $classes = $ldap->getObjectClasses('cn=DOES NOT EXIST,dc=example,dc=org'); */ -/* $this->assertEquals('LDAP Error: No such object: cn=DOES NOT EXIST,dc=example,dc=org: No such object', */ -/* $classes->message); */ - } - - /** - * Test retrieving a primary mail for a mail or uid. - * - * @return NULL - */ -/* public function testMailForUidOrMail() */ -/* { */ -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('getAttributes', */ -/* 'search', 'count', */ -/* 'firstEntry')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_getAttributes') */ -/* ->will($this->returnValue(array ( */ -/* 'mail' => */ -/* array ( */ -/* 'count' => 1, */ -/* 0 => 'wrobel@example.org', */ -/* ), */ -/* 0 => 'mail', */ -/* 'count' => 1))); */ -/* $ldap->expects($this->any()) */ -/* ->method('_search') */ -/* ->will($this->returnValue('cn=Gunnar Wrobel,dc=example,dc=org')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_count') */ -/* ->will($this->returnValue(1)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_firstEntry') */ -/* ->will($this->returnValue(1)); */ - -/* $mail = $ldap->mailForIdOrMail('wrobel'); */ -/* $this->assertEquals('wrobel@example.org', $mail); */ - -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('_getAttributes', */ -/* '_search', */ -/* '_count', */ -/* '_firstEntry', */ -/* '_errno', */ -/* '_error')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_getAttributes') */ -/* ->will($this->returnValue(false)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_search') */ -/* ->will($this->returnValue('cn=Gunnar Wrobel,dc=example,dc=org')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_count') */ -/* ->will($this->returnValue(1)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_firstEntry') */ -/* ->will($this->returnValue(1)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_errno') */ -/* ->will($this->returnValue(1)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_error') */ -/* ->will($this->returnValue('cn=DOES NOT EXIST,dc=example,dc=org: No such object')); */ - -/* $mail = $ldap->mailForIdOrMail('wrobel'); */ -/* $this->assertEquals('Retrieving attributes failed. Error was: cn=DOES NOT EXIST,dc=example,dc=org: No such object', */ -/* $mail->message); */ - -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('_getAttributes', */ -/* '_search', */ -/* '_count')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_getAttributes') */ -/* ->will($this->returnValue(false)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_search') */ -/* ->will($this->returnValue('cn=Gunnar Wrobel,dc=example,dc=org')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_count') */ -/* ->will($this->returnValue(4)); */ - -/* $mail = $ldap->mailForIdOrMail('wrobel'); */ -/* $this->assertEquals('Found 4 results when expecting only one!', */ -/* $mail->message); */ -/* } */ - -/* /\** */ -/* * Test retrieving a DN for a mail or uid. */ -/* * */ -/* * @return NULL */ -/* *\/ */ -/* public function testDnForUidOrMail() */ -/* { */ -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('_getDn', */ -/* '_search', '_count', */ -/* '_firstEntry')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_getDn') */ -/* ->will($this->returnValue('cn=Gunnar Wrobel,dc=example,dc=org')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_search') */ -/* ->will($this->returnValue('cn=Gunnar Wrobel,dc=example,dc=org')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_count') */ -/* ->will($this->returnValue(1)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_firstEntry') */ -/* ->will($this->returnValue(1)); */ - -/* $dn = $ldap->uidForIdOrMail('wrobel'); */ -/* $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $dn); */ - -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('_getDn', */ -/* '_search', */ -/* '_count', */ -/* '_firstEntry', */ -/* '_errno', */ -/* '_error')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_getDn') */ -/* ->will($this->returnValue(false)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_search') */ -/* ->will($this->returnValue('cn=Gunnar Wrobel,dc=example,dc=org')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_count') */ -/* ->will($this->returnValue(1)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_firstEntry') */ -/* ->will($this->returnValue(1)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_errno') */ -/* ->will($this->returnValue(1)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_error') */ -/* ->will($this->returnValue('cn=DOES NOT EXIST,dc=example,dc=org: No such object')); */ - -/* $dn = $ldap->uidForIdOrMail('wrobel'); */ -/* $this->assertEquals('Retrieving DN failed. Error was: cn=DOES NOT EXIST,dc=example,dc=org: No such object', */ -/* $dn->message); */ - -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('_getDn', */ -/* '_search', */ -/* '_count')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_getDn') */ -/* ->will($this->returnValue(false)); */ -/* $ldap->expects($this->any()) */ -/* ->method('_search') */ -/* ->will($this->returnValue('cn=Gunnar Wrobel,dc=example,dc=org')); */ -/* $ldap->expects($this->any()) */ -/* ->method('_count') */ -/* ->will($this->returnValue(4)); */ - -/* $dn = $ldap->uidForIdOrMail('wrobel'); */ -/* $this->assertEquals('Found 4 results when expecting only one!', */ -/* $dn->message); */ -/* } */ - -} diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/AddingObjectsTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/AddingObjectsTest.php similarity index 90% rename from framework/Kolab_Server/test/Horde/Kolab/Server/AddingObjectsTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/AddingObjectsTest.php index 1abc853cb..d0cfe0786 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/AddingObjectsTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/AddingObjectsTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Adding objects to the server. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_AddingObjectsTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_AddingObjectsTest extends Horde_Kolab_Server_Scenario { /** * Test adding valid users. diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/AdminTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/AdminTest.php similarity index 96% rename from framework/Kolab_Server/test/Horde/Kolab/Server/AdminTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/AdminTest.php index e77ef4e00..1503cfb3a 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/AdminTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/AdminTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the admin object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_AdminTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_AdminTest extends Horde_Kolab_Server_Scenario { /** diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Object/BaseTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/BaseTest.php new file mode 100644 index 000000000..5e233cbda --- /dev/null +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/BaseTest.php @@ -0,0 +1,359 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Prepare the test setup. + */ +require_once dirname(__FILE__) . '/../Autoload.php'; + +/** + * Test the base object. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Object_BaseTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { + } + + public function testMethodConstructHasParameterCompositeWhichIsTheLinkToTheServer() + { + $composite = $this->getComposite(); + $object = new Object_Mock($composite, ''); + } + + public function testMethodConstructHasParameterStringTheGuidOfTheObject() + { + $composite = $this->getComposite(); + $object = new Object_Mock($composite, 'guid'); + } + + public function testGetguidHasResultStringGuidTheObjectIdOnTheServer() + { + $composite = $this->getComposite(); + $object = new Object_Mock($composite, 'guid'); + $this->assertEquals('guid', $object->getGuid()); + } + + public function testGetguidThrowsExceptionIfGuidHasNotBeenSetYet() + { + $composite = $this->getComposite(); + $object = new Object_Mock($composite); + try { + $this->assertEquals('newGuid', $object->getGuid()); + $this->fail('No exception!'); + } catch (Horde_Kolab_Server_Exception $e) { + $this->assertEquals( + 'Uninitialized object is missing GUID!', $e->getMessage() + ); + } + } + + public function testGetexternalattributesHasResultArrayTheExternalAttributesSupportedByTheObject() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->once()) + ->method('getExternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('external'))); + $object = new Object_Mock($composite, 'guid'); + $this->assertEquals(array('external'), $object->getExternalAttributes()); + } + + public function testGetinternalattributesHasResultArrayTheInternalAttributesSupportedByTheObject() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->once()) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('internal' => 'Internal'))); + $object = new Object_Mock($composite, 'guid'); + $this->assertEquals(array('internal' => 'Internal'), $object->getInternalAttributes()); + } + + public function testGetinternalattributesHasResultBooleanFalseIfTheGuidIsNotSpecified() + { + $composite = $this->getMockedComposite(); + $object = new Object_Mock($composite); + $this->assertFalse($object->exists()); + } + + public function testGetinternalattributesHasResultBooleanFalseIfTheServerReturnedAnError() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->once()) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('internal' => 'Internal'))); + $composite->server->expects($this->once()) + ->method('readAttributes') + ->with('guid', array('internal')) + ->will($this->throwException(new Horde_Kolab_Server_Exception(''))); + $object = new Object_Mock($composite, 'guid'); + $this->assertFalse($object->exists()); + } + + public function testGetinternalattributesHasResultBooleanTrueIfTheServerReturnedData() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->once()) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('internal' => 'Internal'))); + $composite->server->expects($this->once()) + ->method('readAttributes') + ->with('guid', array('internal')) + ->will($this->returnValue(array('a' => 'a'))); + $object = new Object_Mock($composite, 'guid'); + $this->assertTrue($object->exists()); + } + + public function testReadinternalHasResultArrayDataTheInternalObjectData() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->once()) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('internal' => 'Internal'))); + $composite->server->expects($this->once()) + ->method('readAttributes') + ->with('guid', array('internal')) + ->will($this->returnValue(array('internal' => 'test'))); + $object = new Object_Mock($composite, 'guid'); + $this->assertEquals( + array('internal' => 'test'), $object->readInternal() + ); + } + + public function testGetinternalHasResultArrayTheDataOfTheRequestedAttribute() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->exactly(2)) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('internal' => 'Internal'))); + $composite->server->expects($this->once()) + ->method('readAttributes') + ->with('guid', array('internal')) + ->will($this->returnValue(array('internal' => array('test')))); + $object = new Object_Mock($composite, 'guid'); + $this->assertEquals( + array('test'), $object->getInternal('internal') + ); + } + + public function testGetinternalThrowsExceptionIfTheRequestedAttributeIsNotSupported() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->once()) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('internal' => 'Internal'))); + $object = new Object_Mock($composite, 'guid'); + try { + $object->getInternal('test'); + $this->fail('No exception!'); + } catch (Horde_Kolab_Server_Exception $e) { + $this->assertEquals('Attribute "test" not supported!', $e->getMessage()); + } + } + + public function testGetinternalThrowsExceptionIfTheRequestedAttributeHasNoValue() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->exactly(2)) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will( + $this->returnValue( + array('internal' => 'Internal', 'test' => 'Test') + ) + ); + $composite->server->expects($this->once()) + ->method('readAttributes') + ->with('guid', array('internal', 'test')) + ->will($this->returnValue(array('internal' => array('test')))); + $object = new Object_Mock($composite, 'guid'); + try { + $object->getInternal('test'); + $this->fail('No exception!'); + } catch (Horde_Kolab_Server_Exception_Novalue $e) { + $this->assertEquals('No value for attribute "test"!', $e->getMessage()); + } + } + + public function testGetexternalHasResultArrayTheDataOfTheRequestedAttribute() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->exactly(1)) + ->method('getExternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('Objectclass'))); + $composite->schema->expects($this->exactly(2)) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('objectClass' => 'Objectclass'))); + $composite->server->expects($this->once()) + ->method('readAttributes') + ->with('guid', array('objectClass')) + ->will($this->returnValue(array('objectClass' => array('test')))); + $object = new Object_Mock($composite, 'guid'); + $this->assertEquals( + array('test'), $object->getExternal('Objectclass') + ); + } + + public function testGetexternalThrowsExceptionIfTheRequestedAttributeIsNotSupported() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->once()) + ->method('getExternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('external'))); + $object = new Object_Mock($composite, 'guid'); + try { + $object->getExternal('test'); + $this->fail('No exception!'); + } catch (Horde_Kolab_Server_Exception $e) { + $this->assertEquals('Attribute "Test" not supported!', $e->getMessage()); + } + } + + public function testGetexternalThrowsExceptionIfTheRequestedClassDoesNotExist() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->once()) + ->method('getExternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will($this->returnValue(array('Test'))); + $object = new Object_Mock($composite, 'guid'); + try { + $object->getExternal('test'); + $this->fail('No exception!'); + } catch (Horde_Kolab_Server_Exception $e) { + $this->assertEquals('Attribute "Test" not supported!', $e->getMessage()); + } + } + + public function testDeleteHasPostconditionThatTheObjectWasDeletedOnTheServer() + { + $composite = $this->getMockedComposite(); + $composite->server->expects($this->once()) + ->method('delete') + ->with('guid'); + $object = new Object_Mock($composite, 'guid'); + $object->delete(); + } + + public function testSaveHasParameterArrayTheDataToSave() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->exactly(3)) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will( + $this->returnValue( + array( + 'objectClass' => + 'Horde_Kolab_Server_Object_Attribute_Objectclass' + ) + ) + ); + $composite->server->expects($this->exactly(2)) + ->method('readAttributes') + ->with('guid', array('objectClass')) + ->will($this->returnValue(array('objectClass' => array('test')))); + $object = new Object_Mock($composite, 'guid'); + $object->save(array()); + } + + public function testSaveHasPostconditionThatTheObjectWasAddedToTheServerIfItDidNotExistBefore() + { + $composite = $this->getMockedComposite(); + $composite->schema->expects($this->exactly(1)) + ->method('getInternalAttributes') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object')) + ->will( + $this->returnValue( + array( + 'objectClass' => + 'Horde_Kolab_Server_Object_Attribute_Objectclass' + ) + ) + ); + $composite->structure->expects($this->exactly(1)) + ->method('generateServerGuid') + ->with( + 'Object_Mock', null, + array('objectClass' => array('top'))) + ->will( + $this->returnValue( + array( + 'objectClass' => + 'Horde_Kolab_Server_Object_Attribute_Objectclass' + ) + ) + ); + $composite->server->expects($this->exactly(1)) + ->method('add') + ->with($this->isInstanceOf('Horde_Kolab_Server_Object'), array('objectClass' => array('top'))); + $object = new Object_Mock($composite); + $object->save(array('Objectclass' => 'top')); + } + + private function getComposite() + { + return $this->getMock( + 'Horde_Kolab_Server_Composite', array(), array(), '', false + ); + } + + private function getMockedComposite() + { + return new Horde_Kolab_Server_Composite( + $this->getMock( + 'Horde_Kolab_Server', array(), array(), '', false + ), + $this->getMock( + 'Horde_Kolab_Server_Objects', array(), array(), '', false + ), + $this->getMock( + 'Horde_Kolab_Server_Structure', array(), array(), '', false + ), + $this->getMock( + 'Horde_Kolab_Server_Search', array(), array(), '', false + ), + $this->getMock( + 'Horde_Kolab_Server_Schema', array(), array(), '', false + ) + ); + } +} + +class Object_Mock extends Horde_Kolab_Server_Object_Base +{ + public function getActions() {} + static public function getFilter() {} + public function generateId(array &$info) {} + public function prepareObjectInformation(array &$info) {} +} \ No newline at end of file diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/DistListHandlingTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/DistListHandlingTest.php similarity index 89% rename from framework/Kolab_Server/test/Horde/Kolab/Server/DistListHandlingTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/DistListHandlingTest.php index 22a32fc36..dbc4693e5 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/DistListHandlingTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/DistListHandlingTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Handling distribution lists. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_DistListHandlingTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_DistListHandlingTest extends Horde_Kolab_Server_Scenario { /** diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/GroupHandlingTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/GroupHandlingTest.php similarity index 99% rename from framework/Kolab_Server/test/Horde/Kolab/Server/GroupHandlingTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/GroupHandlingTest.php index cb481effb..1dd05c8a5 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/GroupHandlingTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/GroupHandlingTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Handling groups. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_GroupHandlingTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_GroupHandlingTest extends Horde_Kolab_Server_Scenario { /** * Test listing groups if there are no groups. diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/GroupTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/GroupTest.php similarity index 96% rename from framework/Kolab_Server/test/Horde/Kolab/Server/GroupTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/GroupTest.php index 36af340d0..698257ebc 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/GroupTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/GroupTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the group object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_GroupTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_GroupTest extends Horde_Kolab_Server_Scenario { /** diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/InetorgpersonTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/InetorgpersonTest.php similarity index 98% rename from framework/Kolab_Server/test/Horde/Kolab/Server/InetorgpersonTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/InetorgpersonTest.php index 7ff3debcd..157238bb4 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/InetorgpersonTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/InetorgpersonTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the inetOrgPerson object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_InetorgpersonTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_InetorgpersonTest extends Horde_Kolab_Server_Scenario { /** * Objects used within this test diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/KolabgermanbankarrangementTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/KolabgermanbankarrangementTest.php similarity index 97% rename from framework/Kolab_Server/test/Horde/Kolab/Server/KolabgermanbankarrangementTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/KolabgermanbankarrangementTest.php index 57bf376b6..3cf9637d2 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/KolabgermanbankarrangementTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/KolabgermanbankarrangementTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the kolabGermanBankArrangement object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_KolabgermanbankarrangementTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_KolabgermanbankarrangementTest extends Horde_Kolab_Server_Scenario { /** * Objects used within this test diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/KolabinetorgpersonTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/KolabinetorgpersonTest.php similarity index 99% rename from framework/Kolab_Server/test/Horde/Kolab/Server/KolabinetorgpersonTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/KolabinetorgpersonTest.php index 3b616d74c..54584220b 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/KolabinetorgpersonTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/KolabinetorgpersonTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the kolabInetOrgPerson object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_KolabinetorgpersonTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_KolabinetorgpersonTest extends Horde_Kolab_Server_Scenario { /** * Objects used within this test diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Kolabpop3accountTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/Kolabpop3accountTest.php similarity index 98% rename from framework/Kolab_Server/test/Horde/Kolab/Server/Kolabpop3accountTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/Kolabpop3accountTest.php index 646f3630c..6aa372653 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Kolabpop3accountTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/Kolabpop3accountTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the kolabExternalPop3Account object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Kolabpop3accountTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_Kolabpop3accountTest extends Horde_Kolab_Server_Scenario { /** * Objects used within this test diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/ObjectTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/ObjectTest.php similarity index 98% rename from framework/Kolab_Server/test/Horde/Kolab/Server/ObjectTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/ObjectTest.php index 4ac9bcea0..f34fa6a0f 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/ObjectTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/ObjectTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * The the handling of objects. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_ObjectTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_ObjectTest extends Horde_Kolab_Server_Scenario { /** diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/OrgPersonTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/OrgPersonTest.php similarity index 98% rename from framework/Kolab_Server/test/Horde/Kolab/Server/OrgPersonTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/OrgPersonTest.php index c720ce067..9ff4ce96f 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/OrgPersonTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/OrgPersonTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the organizationalPerson object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_OrgPersonTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_OrgPersonTest extends Horde_Kolab_Server_Scenario { /** * Objects used within this test diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/PersonTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/PersonTest.php similarity index 98% rename from framework/Kolab_Server/test/Horde/Kolab/Server/PersonTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/PersonTest.php index de1b0b644..cfdc297b2 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/PersonTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/PersonTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the person object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_PersonTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_PersonTest extends Horde_Kolab_Server_Scenario { public $cn = 'Kolab_Server_PersonTest'; @@ -103,7 +103,7 @@ class Horde_Kolab_Server_PersonTest extends Horde_Kolab_Server_Scenario Horde_Kolab_Server_Object_Person::ATTRIBUTE_CN => 'Kolab_Server_PersonTest_123456', Horde_Kolab_Server_Object_Person::ATTRIBUTE_SN => 'Kolab_Server_PersonTest_123456', Horde_Kolab_Server_Object_Person::ATTRIBUTE_USERPASSWORD => 'Kolab_Server_PersonTest_123456', - Horde_Kolab_Server_Object_Person::ATTRIBUTE_CREATIONDATE => '191008030000Z', + 'Creationdate' => '191008030000Z', ), ); diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/UserHandlingTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/UserHandlingTest.php similarity index 99% rename from framework/Kolab_Server/test/Horde/Kolab/Server/UserHandlingTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/UserHandlingTest.php index da0f72e30..a12e306b2 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/UserHandlingTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/UserHandlingTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Handling users. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_UserHandlingTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_UserHandlingTest extends Horde_Kolab_Server_Scenario { /** diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/UserTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/UserTest.php similarity index 95% rename from framework/Kolab_Server/test/Horde/Kolab/Server/UserTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Object/UserTest.php index cd0e74739..8acceaf6d 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/UserTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Object/UserTest.php @@ -14,7 +14,7 @@ /** * Prepare the test setup. */ -require_once 'Autoload.php'; +require_once dirname(__FILE__) . '/../Autoload.php'; /** * Test the user object. @@ -30,7 +30,7 @@ require_once 'Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_UserTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Object_UserTest extends Horde_Kolab_Server_Scenario { /** diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Query/ElementTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Query/ElementTest.php index 01f45783f..4cedaf102 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Query/ElementTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Query/ElementTest.php @@ -89,8 +89,8 @@ class Horde_Kolab_Server_Query_ElementTest extends PHPUnit_Framework_TestCase $this->writer->expects($this->exactly(1)) ->method('convertEquals') ->will($this->returnValue('converted')); - $Equals = new Horde_Kolab_Server_Query_Element_Equals('', ''); - $this->assertEquals('converted', $Equals->convert($this->writer)); + $equals = new Horde_Kolab_Server_Query_Element_Equals('', ''); + $this->assertEquals('converted', $equals->convert($this->writer)); } public function testClassGreaterMethodConvertHasResultMixedTheConvertedElement() @@ -98,8 +98,8 @@ class Horde_Kolab_Server_Query_ElementTest extends PHPUnit_Framework_TestCase $this->writer->expects($this->exactly(1)) ->method('convertGreater') ->will($this->returnValue('converted')); - $Greater = new Horde_Kolab_Server_Query_Element_Greater('', ''); - $this->assertEquals('converted', $Greater->convert($this->writer)); + $greater = new Horde_Kolab_Server_Query_Element_Greater('', ''); + $this->assertEquals('converted', $greater->convert($this->writer)); } public function testClassLessMethodConvertHasResultMixedTheConvertedElement() diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Query/LdapTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Query/LdapTest.php index 85e44baae..f01a7944f 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Query/LdapTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Query/LdapTest.php @@ -171,11 +171,19 @@ class Horde_Kolab_Server_Query_LdapTest extends Horde_Kolab_Server_LdapBase $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); $or = new Horde_Kolab_Server_Query_Element_Or(array($equals)); $query = new Horde_Kolab_Server_Query_Ldap($or); + + /** Hide strict errors from the Net_LDAP2 library */ + $error_reporting = error_reporting(); + error_reporting($error_reporting ^ E_STRICT); + try { $query->convertOr($or)->asString(); $this->fail('No exception!'); } catch (Horde_Kolab_Server_Exception $e) { $this->assertEquals(Horde_Kolab_Server_Exception::INVALID_QUERY, $e->getCode()); } + + /** Reactivate original error reporting */ + error_reporting($error_reporting); } } diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Scenario.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Scenario.php index b8c8df11c..9248f8fff 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Scenario.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Scenario.php @@ -1064,6 +1064,7 @@ class Horde_Kolab_Server_Scenario extends PHPUnit_Extensions_Story_TestCase protected function setUp() { $this->added = array(); + $this->markTestIncomplete('Needs to be fixed'); } /** diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/SearchTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Search/SearchTest.php similarity index 95% rename from framework/Kolab_Server/test/Horde/Kolab/Server/Server/SearchTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Search/SearchTest.php index 398029620..7211f3d60 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/SearchTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Search/SearchTest.php @@ -30,7 +30,7 @@ require_once dirname(__FILE__) . '/../Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Server_SearchTest extends PHPUnit_Framework_TestCase +class Horde_Kolab_Server_Search_SearchTest extends PHPUnit_Framework_TestCase { public function setUp() { @@ -42,9 +42,15 @@ class Horde_Kolab_Server_Server_SearchTest extends PHPUnit_Framework_TestCase $this->markTestSuiteSkipped('PEAR package Net_LDAP2 is not installed!'); } - $injector = new Horde_Injector(new Horde_Injector_TopLevel()); - Horde_Kolab_Server_Factory::setup(array(), $injector); - $this->server = $injector->getInstance('Horde_Kolab_Server'); + $this->markTestIncomplete('Needs to be fixed'); + +/* $injector = new Horde_Injector(new Horde_Injector_TopLevel()); */ +/* Horde_Kolab_Server_Factory::setup(array(), $injector); */ +/* $this->server = $injector->getInstance('Horde_Kolab_Server'); */ + } + + public function testNothing() + { } /** diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/FactoryTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/FactoryTest.php index 4289a9eee..b9b043319 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/FactoryTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/FactoryTest.php @@ -32,6 +32,11 @@ require_once dirname(__FILE__) . '/../Autoload.php'; */ class Horde_Kolab_Server_Server_FactoryTest extends Horde_Kolab_Server_Scenario { + public function setUp() + { + $this->markTestIncomplete('Needs to be fixed'); + } + public function testMethodSetupHasPostconditionThatAObjectHandlerOfTypeBaseIsBoundToObjects() { $injector = new Horde_Injector(new Horde_Injector_TopLevel()); diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/FilteredTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/FilteredTest.php new file mode 100644 index 000000000..10478b1ca --- /dev/null +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/FilteredTest.php @@ -0,0 +1,125 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Require our basic test case definition + */ +require_once dirname(__FILE__) . '/../LdapBase.php'; + +/** + * Test the filtered LDAP driver. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Server_FilteredTest extends Horde_Kolab_Server_LdapBase +{ + public function setUp() + { + parent::setUp(); + + $this->ldap_read = $this->getMock('Net_LDAP2'); + $this->ldap_write = $this->getMock('Net_LDAP2'); + $connection = new Horde_Kolab_Server_Connection_Splittedldap( + $this->ldap_read, + $this->ldap_write + ); + + $this->server = new Horde_Kolab_Server_Ldap_Filtered( + $connection, + 'base', + 'filter' + ); + } + + private function getSearchResultMock() + { + $result = $this->getMock( + 'Net_LDAP2_Search', array('as_struct', 'count'), array(), '', false + ); + $result->expects($this->any()) + ->method('as_struct') + ->will($this->returnValue(array(array('dn' => 'test')))); + $result->expects($this->any()) + ->method('count') + ->will($this->returnValue(1)); + return $result; + } + + public function testMethodFindbelowHasParameterQueryelementTheSearchCriteria() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('', '(&(filter)(equals=equals))', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->server->findBelow($equals, ''); + } + + public function testMethodFindbelowHasParameterStringParent() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('parent', '(&(filter)(equals=equals))', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->server->findBelow($equals, 'parent', array()); + } + + public function testMethodFindbelowHasParameterArrayAdditionalParameters() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('', '(&(filter)(equals=equals))', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->server->findBelow($equals, '', array()); + } + + public function testMethodFindbelowReturnsArraySearchResult() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('parent', '(&(filter)(equals=equals))', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->assertEquals( + array(array('dn' => 'test')), + $this->server->findBelow($equals, 'parent')->asArray() + ); + } + + public function testMethodFindbelowThrowsExceptionIfTheSearchFailed() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->will($this->returnValue(new PEAR_Error('Search failed!'))); + try { + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->assertEquals(array('dn' => 'test'), $this->server->findBelow($equals, '')); + $this->fail('No exception!'); + } catch (Exception $e) { + $this->assertEquals('Search failed!', $e->getMessage()); + $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); + } + } + +} diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/LdapTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/LdapTest.php index c4e070ccb..c014d2173 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/LdapTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/LdapTest.php @@ -36,35 +36,77 @@ class Horde_Kolab_Server_Server_LdapTest extends Horde_Kolab_Server_LdapBase { parent::setUp(); - $this->logger = new Horde_Log_Handler_Mock(); + $this->ldap_read = $this->getMock('Net_LDAP2'); + $this->ldap_write = $this->getMock('Net_LDAP2'); + $connection = new Horde_Kolab_Server_Connection_Splittedldap( + $this->ldap_read, + $this->ldap_write + ); - $injector = new Horde_Injector(new Horde_Injector_TopLevel()); - Horde_Kolab_Server_Factory::setup( - array('logger' => new Horde_Log_Logger($this->logger)), $injector + $this->server = new Horde_Kolab_Server_Ldap_Standard( + $connection, + 'base' + ); + } + + private function getSearchResultMock() + { + $result = $this->getMock( + 'Net_LDAP2_Search', array('as_struct', 'count'), array(), '', false ); - $this->server = $injector->getInstance('Horde_Kolab_Server'); + $result->expects($this->any()) + ->method('as_struct') + ->will($this->returnValue(array(array('dn' => 'test')))); + $result->expects($this->any()) + ->method('count') + ->will($this->returnValue(1)); + return $result; } - public function testMethodConnectuidHasPostconditionThatTheUidIsSetIfTheConnectionWasSuccessful() + public function testMethodConnectguidHasStringParameterGuid() { - $ldap = $this->getMock('Net_LDAP2', array('bind')); - $ldap->expects($this->exactly(1)) + $this->server->connectGuid('guid', ''); + } + + public function testMethodConnectguidHasStringParameterPass() + { + $this->server->connectGuid('', 'pass'); + } + + public function testMethodConnectguidHasPostconditionThatTheGuidIsSetIfTheConnectionWasSuccessful() + { + $this->ldap_read->expects($this->exactly(1)) ->method('bind') ->will($this->returnValue(true)); - $this->server->setLdap($ldap); - $this->server->connectUid('test', 'test'); - $this->assertEquals('test', $this->server->uid); + $this->server->connectGuid('test', 'test'); + $this->assertEquals('test', $this->server->getGuid()); } - public function testMethodConnectuidThrowsExceptionIfTheConnectionFailed() + public function testMethodConnectguidDoesNotCallBindAgainIfAlreadyConnectedWithThisGuid() { - $ldap = $this->getMock('Net_LDAP2', array('bind')); - $ldap->expects($this->exactly(1)) + $this->ldap_read->expects($this->exactly(1)) ->method('bind') - ->will($this->returnValue(PEAR::raiseError('Bind failed!'))); - $this->server->setLdap($ldap); + ->will($this->returnValue(true)); + $this->server->connectGuid('test', 'test'); + $this->server->connectGuid('test', 'test'); + } + + public function testMethodConnectguidDoesNotCallBindAgainIfAlreadyConnectedWithThisGuidEvenIfTheGuidIsEmpty() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('bind') + ->will($this->returnValue(true)); + $this->server->connectGuid('', ''); + $this->server->connectGuid('', ''); + } + + public function testMethodConnectguidThrowsExceptionIfTheConnectionFailed() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('bind') + ->will($this->returnValue(new PEAR_Error('Bind failed!'))); try { - $this->server->connectUid('test', 'test'); + $this->server->connectGuid('test', 'test'); $this->fail('No exception!'); } catch (Exception $e) { $this->assertEquals('Bind failed!', $e->getMessage()); @@ -72,79 +114,96 @@ class Horde_Kolab_Server_Server_LdapTest extends Horde_Kolab_Server_LdapBase } } - public function testMethodSearchHasPostconditionThatItIsPossibleToTestTheLastResultForAnExceededSearchSizeLimit() + public function testMethodGetguidHasResultBooleanFalseIfNotConnected() { - $ldap = $this->getMock('Net_LDAP2', array('search')); - $ldap->expects($this->exactly(1)) - ->method('search') - ->will($this->returnValue(new Search_Mock(array(array('dn' => 'test')), true))); - $this->server->setLdap($ldap); - $this->server->search('filter'); - $this->assertTrue($this->server->sizeLimitExceeded()); + $this->assertSame(false, $this->server->getGuid()); } - public function testMethodSearchReturnsArraySearchResult() + public function testMethodGetguidHasResultStringGuidIfNotConnected() { - $ldap = $this->getMock('Net_LDAP2', array('search')); - $ldap->expects($this->exactly(1)) + $this->server->connectGuid('guid', ''); + $this->assertEquals('guid', $this->server->getGuid()); + } + + public function testMethodReadHasParameterStringGuid() + { + $this->ldap_read->expects($this->exactly(1)) ->method('search') - ->will($this->returnValue(new Search_Mock(array(array('dn' => 'test'))))); - $this->server->setLdap($ldap); - $this->assertEquals(array(array('dn' => 'test')), $this->server->search('filter')); + ->with('test', null, array('scope' => 'base')) + ->will($this->returnValue($this->getSearchResultMock())); + $this->server->read('test'); } - public function testMethodSearchReturnsArrayMappedSearchResultIfMappingIsActivated() + public function testMethodReadReturnsArrayReadResult() { - $ldap = $this->getMock('Net_LDAP2', array('search')); - $ldap->expects($this->exactly(1)) + $this->ldap_read->expects($this->exactly(1)) ->method('search') - ->will($this->returnValue(new Search_Mock(array(array('dn2' => 'test'))))); - $this->server->setLdap($ldap); - $this->server->setParams(array('map' => array('dn' => 'dn2'))); - $this->assertEquals( - array(array('dn' => 'test')), - $this->server->search( - 'filter', - array('attributes' => array('dn')) - ) - ); + ->with('test', null, array('scope' => 'base')) + ->will($this->returnValue($this->getSearchResultMock())); + $this->assertEquals(array('dn' => 'test'), $this->server->read('test')); } - public function testMethodSearchThrowsExceptionIfTheSearchFailed() + public function testMethodReadThrowsExceptionIfTheObjectWasNotFound() { - $ldap = $this->getMock('Net_LDAP2', array('search')); - $ldap->expects($this->exactly(1)) + $result = $this->getMock( + 'Net_LDAP2_Search', array('as_struct', 'count'), array(), '', false + ); + $result->expects($this->exactly(1)) + ->method('count') + ->will($this->returnValue(0)); + $this->ldap_read->expects($this->exactly(1)) ->method('search') - ->will($this->returnValue(PEAR::raiseError('Search failed!'))); - $this->server->setLdap($ldap); + ->will($this->returnValue($result)); try { - $this->assertEquals(array('dn' => 'test'), $this->server->search('filter')); + $this->assertEquals(array(), $this->server->read('test')); $this->fail('No exception!'); } catch (Exception $e) { - $this->assertEquals('Search failed!', $e->getMessage()); - $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); + $this->assertEquals('Empty result!', $e->getMessage()); + $this->assertEquals(Horde_Kolab_Server_Exception::EMPTY_RESULT, $e->getCode()); } } - public function testMethodReadReturnsArrayReadResult() + public function testMethodReadAttributesHasParameterStringGuid() { - $ldap = $this->getMock('Net_LDAP2', array('search')); - $ldap->expects($this->exactly(1)) + $this->ldap_read->expects($this->exactly(1)) ->method('search') - ->will($this->returnValue(new Search_Mock(array(array('dn' => 'test'))))); - $this->server->setLdap($ldap); - $this->assertEquals(array('dn' => 'test'), $this->server->read('test')); + ->with('guid', null, array('scope' => 'base', 'attributes' => array())) + ->will($this->returnValue($this->getSearchResultMock())); + $this->server->readAttributes('guid', array()); } - public function testMethodReadThrowsExceptionIfTheObjectWasNotFound() + public function testMethodReadAttributesHasParameterArrayAttributes() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('', null, array('scope' => 'base', 'attributes' => array('a'))) + ->will($this->returnValue($this->getSearchResultMock())); + $this->server->readAttributes('', array('a')); + } + + public function testMethodReadAttributesReturnsArrayReadResult() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('test', null, array('scope' => 'base', 'attributes' => array('a'))) + ->will($this->returnValue($this->getSearchResultMock())); + $this->assertEquals(array('dn' => 'test'), $this->server->readAttributes('test', array('a'))); + } + + public function testMethodReadAttributesThrowsExceptionIfTheObjectWasNotFound() { - $ldap = $this->getMock('Net_LDAP2', array('search')); - $ldap->expects($this->exactly(1)) + $result = $this->getMock( + 'Net_LDAP2_Search', array('as_struct', 'count'), array(), '', false + ); + $result->expects($this->exactly(1)) + ->method('count') + ->will($this->returnValue(0)); + $this->ldap_read->expects($this->exactly(1)) ->method('search') - ->will($this->returnValue(new Search_Mock(array()))); - $this->server->setLdap($ldap); + ->with('test', null, array('scope' => 'base', 'attributes' => array('a'))) + ->will($this->returnValue($result)); try { - $this->assertEquals(array(), $this->server->read('test', array('dn'))); + $this->assertEquals(array(), $this->server->readAttributes('test', array('a'))); $this->fail('No exception!'); } catch (Exception $e) { $this->assertEquals('Empty result!', $e->getMessage()); @@ -152,39 +211,177 @@ class Horde_Kolab_Server_Server_LdapTest extends Horde_Kolab_Server_LdapBase } } - public function testMethodSaveHasPostconditionThatTheEntryWasSaved() + public function testMethodFindHasParameterQueryelementTheSearchCriteria() { - $ldap = $this->getMock('Net_LDAP2', array('add')); - $ldap->expects($this->exactly(1)) - ->method('add') - ->with(new PHPUnit_Framework_Constraint_IsInstanceOf('Net_LDAP2_Entry')); - $this->server->setLdap($ldap); - $this->server->save('test', array('add' => array('dn' => 'test'))); + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('base', '(equals=equals)', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->server->find($equals); + } + + public function testMethodFindHasParameterArrayAdditionalParameters() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('base', '(equals=equals)', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->server->find($equals, array()); } - public function testMethodSaveThrowsExceptionIfDataToSaveIsNoArray() + public function testMethodFindReturnsArraySearchResult() { - $ldap = $this->getMock('Net_LDAP2', array('add')); - $this->server->setLdap($ldap); + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('base', '(equals=equals)', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->assertEquals( + array(array('dn' => 'test')), + $this->server->find($equals)->asArray() + ); + } + + public function testMethodFindThrowsExceptionIfTheSearchFailed() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->will($this->returnValue(new PEAR_Error('Search failed!'))); try { - $this->server->save('test', array('add' => 'hello')); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->assertEquals(array('dn' => 'test'), $this->server->find($equals)); $this->fail('No exception!'); } catch (Exception $e) { - $this->assertEquals('Unable to create fresh entry: Parameter $attrs needs to be an array!', $e->getMessage()); + $this->assertEquals('Search failed!', $e->getMessage()); $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); } + } + + public function testMethodSaveHasParameterObjectTheObjectToModifyOnTheServer() + { + $entry = $this->getMock( + 'Net_LDAP2_Entry', array(), array(), '', false + ); + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->ldap_write->expects($this->exactly(1)) + ->method('getEntry') + ->will($this->returnValue($entry)); + $this->ldap_write->expects($this->exactly(1)) + ->method('modify') + ->with(new PHPUnit_Framework_Constraint_IsInstanceOf('Net_LDAP2_Entry')); + $object->expects($this->exactly(1)) + ->method('readInternal') + ->will($this->returnValue(array())); + $this->server->save($object, array('attributes' => array('dn'))); + } + + public function testMethodSaveHasParameterArrayData() + { + $entry = $this->getMock( + 'Net_LDAP2_Entry', array(), array(), '', false + ); + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->ldap_write->expects($this->exactly(1)) + ->method('getEntry') + ->will($this->returnValue($entry)); + $this->ldap_write->expects($this->exactly(1)) + ->method('modify') + ->with(new PHPUnit_Framework_Constraint_IsInstanceOf('Net_LDAP2_Entry')); + $object->expects($this->exactly(1)) + ->method('readInternal') + ->will($this->returnValue(array())); + $this->server->save($object, array('dn' => 'test')); + } + public function testMethodSaveHasPostconditionThatTheEntryWasModified() + { + $entry = $this->getMock( + 'Net_LDAP2_Entry', array(), array(), '', false + ); + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->ldap_write->expects($this->exactly(1)) + ->method('getEntry') + ->will($this->returnValue($entry)); + $this->ldap_write->expects($this->exactly(1)) + ->method('modify') + ->with(new PHPUnit_Framework_Constraint_IsInstanceOf('Net_LDAP2_Entry')); + $object->expects($this->exactly(1)) + ->method('readInternal') + ->will($this->returnValue(array())); + $this->server->save($object, array('dn' => 'test')); } public function testMethodSaveThrowsExceptionIfSavingDataFailed() { - $ldap = $this->getMock('Net_LDAP2', array('add')); - $ldap->expects($this->exactly(1)) + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->ldap_write->expects($this->exactly(1)) + ->method('modify') + ->will($this->returnValue(new PEAR_Error('Saving failed!'))); + $object->expects($this->exactly(1)) + ->method('readInternal') + ->will($this->returnValue(array())); + try { + $this->server->save($object, array('dn' => 'test')); + $this->fail('No exception!'); + } catch (Exception $e) { + $this->assertEquals('Saving failed!', $e->getMessage()); + $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); + } + } + + public function testMethodAddHasParameterObjectTheObjectToAddToTheServer() + { + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->ldap_write->expects($this->exactly(1)) + ->method('add') + ->with(new PHPUnit_Framework_Constraint_IsInstanceOf('Net_LDAP2_Entry')); + $this->server->add($object, array('attributes' => array('dn'))); + } + + public function testMethodAddHasParameterArrayData() + { + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->ldap_write->expects($this->exactly(1)) + ->method('add') + ->with(new PHPUnit_Framework_Constraint_IsInstanceOf('Net_LDAP2_Entry')); + $this->server->add($object, array('dn' => 'test')); + } + + public function testMethodAddHasPostconditionThatTheEntryWasModified() + { + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->ldap_write->expects($this->exactly(1)) + ->method('add') + ->with(new PHPUnit_Framework_Constraint_IsInstanceOf('Net_LDAP2_Entry')); + $this->server->add($object, array('dn' => 'test')); + } + + public function testMethodAddThrowsExceptionIfSavingDataFailed() + { + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $this->ldap_write->expects($this->exactly(1)) ->method('add') - ->will($this->returnValue(PEAR::raiseError('Saving failed!'))); - $this->server->setLdap($ldap); + ->will($this->returnValue(new PEAR_Error('Saving failed!'))); try { - $this->server->save('test', array('add' => array('dn' => 'test'))); + $this->server->add($object, array('add' => array('dn' => 'test'))); $this->fail('No exception!'); } catch (Exception $e) { $this->assertEquals('Saving failed!', $e->getMessage()); @@ -192,23 +389,27 @@ class Horde_Kolab_Server_Server_LdapTest extends Horde_Kolab_Server_LdapBase } } + public function testMethodDeleteHasParameterStringGuid() + { + $this->ldap_write->expects($this->exactly(1)) + ->method('delete') + ->with('guid'); + $this->server->delete('guid'); + } + public function testMethodDeleteHasPostconditionThatTheEntryWasDeleted() { - $ldap = $this->getMock('Net_LDAP2', array('delete')); - $ldap->expects($this->exactly(1)) + $this->ldap_write->expects($this->exactly(1)) ->method('delete') ->with('test'); - $this->server->setLdap($ldap); $this->server->delete('test'); } public function testMethodDeleteThrowsExceptionIfDeletingDataFailed() { - $ldap = $this->getMock('Net_LDAP2', array('delete')); - $ldap->expects($this->exactly(1)) + $this->ldap_write->expects($this->exactly(1)) ->method('delete') - ->will($this->returnValue(PEAR::raiseError('Deleting failed!'))); - $this->server->setLdap($ldap); + ->will($this->returnValue(new PEAR_Error('Deleting failed!'))); try { $this->server->delete('test'); $this->fail('No exception!'); @@ -218,68 +419,49 @@ class Horde_Kolab_Server_Server_LdapTest extends Horde_Kolab_Server_LdapBase } } - public function testMethodRenameHasPostconditionThatTheEntryWasRenamed() + public function testMethodRenameHasParameterStringOldGuid() { - $ldap = $this->getMock('Net_LDAP2', array('move')); - $ldap->expects($this->exactly(1)) + $this->ldap_write->expects($this->exactly(1)) ->method('move') - ->with('test', 'new'); - $this->server->setLdap($ldap); - $this->server->rename('test', 'new'); + ->with('oldguid', ''); + $this->server->rename('oldguid', ''); } - public function testMethodRenameThrowsExceptionIfRenamingDataFailed() + public function testMethodRenameHasParameterStringNewGuid() { - $ldap = $this->getMock('Net_LDAP2', array('move')); - $ldap->expects($this->exactly(1)) + $this->ldap_write->expects($this->exactly(1)) ->method('move') - ->will($this->returnValue(PEAR::raiseError('Renaming failed!'))); - $this->server->setLdap($ldap); - try { - $this->server->rename('test', 'new'); - $this->fail('No exception!'); - } catch (Exception $e) { - $this->assertEquals('Renaming failed!', $e->getMessage()); - $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); - } + ->with('', 'newguid'); + $this->server->rename('', 'newguid'); } - public function testMethodGetobjectclassesHasResultArrayWithLowerCaseObjectclassNames() + public function testMethodRenameHasPostconditionThatTheEntryWasRenamed() { - $ldap = $this->getMock('Net_LDAP2', array('search')); - $ldap->expects($this->exactly(1)) - ->method('search') - ->will($this->returnValue(new Search_Mock(array(array(Horde_Kolab_Server_Object::ATTRIBUTE_OC => array('test', 'PERSON', 'Last')))))); - $this->server->setLdap($ldap); - $this->assertEquals( - array('test', 'person', 'last'), - $this->server->getObjectClasses('test') - ); + $this->ldap_write->expects($this->exactly(1)) + ->method('move') + ->with('test', 'new'); + $this->server->rename('test', 'new'); } - public function testMethodGetobjectclassesThrowsExceptionIfTheObjectHasNoAttributeObjectclass() + public function testMethodRenameThrowsExceptionIfRenamingDataFailed() { - $ldap = $this->getMock('Net_LDAP2', array('search')); - $ldap->expects($this->exactly(1)) - ->method('search') - ->will($this->returnValue(new Search_Mock(array(array('dummy' => array('test', 'PERSON', 'Last')))))); - $this->server->setLdap($ldap); + $this->ldap_write->expects($this->exactly(1)) + ->method('move') + ->will($this->returnValue(new PEAR_Error('Renaming failed!'))); try { - $this->server->getObjectClasses('test'); + $this->server->rename('test', 'new'); $this->fail('No exception!'); } catch (Exception $e) { - $this->assertEquals('The object test has no objectClass attribute!', $e->getMessage()); + $this->assertEquals('Renaming failed!', $e->getMessage()); $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); } } public function testMethodGetschemaReturnsArrayWithADescriptionOfAllObjectClasses() { - $ldap = $this->getMock('Net_LDAP2', array('schema')); - $ldap->expects($this->exactly(1)) + $this->ldap_read->expects($this->exactly(1)) ->method('schema') ->will($this->returnValue(array('schema' => 'dummy'))); - $this->server->setLdap($ldap); $this->assertEquals( array('schema' => 'dummy'), $this->server->getSchema() @@ -288,11 +470,9 @@ class Horde_Kolab_Server_Server_LdapTest extends Horde_Kolab_Server_LdapBase public function testMethodGetschemaThrowsExceptionIfTheSchemaRetrievalFailed() { - $ldap = $this->getMock('Net_LDAP2', array('schema')); - $ldap->expects($this->exactly(1)) + $this->ldap_read->expects($this->exactly(1)) ->method('schema') - ->will($this->returnValue(PEAR::raiseError('Schema failed!'))); - $this->server->setLdap($ldap); + ->will($this->returnValue(new PEAR_Error('Schema failed!'))); try { $this->server->getSchema(); $this->fail('No exception!'); @@ -302,62 +482,21 @@ class Horde_Kolab_Server_Server_LdapTest extends Horde_Kolab_Server_LdapBase } } - /** - * Test handling of object classes. - * - * @return NULL - */ -/* public function testGetObjectClasses() */ +/* public function testMethodSearchReturnsArrayMappedSearchResultIfMappingIsActivated() */ /* { */ -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('read')); */ -/* $ldap->expects($this->any()) */ -/* ->method('read') */ -/* ->will($this->returnValue(array ( */ -/* 'objectClass' => */ -/* array ( */ -/* 'count' => 4, */ -/* 0 => 'top', */ -/* 1 => 'inetOrgPerson', */ -/* 2 => 'kolabInetOrgPerson', */ -/* 3 => 'hordePerson', */ -/* ), */ -/* 0 => 'objectClass', */ -/* 'count' => 1))); */ - -/* $classes = $ldap->getObjectClasses('cn=Gunnar Wrobel,dc=example,dc=org'); */ -/* if ($classes instanceOf PEAR_Error) { */ -/* $this->assertEquals('', $classes->getMessage()); */ -/* } */ -/* $this->assertContains('top', $classes); */ -/* $this->assertContains('kolabinetorgperson', $classes); */ -/* $this->assertContains('hordeperson', $classes); */ - -/* $ldap = $this->getMock('Horde_Kolab_Server_ldap', array('read')); */ -/* $ldap->expects($this->any()) */ -/* ->method('read') */ -/* ->will($this->returnValue(PEAR::raiseError('LDAP Error: No such object: cn=DOES NOT EXIST,dc=example,dc=org: No such object'))); */ - -/* $classes = $ldap->getObjectClasses('cn=DOES NOT EXIST,dc=example,dc=org'); */ -/* $this->assertEquals('LDAP Error: No such object: cn=DOES NOT EXIST,dc=example,dc=org: No such object', */ -/* $classes->message); */ +/* $ldap = $this->getMock('Net_LDAP2', array('search')); */ +/* $ldap->expects($this->exactly(1)) */ +/* ->method('search') */ +/* ->will($this->returnValue(new Search_Mock(array(array('dn2' => 'test'))))); */ +/* $this->server->setLdap($ldap); */ +/* $this->server->setParams(array('map' => array('dn' => 'dn2'))); */ +/* $this->assertEquals( */ +/* array(array('dn' => 'test')), */ +/* $this->server->search( */ +/* 'filter', */ +/* array('attributes' => array('dn')) */ +/* ) */ +/* ); */ /* } */ } - - -class Search_Mock -{ - public function __construct($result, $limit = false) - { - $this->result = $result; - $this->limit = $limit; - } - public function as_struct() - { - return $this->result; - } - public function sizeLimitExceeded() - { - return $this->limit; - } -} \ No newline at end of file diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/LoggedTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/LoggedTest.php index 1957bb2a6..470fa723c 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/LoggedTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/LoggedTest.php @@ -71,7 +71,7 @@ class Horde_Kolab_Server_Server_LoggedTest extends Horde_Kolab_Server_LdapBase public function testMethodFindDelegatesToServer() { $query = $this->getMock( - 'Horde_Kolab_Server_Query', array(), array(), '', false + 'Horde_Kolab_Server_Query_Element', array(), array(), '', false ); $this->server->expects($this->exactly(1)) ->method('find') @@ -82,7 +82,7 @@ class Horde_Kolab_Server_Server_LoggedTest extends Horde_Kolab_Server_LdapBase public function testMethodFindbelowDelegatesToServer() { $query = $this->getMock( - 'Horde_Kolab_Server_Query', array(), array(), '', false + 'Horde_Kolab_Server_Query_Element', array(), array(), '', false ); $this->server->expects($this->exactly(1)) ->method('findBelow') @@ -92,18 +92,24 @@ class Horde_Kolab_Server_Server_LoggedTest extends Horde_Kolab_Server_LdapBase public function testMethodSaveDelegatesToServer() { + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); $this->server->expects($this->exactly(1)) ->method('save') - ->with('a', array('a' => 'a')); - $this->logged->save('a', array('a' => 'a')); + ->with($object, array('a' => 'a')); + $this->logged->save($object, array('a' => 'a')); } public function testMethodAddDelegatesToServer() { + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); $this->server->expects($this->exactly(1)) ->method('add') - ->with('a', array('a' => 'a')); - $this->logged->add('a', array('a' => 'a')); + ->with($object, array('a' => 'a')); + $this->logged->add($object, array('a' => 'a')); } public function testMethodDeleteDelegatesToServer() @@ -131,7 +137,13 @@ class Horde_Kolab_Server_Server_LoggedTest extends Horde_Kolab_Server_LdapBase public function testMethodSaveHasPostconditionThatTheEventWasLogged() { - $this->logged->save('a', array('a' => 'a')); + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $object->expects($this->once()) + ->method('getGuid') + ->will($this->returnValue('a')); + $this->logged->save($object, array('a' => 'a')); $this->assertEquals( $this->logger->events[0]['message'], 'The object "a" has been successfully saved!' @@ -140,7 +152,13 @@ class Horde_Kolab_Server_Server_LoggedTest extends Horde_Kolab_Server_LdapBase public function testMethodAddHasPostconditionThatTheEventWasLogged() { - $this->logged->add('a', array('a' => 'a')); + $object = $this->getMock( + 'Horde_Kolab_Server_Object', array(), array(), '', false + ); + $object->expects($this->once()) + ->method('getGuid') + ->will($this->returnValue('a')); + $this->logged->add($object, array('a' => 'a')); $this->assertEquals( $this->logger->events[0]['message'], 'The object "a" has been successfully added!' diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/TestTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/MockTest.php similarity index 99% rename from framework/Kolab_Server/test/Horde/Kolab/Server/Server/TestTest.php rename to framework/Kolab_Server/test/Horde/Kolab/Server/Server/MockTest.php index 312352671..78bb162e6 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/TestTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/MockTest.php @@ -30,7 +30,7 @@ require_once dirname(__FILE__) . '/../Autoload.php'; * @license http://www.fsf.org/copyleft/lgpl.html LGPL * @link http://pear.horde.org/index.php?package=Kolab_Server */ -class Horde_Kolab_Server_Server_TestTest extends Horde_Kolab_Server_Scenario +class Horde_Kolab_Server_Server_MockTest extends Horde_Kolab_Server_Scenario { /** The file based mock environment */ @@ -81,6 +81,8 @@ class Horde_Kolab_Server_Server_TestTest extends Horde_Kolab_Server_Scenario { parent::setUp(); + $this->markTestIncomplete('Needs to be fixed'); + $this->initializeEnvironments(); $this->servers = $this->getKolabServers(); foreach ($this->servers as $server) { diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/ServerTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/ServerTest.php index b879a14fc..ee7c12aa6 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/ServerTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/ServerTest.php @@ -1,4 +1,3 @@ - markTestIncomplete('Needs to be fixed'); + } + /** * Provide a mock server. * @@ -126,204 +130,3 @@ class Horde_Kolab_Server_Server_ServerTest extends PHPUnit_Framework_TestCase } } - -/** - * A dummy class to test the original abstract class. - * - * Copyright 2008-2009 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_Server - * @author Gunnar Wrobel - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ -class Horde_Kolab_Server_None extends Horde_Kolab_Server -{ - /** - * Stub for reading object data. - * - * @param string $uid The object to retrieve. - * @param string $attrs Restrict to these attributes. - * - * @return array|PEAR_Error An array of attributes. - */ - public function read($uid, $attrs = null) - { - return false; - } - - /** - * Stub for saving object data. - * - * @param string $uid The object to retrieve. - * @param string $attrs Restrict to these attributes. - * - * @return array|PEAR_Error An array of attributes. - */ - public function save($uid, $data, $exists = false) - { - throw new Horde_Kolab_Server_Exception('Not implemented!'); - } - - /** - * Stub for deleting an object. - * - * @param string $uid The UID of the object to be deleted. - * - * @return boolean True if saving succeeded. - * - * @throws Horde_Kolab_Server_Exception - */ - public function delete($uid) - { - throw new Horde_Kolab_Server_Exception('Not implemented!'); - } - - /** - * Stub for renaming an object. - * - * @param string $uid The UID of the object to be renamed. - * @param string $new The new UID of the object. - * - * @return boolean True if renaming succeeded. - * - * @throws Horde_Kolab_Server_Exception - */ - public function rename($uid, $new) - { - throw new Horde_Kolab_Server_Exception('Not implemented!'); - } - - /** - * Determine the type of a Kolab object. - * - * @param string $uid The UID of the object to examine. - * - * @return string The corresponding Kolab object type. - */ - public function determineType($uid) - { - return 'Horde_Kolab_Server_Object_Kolab_User'; - } - - /** - * List all objects of a specific type - * - * @param string $type The type of the objects to be listed - * @param array $params Additional parameters. - * - * @return array|PEAR_Error An array of Kolab objects. - */ - public function listObjects($type, $params = null) - { - return array(); - } - - /** - * Generates a UID for the given information. - * - * @param string $type The type of the object to create. - * @param string $id The id of the object. - * @param array $info Any additional information about the object to create. - * - * @return string|PEAR_Error The UID. - */ - public function generateServerUid($type, $id, $info) - { - return $id; - } - - /** - * Return the root of the UID values on this server. - * - * @return string The base UID on this server (base DN on ldap). - */ - public function getBaseUid() - { - return ''; - } - - /** - * Identify the UID for the first object found using the specified - * search criteria. - * - * @param array $criteria The search parameters as array. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result restriction. - * - * @return boolean|string|array The UID(s) or false if there was no result. - * - * @throws Horde_Kolab_Server_Exception - */ - public function uidForSearch($criteria, - $restrict = Horde_Kolab_Server::RESULT_SINGLE) - { - /* In the default class we just return false */ - return false; - } - - /** - * Identify the GID for the first group found using the specified - * search criteria - * - * @param array $criteria The search parameters as array. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result restriction. - * - * @return boolean|string|array The GID(s) or false if there was no result. - * - * @throws Horde_Kolab_Server_Exception - */ - public function gidForSearch($criteria, - $restrict = Horde_Kolab_Server::RESULT_SINGLE) - { - /* In the default class we just return false */ - return false; - } - - /** - * Identify attributes for the objects found using a filter. - * - * @param array $criteria The search parameters as array. - * @param array $attrs The attributes to retrieve. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result restriction. - * - * @return array The results. - * - * @throws Horde_Kolab_Server_Exception - */ - public function attrsForSearch($criteria, $attrs, - $restrict = Horde_Kolab_Server::RESULT_SINGLE) - { - /* In the default class we just return an empty array */ - return array(); - } - - /** - * Find object data matching a given set of criteria. - * - * @param array $criteria The criteria for the search. - * @param string $params Additional search parameters. - * - * @return array The result array. - * - * @throws Horde_Kolab_Server_Exception - */ - public function find($criteria, $params = array()) - { - /* In the default class we just return an empty array */ - return array(); - } - - /** - * Returns the set of objects supported by this server. - * - * @return array An array of supported objects. - */ - public function getSupportedObjects() - { - return array('Horde_Kolab_Server_Object'); - } -} diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Server/StandardTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/StandardTest.php new file mode 100644 index 000000000..b5486ef3a --- /dev/null +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Server/StandardTest.php @@ -0,0 +1,124 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Require our basic test case definition + */ +require_once dirname(__FILE__) . '/../LdapBase.php'; + +/** + * Test the standard LDAP driver. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Server_StandardTest extends Horde_Kolab_Server_LdapBase +{ + public function setUp() + { + parent::setUp(); + + $this->ldap_read = $this->getMock('Net_LDAP2'); + $this->ldap_write = $this->getMock('Net_LDAP2'); + $connection = new Horde_Kolab_Server_Connection_Splittedldap( + $this->ldap_read, + $this->ldap_write + ); + + $this->server = new Horde_Kolab_Server_Ldap_Standard( + $connection, + 'base' + ); + } + + private function getSearchResultMock() + { + $result = $this->getMock( + 'Net_LDAP2_Search', array('as_struct', 'count'), array(), '', false + ); + $result->expects($this->any()) + ->method('as_struct') + ->will($this->returnValue(array(array('dn' => 'test')))); + $result->expects($this->any()) + ->method('count') + ->will($this->returnValue(1)); + return $result; + } + + public function testMethodFindbelowHasParameterQueryelementTheSearchCriteria() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('', '(equals=equals)', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->server->findBelow($equals, ''); + } + + public function testMethodFindbelowHasParameterStringParent() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('parent', '(equals=equals)', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->server->findBelow($equals, 'parent', array()); + } + + public function testMethodFindbelowHasParameterArrayAdditionalParameters() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('', '(equals=equals)', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->server->findBelow($equals, '', array()); + } + + public function testMethodFindbelowReturnsArraySearchResult() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->with('parent', '(equals=equals)', array()) + ->will($this->returnValue($this->getSearchResultMock())); + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->assertEquals( + array(array('dn' => 'test')), + $this->server->findBelow($equals, 'parent')->asArray() + ); + } + + public function testMethodFindbelowThrowsExceptionIfTheSearchFailed() + { + $this->ldap_read->expects($this->exactly(1)) + ->method('search') + ->will($this->returnValue(new PEAR_Error('Search failed!'))); + try { + $equals = new Horde_Kolab_Server_Query_Element_Equals('equals', 'equals'); + $this->assertEquals(array('dn' => 'test'), $this->server->findBelow($equals, '')); + $this->fail('No exception!'); + } catch (Exception $e) { + $this->assertEquals('Search failed!', $e->getMessage()); + $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); + } + } + +} diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/ServerTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/ServerTest.php deleted file mode 100644 index 6a807ccab..000000000 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/ServerTest.php +++ /dev/null @@ -1,328 +0,0 @@ - - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ - -/** - * Prepare the test setup. - */ -require_once 'Autoload.php'; - -/** - * Tests for the main server class. - * - * Copyright 2008-2009 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_Server - * @author Gunnar Wrobel - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ -class Horde_Kolab_Server_ServerTest extends PHPUnit_Framework_TestCase -{ - /** - * Provide a mock server. - * - * @return Horde_Kolab_Server The mock server. - */ - protected function getMockServer() - { - $injector = new Horde_Injector(new Horde_Injector_TopLevel()); - $config = new stdClass; - $config->driver = 'none'; - $injector->setInstance('Horde_Kolab_Server_Config', $config); - $injector->bindFactory('Horde_Kolab_Server_Structure', - 'Horde_Kolab_Server_Factory', - 'getStructure'); - $injector->bindFactory('Horde_Kolab_Server', - 'Horde_Kolab_Server_Factory', - 'getServer'); - return $injector->getInstance('Horde_Kolab_Server'); - } - - /** - * The generating a uid for an object. - * - * @return NULL - */ - public function testGenerateUid() - { - $ks = $this->getMockServer(); - $user = new Horde_Kolab_Server_Object($ks, null, null); - $this->assertEquals(preg_replace('/[0-9a-f]*/', '', $user->get(Horde_Kolab_Server_Object::ATTRIBUTE_UID)), ''); - } - - /** - * Test creating the server object. - * - * @return NULL - */ - public function testCreation() - { - try { - $injector = new Horde_Injector(new Horde_Injector_TopLevel()); - $config = new stdClass; - $config->driver = 'dummy'; - $injector->setInstance('Horde_Kolab_Server_Config', $config); - $injector->bindFactory('Horde_Kolab_Server_Structure', - 'Horde_Kolab_Server_Factory', - 'getStructure'); - $injector->bindFactory('Horde_Kolab_Server', - 'Horde_Kolab_Server_Factory', - 'getServer'); - Horde_Kolab_Server_Factory::getServer($injector); - $this->assertFail('No error!'); - } catch (Horde_Kolab_Server_Exception $e) { - $this->assertEquals('Server type definition "Horde_Kolab_Server_Dummy" missing.', - $e->getMessage()); - } - } - - /** - * The base class provides no abilities for reading data. So it - * should mainly return error. But it should be capable of - * returning a dummy Kolab user object. - * - * @return NULL - */ - public function testFetch() - { - $ks = $this->getMockServer(); - $user = $ks->fetch('test'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolab_User', get_class($user)); - - $ks = $this->getMockServer(); - $user = $ks->fetch(); - $this->assertEquals('Horde_Kolab_Server_Object_Kolab_User', get_class($user)); - } - - /** - * Test listing objects. - * - * @return NULL - */ - public function testList() - { - $ks = $this->getMockServer(); - $hash = $ks->listHash('Horde_Kolab_Server_Object'); - $this->assertEquals($hash, array()); - - $ks = $this->getMockServer(); - $hash = $ks->listHash('Horde_Kolab_Server_Object'); - $this->assertEquals($hash, array()); - } - -} - -/** - * A dummy class to test the original abstract class. - * - * Copyright 2008-2009 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_Server - * @author Gunnar Wrobel - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ -class Horde_Kolab_Server_None extends Horde_Kolab_Server -{ - /** - * Stub for reading object data. - * - * @param string $uid The object to retrieve. - * @param string $attrs Restrict to these attributes. - * - * @return array|PEAR_Error An array of attributes. - */ - public function read($uid, $attrs = null) - { - return false; - } - - /** - * Stub for saving object data. - * - * @param string $uid The object to retrieve. - * @param string $attrs Restrict to these attributes. - * - * @return array|PEAR_Error An array of attributes. - */ - public function save($uid, $data, $exists = false) - { - throw new Horde_Kolab_Server_Exception('Not implemented!'); - } - - /** - * Stub for deleting an object. - * - * @param string $uid The UID of the object to be deleted. - * - * @return boolean True if saving succeeded. - * - * @throws Horde_Kolab_Server_Exception - */ - public function delete($uid) - { - throw new Horde_Kolab_Server_Exception('Not implemented!'); - } - - /** - * Stub for renaming an object. - * - * @param string $uid The UID of the object to be renamed. - * @param string $new The new UID of the object. - * - * @return boolean True if renaming succeeded. - * - * @throws Horde_Kolab_Server_Exception - */ - public function rename($uid, $new) - { - throw new Horde_Kolab_Server_Exception('Not implemented!'); - } - - /** - * Determine the type of a Kolab object. - * - * @param string $uid The UID of the object to examine. - * - * @return string The corresponding Kolab object type. - */ - public function determineType($uid) - { - return 'Horde_Kolab_Server_Object_Kolab_User'; - } - - /** - * List all objects of a specific type - * - * @param string $type The type of the objects to be listed - * @param array $params Additional parameters. - * - * @return array|PEAR_Error An array of Kolab objects. - */ - public function listObjects($type, $params = null) - { - return array(); - } - - /** - * Generates a UID for the given information. - * - * @param string $type The type of the object to create. - * @param string $id The id of the object. - * @param array $info Any additional information about the object to create. - * - * @return string|PEAR_Error The UID. - */ - public function generateServerUid($type, $id, $info) - { - return $id; - } - - /** - * Return the root of the UID values on this server. - * - * @return string The base UID on this server (base DN on ldap). - */ - public function getBaseUid() - { - return ''; - } - - /** - * Identify the UID for the first object found using the specified - * search criteria. - * - * @param array $criteria The search parameters as array. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result restriction. - * - * @return boolean|string|array The UID(s) or false if there was no result. - * - * @throws Horde_Kolab_Server_Exception - */ - public function uidForSearch($criteria, - $restrict = Horde_Kolab_Server::RESULT_SINGLE) - { - /* In the default class we just return false */ - return false; - } - - /** - * Identify the GID for the first group found using the specified - * search criteria - * - * @param array $criteria The search parameters as array. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result restriction. - * - * @return boolean|string|array The GID(s) or false if there was no result. - * - * @throws Horde_Kolab_Server_Exception - */ - public function gidForSearch($criteria, - $restrict = Horde_Kolab_Server::RESULT_SINGLE) - { - /* In the default class we just return false */ - return false; - } - - /** - * Identify attributes for the objects found using a filter. - * - * @param array $criteria The search parameters as array. - * @param array $attrs The attributes to retrieve. - * @param int $restrict A Horde_Kolab_Server::RESULT_* result restriction. - * - * @return array The results. - * - * @throws Horde_Kolab_Server_Exception - */ - public function attrsForSearch($criteria, $attrs, - $restrict = Horde_Kolab_Server::RESULT_SINGLE) - { - /* In the default class we just return an empty array */ - return array(); - } - - /** - * Find object data matching a given set of criteria. - * - * @param array $criteria The criteria for the search. - * @param string $params Additional search parameters. - * - * @return array The result array. - * - * @throws Horde_Kolab_Server_Exception - */ - public function find($criteria, $params = array()) - { - /* In the default class we just return an empty array */ - return array(); - } - - /** - * Returns the set of objects supported by this server. - * - * @return array An array of supported objects. - */ - public function getSupportedObjects() - { - return array('Horde_Kolab_Server_Object'); - } -} diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Structure/KolabTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Structure/KolabTest.php new file mode 100644 index 000000000..fa72c920a --- /dev/null +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Structure/KolabTest.php @@ -0,0 +1,349 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Require our basic test case definition + */ +require_once dirname(__FILE__) . '/../LdapBase.php'; + +/** + * Test the LDAP backend. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Structure_KolabTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { + $this->markTestIncomplete('Needs to be fixed'); + + $server = $this->getMock('Horde_Kolab_Server'); + $this->composite = new Horde_Kolab_Server_Composite( + $server, + $this->getMock('Horde_Kolab_Server_Objects'), + new Horde_Kolab_Server_Structure_Kolab(), + $this->getMock('Horde_Kolab_Server_Search'), + $this->getMock('Horde_Kolab_Server_Schema') + ); + } + + public function testMethodGetsupportedobjectsHasResultArrayTheObjectTypesSupportedByThisStructure() + { + $this->assertType('array', $this->composite->structure->getSupportedObjects()); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid1() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array('objectClass' => array('kolabGroupOfNames')))); + $this->assertEquals('Horde_Kolab_Server_Object_Kolabgroupofnames', $this->composite->structure->determineType('guid')); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid2() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array('objectClass' => array('kolabExternalPop3Account')))); + $this->assertEquals('Horde_Kolab_Server_Object_Kolabpop3account', $this->composite->structure->determineType('guid')); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid3() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array('objectClass' => array('kolabSharedFolder')))); + $this->assertEquals('Horde_Kolab_Server_Object_Kolabsharedfolder', $this->composite->structure->determineType('guid')); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid4() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array('objectClass' => array('top')))); + $this->assertEquals('Horde_Kolab_Server_Object', $this->composite->structure->determineType('guid')); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid5() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will( + $this->returnValue( + array( + 'objectClass' => + array( + 'kolabinetorgperson', + ) + ) + ) + ); + $this->composite->search->expects($this->exactly(1)) + ->method('__call') + ->with('getGroups', array('guid')) + ->will( + $this->returnValue( + array( + ) + ) + ); + $this->assertEquals( + 'Horde_Kolab_Server_Object_Kolab_User', + $this->composite->structure->determineType('guid') + ); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid6() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will( + $this->returnValue( + array( + 'objectClass' => + array( + 'kolabinetorgperson', + ) + ) + ) + ); + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->composite->search->expects($this->exactly(1)) + ->method('__call') + ->with('getGroups', array('guid')) + ->will( + $this->returnValue( + array( + 'cn=admin,cn=internal,base' + ) + ) + ); + $this->assertEquals( + 'Horde_Kolab_Server_Object_Kolab_Administrator', + $this->composite->structure->determineType('guid') + ); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid7() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will( + $this->returnValue( + array( + 'objectClass' => + array( + 'kolabinetorgperson', + ) + ) + ) + ); + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->composite->search->expects($this->exactly(1)) + ->method('__call') + ->with('getGroups', array('guid')) + ->will( + $this->returnValue( + array( + 'cn=maintainer,cn=internal,base' + ) + ) + ); + $this->assertEquals( + 'Horde_Kolab_Server_Object_Kolab_Maintainer', + $this->composite->structure->determineType('guid') + ); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid8() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will( + $this->returnValue( + array( + 'objectClass' => + array( + 'kolabinetorgperson', + ) + ) + ) + ); + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->composite->search->expects($this->exactly(1)) + ->method('__call') + ->with('getGroups', array('guid')) + ->will( + $this->returnValue( + array( + 'cn=domain-maintainer,cn=internal,base' + ) + ) + ); + $this->assertEquals( + 'Horde_Kolab_Server_Object_Kolab_Domainmaintainer', + $this->composite->structure->determineType('guid') + ); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid9() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid,cn=external') + ->will( + $this->returnValue( + array( + 'objectClass' => + array( + 'kolabinetorgperson', + ) + ) + ) + ); + $this->composite->search->expects($this->exactly(1)) + ->method('__call') + ->with('getGroups', array('guid,cn=external')) + ->will( + $this->returnValue( + array( + 'unknown' + ) + ) + ); + $this->assertEquals( + 'Horde_Kolab_Server_Object_Kolab_Address', + $this->composite->structure->determineType('guid,cn=external') + ); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid1() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals('id,base', $this->composite->structure->generateServerGuid('Horde_Kolab_Server_Object_Kolabgroupofnames', 'id', array())); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid2() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals('id,cn=internal,base', $this->composite->structure->generateServerGuid('Horde_Kolab_Server_Object_Kolabgroupofnames', 'id', array('visible' => false))); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid3() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals('id,base', $this->composite->structure->generateServerGuid('Horde_Kolab_Server_Object_Kolabsharedfolder', 'id', array('visible' => false))); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid4() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals('id,cn=external,base', $this->composite->structure->generateServerGuid('Horde_Kolab_Server_Object_Kolab_Address', 'id', array())); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid5() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals( + 'id,cn=internal,base', + $this->composite->structure->generateServerGuid( + 'Horde_Kolab_Server_Object_Kolab_User', 'id', + array('user_type' => Horde_Kolab_Server_Object_Kolab_User::USERTYPE_INTERNAL) + ) + ); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid6() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals( + 'id,cn=groups,base', + $this->composite->structure->generateServerGuid( + 'Horde_Kolab_Server_Object_Kolab_User', 'id', + array('user_type' => Horde_Kolab_Server_Object_Kolab_User::USERTYPE_GROUP) + ) + ); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid7() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals( + 'id,cn=resources,base', + $this->composite->structure->generateServerGuid( + 'Horde_Kolab_Server_Object_Kolab_User', 'id', + array('user_type' => Horde_Kolab_Server_Object_Kolab_User::USERTYPE_RESOURCE) + ) + ); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid8() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals('id,base', $this->composite->structure->generateServerGuid('Horde_Kolab_Server_Object_Kolab_User', 'id', array())); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid9() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals( + 'id,base', + $this->composite->structure->generateServerGuid( + 'Horde_Kolab_Server_Object_Kolab_User', 'id', + array('user_type' => 'undefined') + ) + ); + } + +} diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/Structure/LdapTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/Structure/LdapTest.php new file mode 100644 index 000000000..7c9630e40 --- /dev/null +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/Structure/LdapTest.php @@ -0,0 +1,140 @@ + + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ + +/** + * Require our basic test case definition + */ +require_once dirname(__FILE__) . '/../LdapBase.php'; + +/** + * Test the LDAP backend. + * + * Copyright 2008-2009 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_Server + * @author Gunnar Wrobel + * @license http://www.fsf.org/copyleft/lgpl.html LGPL + * @link http://pear.horde.org/index.php?package=Kolab_Server + */ +class Horde_Kolab_Server_Structure_LdapTest extends PHPUnit_Framework_TestCase +{ + public function setUp() + { + $this->markTestIncomplete('Needs to be fixed'); + + $server = $this->getMock('Horde_Kolab_Server'); + $this->composite = new Horde_Kolab_Server_Composite( + $server, + $this->getMock('Horde_Kolab_Server_Objects'), + new Horde_Kolab_Server_Structure_Ldap(), + $this->getMock('Horde_Kolab_Server_Search'), + $this->getMock('Horde_Kolab_Server_Schema') + ); + } + + public function testMethodGetsupportedobjectsHasResultArrayTheObjectTypesSupportedByThisStructure() + { + $this->assertEquals(array('Horde_Kolab_Server_Object'), $this->composite->structure->getSupportedObjects()); + } + + public function testMethodDeterminetypeHasParameterStringGuid() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array('objectClass' => array('TOP')))); + $this->composite->structure->determineType('guid'); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array('objectClass' => array('TOP')))); + $this->assertEquals('Horde_Kolab_Server_Object', $this->composite->structure->determineType('guid')); + } + + public function testMethodDeterminetypeHasResultStringTheObjectclassOfTheGivenGuid2() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array('objectClass' => array('person')))); + $this->assertEquals('Horde_Kolab_Server_Object_Person', $this->composite->structure->determineType('guid')); + } + + public function testMethodDeterminetypeThrowsExceptionIfTheGuidHasNoAttributeObjectclass() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array())); + try { + $this->composite->structure->determineType('guid'); + } catch (Exception $e) { + $this->assertEquals('The object guid has no objectClass attribute!', $e->getMessage()); + $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); + } + } + + public function testMethodDeterminetypeThrowsExceptionIfTheTypeIsUnknown() + { + $this->composite->server->expects($this->exactly(1)) + ->method('read') + ->with('guid') + ->will($this->returnValue(array('objectClass' => array('UNKNOWN')))); + try { + $this->composite->structure->determineType('guid'); + } catch (Exception $e) { + $this->assertEquals('Unknown object type for GUID guid.', $e->getMessage()); + $this->assertEquals(Horde_Kolab_Server_Exception::SYSTEM, $e->getCode()); + } + } + + public function testMethodGenerateserverguidHasParameterStringType() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->composite->structure->generateServerGuid('type', '', array()); + } + + public function testMethodGenerateserverguidHasParameterStringId() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->composite->structure->generateServerGuid('', 'id', array()); + } + + public function testMethodGenerateserverguidHasParameterArrayObjectData() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->composite->structure->generateServerGuid('', '', array('object' => 'data')); + } + + public function testMethodGenerateserverguidHasResultStringTheGuid() + { + $this->composite->server->expects($this->exactly(1)) + ->method('getBaseGuid') + ->will($this->returnValue('base')); + $this->assertEquals('id,base', $this->composite->structure->generateServerGuid('', 'id', array())); + } +} diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/TestTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/TestTest.php deleted file mode 100644 index 8a6353594..000000000 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/TestTest.php +++ /dev/null @@ -1,624 +0,0 @@ - - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ - -/** - * Prepare the test setup. - */ -require_once 'Autoload.php'; - -/** - * Test the test backend. - * - * Copyright 2008-2009 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_Server - * @author Gunnar Wrobel - * @license http://www.fsf.org/copyleft/lgpl.html LGPL - * @link http://pear.horde.org/index.php?package=Kolab_Server - */ -class Horde_Kolab_Server_testTest extends Horde_Kolab_Server_Scenario -{ - - /** The file based mock environment */ - const ENVIRONMENT_FILE = 'file'; - - /** - * The environments we provide to the test. - * - * @var array - */ - protected $_environments = array( - self::ENVIRONMENT_MOCK, - self::ENVIRONMENT_FILE - ); - - /** - * Prepare the server configuration for the given environment. - * - * @param string $environment The name of the environment. - * - * @return NULL - */ - public function prepareKolabServerConfiguration($environment) - { - switch ($environment) { - case self::ENVIRONMENT_FILE: - /** Prepare a Kolab test server */ - $config = new stdClass; - $config->driver = 'file'; - $config->params = array( - 'file' => Horde::getTempFile('fileTest'), - 'basedn' => 'dc=example,dc=org', - 'hashtype' => 'plain' - ); - $this->world['injector'][$environment]->setInstance('Horde_Kolab_Server_Config', $config); - break; - default: - return parent::prepareKolabServerConfiguration($environment); - } - } - - /** - * Set up testing. - * - * @return NULL - */ - protected function setUp() - { - $this->initializeEnvironments(); - $this->servers = $this->getKolabServers(); - foreach ($this->servers as $server) { - $this->addBasicUsersToServer($server); - } - } - - /** - * Test search base. - * - * @return NULL - */ - public function testSearchBase() - { - foreach ($this->servers as $server) { - $result = $server->search( - '(' . Horde_Kolab_Server_Object::ATTRIBUTE_OC - . '=' . Horde_Kolab_Server_Object::OBJECTCLASS_TOP . ')', - array(Horde_Kolab_Server_Object::ATTRIBUTE_OC)); - $this->assertEquals(13, count($result)); - - $result = $server->search( - '(' . Horde_Kolab_Server_Object::ATTRIBUTE_OC - . '=' . Horde_Kolab_Server_Object::OBJECTCLASS_TOP . ')', - array(Horde_Kolab_Server_Object::ATTRIBUTE_OC), - 'cn=internal,dc=example,dc=org'); - $this->assertEquals(4, count($result)); - } - } - - /** - * Test sorting. - * - * @return NULL - */ - public function testSorting() - { - foreach ($this->servers as $server) { - -/* $result = $server->search('(mail=*)', array('mail')); */ -/* $this->assertEquals(5, count($result)); */ -/* $server->sort($result, 'mail'); */ -/* foreach ($result as $object) { */ -/* if (isset($object['data']['dn'])) { */ -/* switch ($object['data']['dn']) { */ -/* case 'cn=Test Address,cn=external,dc=example,dc=org': */ -/* $this->assertContains('address@example.org', $object['data']['mail']); */ -/* break; */ -/* case '': */ -/* $this->assertContains('address@example.org', $object['data']['mail']); */ -/* break; */ -/* } */ -/* } */ -/* } */ - } - } - - /** - * Test listing objects. - * - * @return NULL - */ - public function testListObjects() - { - foreach ($this->servers as $server) { - $filter = '(&(objectClass=kolabInetOrgPerson)(uid=*)(mail=*)(sn=*))'; - $attributes = array( - Horde_Kolab_Server_Object_Kolabinetorgperson::ATTRIBUTE_SN, - Horde_Kolab_Server_Object_Kolabinetorgperson::ATTRIBUTE_CN, - Horde_Kolab_Server_Object_Kolabinetorgperson::ATTRIBUTE_UID, - Horde_Kolab_Server_Object_Kolabinetorgperson::ATTRIBUTE_MAIL, - Horde_Kolab_Server_Object_Kolabinetorgperson::ATTRIBUTE_DELETED, - ); - - $sort = Horde_Kolab_Server_Object_Kolabinetorgperson::ATTRIBUTE_SN; - $result = $server->search($filter); - $this->assertEquals(2, count($result)); - - $result = $server->listObjects('Horde_Kolab_Server_Object_Kolab_User'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolab_User', get_class(array_shift($result))); - - $result = $server->listObjects('Horde_Kolab_Server_Object_Kolabsharedfolder'); - $this->assertEquals(1, count($result)); - $this->assertEquals('Horde_Kolab_Server_Object_Kolabsharedfolder', get_class(array_shift($result))); - } - } - - /** - * Test handling of object classes. - * - * @return NULL - */ - public function testGetObjectClasses() - { - foreach ($this->servers as $server) { - $classes = $server->getObjectClasses('cn=Gunnar Wrobel,dc=example,dc=org'); - $this->assertContains('top', $classes); - $this->assertContains('kolabinetorgperson', $classes); - - try { - $classes = $server->getObjectClasses('cn=DOES NOT EXIST,dc=example,dc=org'); - } catch (Horde_Kolab_Server_Exception $classes) { - } - $this->assertError($classes, - 'No such object: cn=DOES NOT EXIST,dc=example,dc=org'); - - $classes = $server->getObjectClasses('cn=The Administrator,dc=example,dc=org'); - $this->assertContains('kolabinetorgperson', $classes); - } - } - - /** - * Test handling of object types. - * - * @return NULL - */ - public function testDetermineType() - { - foreach ($this->servers as $server) { - $type = $server->determineType('cn=empty.group@example.org,dc=example,dc=org'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolabgroupofnames', $type); - - $type = $server->determineType('cn=shared@example.org,dc=example,dc=org'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolabsharedfolder', $type); - - $type = $server->determineType('cn=The Administrator,dc=example,dc=org'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolab_Administrator', $type); - - $type = $server->determineType('cn=Main Tainer,dc=example,dc=org'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolab_Maintainer', $type); - - $type = $server->determineType('cn=Domain Maintainer,dc=example,dc=org'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolab_Domainmaintainer', $type); - - $type = $server->determineType('cn=Test Address,cn=external,dc=example,dc=org'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolab_Address', $type); - - $type = $server->determineType('cn=Gunnar Wrobel,dc=example,dc=org'); - $this->assertEquals('Horde_Kolab_Server_Object_Kolab_User', $type); - } - } - - /** - * Test retrieving a primary mail for a mail or id. - * - * @return NULL - */ - public function testMailForIdOrMail() - { - foreach ($this->servers as $server) { - $mail = $server->mailForIdOrMail('wrobel'); - $this->assertEquals('wrobel@example.org', $mail); - - $mail = $server->mailForIdOrMail('wrobel@example.org'); - $this->assertEquals('wrobel@example.org', $mail); - - $mail = $server->mailForIdOrMail('DOES NOT EXIST'); - $this->assertSame(false, $mail); - } - } - - /** - * Test retrieving a UID for a mail or id. - * - * @return NULL - */ - public function testUidForIdOrMail() - { - foreach ($this->servers as $server) { - $uid = $server->uidForIdOrMail('wrobel'); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - - $uid = $server->uidForIdOrMail('wrobel@example.org'); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - - $uid = $server->uidForIdOrMail('DOES NOT EXIST'); - $this->assertSame(false, $uid); - } - } - - /** - * Test retrieving a UID for a mail or id. - * - * @return NULL - */ - public function testUidForMailOrIdOrAlias() - { - foreach ($this->servers as $server) { - $uid = $server->uidForIdOrMailOrAlias('g.wrobel@example.org'); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - - $uid = $server->uidForIdOrMailOrAlias('wrobel@example.org'); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - - $uid = $server->uidForIdOrMailOrAlias('wrobel'); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - - $uid = $server->uidForIdOrMailOrAlias('DOES NOT EXIST'); - $this->assertSame(false, $uid); - } - } - - /** - * Test retrieving all addresses for a mail or id. - * - * @return NULL - */ - public function testAddrsForIdOrMail() - { - foreach ($this->servers as $server) { - $addrs = $server->addrsForIdOrMail('wrobel'); - - $testuser = $server->fetch('cn=Test Test,dc=example,dc=org'); - $this->assertContains('wrobel@example.org', - $testuser->get(Horde_Kolab_Server_Object_Kolabinetorgperson::ATTRIBUTE_DELEGATE, false)); - - $this->assertContains('wrobel@example.org', $addrs); - $this->assertContains('test@example.org', $addrs); - $this->assertContains('t.test@example.org', $addrs); - $this->assertContains('g.wrobel@example.org', $addrs); - $this->assertContains('gunnar@example.org', $addrs); - - $addrs = $server->addrsForIdOrMail('test@example.org'); - $this->assertContains('test@example.org', $addrs); - $this->assertContains('t.test@example.org', $addrs); - } - } - - /** - * Test retrieving a UID for a primary mail. - * - * @return NULL - */ - public function testUidForMailAddress() - { - foreach ($this->servers as $server) { - $uid = $server->uidForIdOrMailOrAlias('wrobel@example.org'); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - - $uid = $server->uidForIdOrMailOrAlias('test@example.org'); - $this->assertEquals('cn=Test Test,dc=example,dc=org', $uid); - - $uid = $server->uidForIdOrMailOrAlias('gunnar@example.org'); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - - $uid = $server->uidForIdOrMailOrAlias('wrobel'); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - } - } - - /** - * Test retrieving a UID for an attribute. - * - * @return NULL - */ - public function testUidForAttr() - { - foreach ($this->servers as $server) { - $uid = $server->uidForSearch(array('AND' => array(array('field' => 'alias', - 'op' => '=', - 'test' => 'g.wrobel@example.org')))); - $this->assertEquals('cn=Gunnar Wrobel,dc=example,dc=org', $uid); - } - } - - /** - * Test group membership testing. - * - * @return NULL - */ - public function testMemberOfGroupAddress() - { - foreach ($this->servers as $server) { - $uid = $server->uidForIdOrMailOrAlias('g.wrobel@example.org'); - $member = $server->memberOfGroupAddress($uid, 'group@example.org'); - $this->assertTrue($member); - - $member = $server->memberOfGroupAddress( - $server->uidForIdOrMailOrAlias('test@example.org'), - 'group@example.org'); - $this->assertTrue($member); - - $member = $server->memberOfGroupAddress( - $server->uidForIdOrMailOrAlias('somebody@example.org'), - 'group@example.org'); - $this->assertFalse($member); - } - } - - /** - * Test group fetching. - * - * @return NULL - */ - public function testGetGroups() - { - foreach ($this->servers as $server) { - $filter = '(&(objectClass=kolabGroupOfNames)(member=' - . Horde_LDAP::quote('cn=The Administrator,dc=example,dc=org') . '))'; - $result = $server->search($filter, array()); - $this->assertTrue(!empty($result)); - - /* $entry = $server->_firstEntry($result); */ - /* $this->assertTrue(!empty($entry)); */ - - /* $uid = $server->_getDn($entry); */ - /* $this->assertTrue(!empty($uid)); */ - - /* $entry = $server->_nextEntry($entry); */ - /* $this->assertTrue(empty($entry)); */ - - /* $entries = $server->_getDns($result); */ - /* $this->assertTrue(!empty($entries)); */ - - $groups = $server->getGroups('cn=The Administrator,dc=example,dc=org'); - $this->assertTrue(!empty($groups)); - - $groups = $server->getGroups($server->uidForIdOrMailOrAlias('g.wrobel@example.org')); - $this->assertContains('cn=group@example.org,dc=example,dc=org', $groups); - - $groups = $server->getGroupAddresses($server->uidForIdOrMailOrAlias('g.wrobel@example.org')); - $this->assertContains('group@example.org', $groups); - - $groups = $server->getGroups($server->uidForIdOrMailOrAlias('test@example.org')); - $this->assertContains('cn=group@example.org,dc=example,dc=org', $groups); - - $groups = $server->getGroupAddresses($server->uidForIdOrMailOrAlias('test@example.org')); - $this->assertContains('group@example.org', $groups); - - $groups = $server->getGroups('nobody'); - $this->assertTrue(empty($groups)); - } - } - - /** - * Test parsing of LDAP filters. - * - * @return NULL - */ - public function testFilterParse() - { - $db = $this->getKolabMockServer(); - - $a = $db->parse('(a=b)'); - $this->assertEquals(array('att' => 'a', 'log' => '=', 'val' => 'b'), - $a); - - $a = $db->parse('(&(a=b)(c=d))'); - $this->assertEquals(array('op' => '&', 'sub' => array( - array('att' => 'a', 'log' => '=', 'val' => 'b'), - array('att' => 'c', 'log' => '=', 'val' => 'd'), - )), $a); - - $a = $db->parse('(&(a=1)(|(b=2)(c=3)))'); - $this->assertEquals(array('op' => '&', 'sub' => array( - array('att' => 'a', 'log' => '=', 'val' => '1'), - array('op' => '|', 'sub' => - array( - array('att' => 'b', 'log' => '=', 'val' => '2'), - array('att' => 'c', 'log' => '=', 'val' => '3'), - )))), $a); - - $a = $db->parseSub('(!(x=2))(b=1)'); - $this->assertEquals(array(array('op' => '!', 'sub' => - array( - array('att' => 'x', 'log' => '=', 'val' => '2'), - ) - ), - array('att' => 'b', 'log' => '=', 'val' => '1'), - ), $a); - - $a = $db->parse('(&(!(x=2))(b=1))'); - $this->assertEquals(array('op' => '&', 'sub' => array( - array('op' => '!', 'sub' => - array( - array('att' => 'x', 'log' => '=', 'val' => '2'), - ) - ), - array('att' => 'b', 'log' => '=', 'val' => '1'), - )), $a); - - } - - /** - * Test searching in the simulated LDAP data. - * - * @return NULL - */ - public function testSearch() - { - $injector = new Horde_Injector(new Horde_Injector_TopLevel()); - $config = new stdClass; - $config->driver = 'test'; - $config->params = array( - 'data' => - array( - 'cn=a' => array( - 'dn' => 'cn=a', - 'data' => array( - 'a' => '1', - 'b' => '1', - 'c' => '1', - ) - ), - 'cn=b' => array( - 'dn' => 'cn=b', - 'data' => array( - 'a' => '1', - 'b' => '2', - 'c' => '2', - ) - ), - 'cn=c' => array( - 'dn' => 'cn=c', - 'data' => array( - 'a' => '1', - 'b' => '2', - 'c' => '3', - ) - ), - 'cn=d' => array( - 'dn' => 'cn=d', - 'data' => array( - 'a' => '2', - 'b' => '2', - 'c' => '1', - ) - ), - ) - ); - $injector->setInstance('Horde_Kolab_Server_Config', $config); - $injector->bindFactory('Horde_Kolab_Server_Structure', - 'Horde_Kolab_Server_Factory', - 'getStructure'); - $injector->bindFactory('Horde_Kolab_Server', - 'Horde_Kolab_Server_Factory', - 'getServer'); - $db = $injector->getInstance('Horde_Kolab_Server'); - - $a = $db->search('(c=1)'); - $this->assertEquals( - array( - 'cn=a' => array( - 'a' => '1', - 'b' => '1', - 'c' => '1', - 'dn' => 'cn=a', - ), - 'cn=d' => array( - 'a' => '2', - 'b' => '2', - 'c' => '1', - 'dn' => 'cn=d', - ), - ), - $a - ); - - $a = $db->search('(c=3)'); - $this->assertEquals( - array( - 'cn=c' => array( - 'a' => '1', - 'b' => '2', - 'c' => '3', - 'dn' => 'cn=c', - ), - ), - $a - ); - - $a = $db->search('(c=3)', array('attributes' => array('a'))); - $this->assertEquals( - array( - 'cn=c' => array( - 'a' => '1', - 'dn' => 'cn=c', - ), - ), - $a - ); - - $a = $db->search('(&(a=1)(b=2))', array('attributes' => array('a', 'b'))); - $this->assertEquals( - array( - 'cn=b' => array( - 'a' => '1', - 'b' => '2', - 'dn' => 'cn=b', - ), - 'cn=c' => array( - 'a' => '1', - 'b' => '2', - 'dn' => 'cn=c', - ), - ), - $a - ); - - $a = $db->search('(&(b=2))', array('attributes' => array('b'))); - $this->assertEquals( - array( - 'cn=b' => array( - 'b' => '2', - 'dn' => 'cn=b', - ), - 'cn=c' => array( - 'b' => '2', - 'dn' => 'cn=c', - ), - 'cn=d' => array( - 'b' => '2', - 'dn' => 'cn=d', - ), - ), - $a - ); - - $a = $db->search('(!(b=2))', array('attributes' => array('a', 'b'))); - $this->assertEquals( - array( - 'cn=a' => array( - 'a' => '1', - 'b' => '1', - 'dn' => 'cn=a', - ), - ), - $a - ); - - $a = $db->search('(&(!(x=2))(b=1))', array('attributes' => array('b'))); - $this->assertEquals( - array( - 'cn=a' => array( - 'b' => '1', - 'dn' => 'cn=a', - ), - ), - $a - ); - } - -} -- 2.11.0