From 5071ed1c39807a55fd38759a979d95b4a6cfc40b Mon Sep 17 00:00:00 2001 From: Gunnar Wrobel Date: Mon, 6 Apr 2009 07:20:33 +0200 Subject: [PATCH] Moved the ability to determine object attribtues into the core server class as it is something required for all defined server types. --- framework/Kolab_Server/lib/Horde/Kolab/Server.php | 179 +++++++++++++++++- .../Kolab_Server/lib/Horde/Kolab/Server/Ldap.php | 201 +++++---------------- .../Kolab_Server/lib/Horde/Kolab/Server/Test.php | 29 ++- 3 files changed, 236 insertions(+), 173 deletions(-) diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server.php b/framework/Kolab_Server/lib/Horde/Kolab/Server.php index f561b6343..f894b8291 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server.php @@ -33,6 +33,9 @@ require_once 'Horde/Autoloader.php'; */ abstract class Horde_Kolab_Server { + /** Maximum accepted level for the object class hierarchy */ + const MAX_HIERARCHY = 100; + /** * Server parameters. * @@ -55,13 +58,6 @@ abstract class Horde_Kolab_Server protected $searches; /** - * Does this server type support automatic schema analysis? - * - * @var boolean - */ - public $schema_support = false; - - /** * Construct a new Horde_Kolab_Server object. * * @param array $params Parameter array. @@ -176,6 +172,24 @@ abstract class Horde_Kolab_Server } /** + * Stores the attribute definitions in the cache. + */ + function shutdown() + { + if (isset($this->attributes)) { + if (!empty($GLOBALS['conf']['kolab']['server']['cache']['driver'])) { + $params = isset($GLOBALS['conf']['kolab']['server']['cache']['params']) + ? $GLOBALS['conf']['kolab']['server']['cache']['params'] : null; + $cache = Horde_Cache::singleton($GLOBALS['conf']['kolab']['server']['cache']['driver'], + $params); + foreach ($this->attributes as $key => $value) { + $cache->set('attributes_' . $key, @serialize($value)); + } + } + } + } + + /** * Fetch a Kolab object. * * This method will not retrieve any data from the server @@ -325,6 +339,157 @@ abstract class Horde_Kolab_Server } /** + * 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) + { + static $cache = null; + static $lifetime; + + if (!isset($this->attributes)) { + if (!empty($GLOBALS['conf']['kolab']['server']['cache']['driver'])) { + $params = isset($GLOBALS['conf']['kolab']['server']['cache']['params']) + ? $GLOBALS['conf']['kolab']['server']['cache']['params'] : null; + $cache = Horde_Cache::singleton($GLOBALS['conf']['kolab']['server']['cache']['driver'], + $params); + register_shutdown_function(array($this, 'shutdown')); + $lifetime = isset($GLOBALS['conf']['kolab']['server']['cache']['lifetime']) + ? $GLOBALS['conf']['kolab']['server']['cache']['lifetime'] : 300; + } + } + + if (empty($this->attributes[$class])) { + + if (!empty($cache)) { + $this->attributes[$class] = @unserialize($cache->get('attributes_' . $class, $lifetime)); + } + + if (empty($this->attributes[$class])) { + + $childclass = $class; + $classes = array(); + $level = 0; + while ($childclass != 'Horde_Kolab_Server_Object' + && $level < self::MAX_HIERARCHY) { + $classes[] = $childclass; + $childclass = get_parent_class($childclass); + $level++; + } + + /** Finally add the basic object class */ + $classes[] = $childclass; + + if ($level == self::MAX_HIERARCHY) { + Horde::logMessage(sprintf('The maximal level of the object hierarchy has been exceeded for class \"%s\"!', + $class), + __FILE__, __LINE__, PEAR_LOG_ERROR); + } + + /** + * Collect attributes from bottom to top. + */ + $classes = array_reverse($classes); + + $types = array('defined', 'required', 'derived', 'defaults', + 'locked', 'object_classes'); + foreach ($types as $type) { + $$type = array(); + } + + foreach ($classes as $childclass) { + $vars = get_class_vars($childclass); + if (isset($vars['init_attributes'])) { + foreach ($types as $type) { + /** + * If the user wishes to adhere to the schema + * information from the server we will skip the + * attributes defined within the object class here. + */ + if (!empty($GLOBALS['conf']['kolab']['server']['schema_override']) + && in_array($type, 'defined', 'required')) { + continue; + } + if (isset($vars['init_attributes'][$type])) { + $$type = array_merge($$type, + $vars['init_attributes'][$type]); + } + } + } + } + + $attrs = array(); + + foreach ($object_classes as $object_class) { + $info = $this->getObjectclassSchema($object_class); + if (isset($info['may'])) { + $defined = array_merge($defined, $info['may']); + } + if (isset($info['must'])) { + $defined = array_merge($defined, $info['must']); + $required = array_merge($required, $info['must']); + } + foreach ($defined as $attribute) { + $attrs[$attribute] = $this->getAttributeSchema($attribute); + } + foreach ($required as $attribute) { + $attrs[$attribute]['required'] = true; + } + foreach ($locked as $attribute) { + $attrs[$attribute]['locked'] = true; + } + foreach ($defaults as $attribute => $default) { + $attrs[$attribute]['default'] = $default; + } + $attrs[Horde_Kolab_Server_Object::ATTRIBUTE_OC]['default'] = $object_classes; + + $attrs = array_merge($attrs, $derived); + + } + $this->attributes[$class] = array($attrs, + array( + 'derived' => array_keys($derived), + 'locked' => $locked, + 'required' => $required)); + } + } + return $this->attributes[$class]; + } + + /** + * 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. + */ + protected function getObjectclassSchema($objectclass) + { + return array(); + } + + /** + * 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. + */ + protected function getAttributeSchema($attribute) + { + return array(); + } + + /** * 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/Ldap.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap.php index 591c4d013..fb25297a7 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Ldap.php @@ -28,9 +28,6 @@ */ class Horde_Kolab_Server_Ldap extends Horde_Kolab_Server { - /** Maximum accepted level for the object class hierarchy */ - const MAX_HIERARCHY = 100; - /** * LDAP connection handle. * @@ -53,13 +50,6 @@ class Horde_Kolab_Server_Ldap extends Horde_Kolab_Server private $_base_dn; /** - * Does this server type support automatic schema analysis? - * - * @var boolean - */ - public $schema_support = false; - - /** * The LDAP schemas. * * @var Net_LDAP2_Schema @@ -105,10 +95,6 @@ class Horde_Kolab_Server_Ldap extends Horde_Kolab_Server $this->_config = $config; - if (!empty($params['schema_support'])) { - $this->schema_support = true; - } - $this->connect(); parent::__construct($params); @@ -310,168 +296,67 @@ class Horde_Kolab_Server_Ldap extends Horde_Kolab_Server } /** - * Return the attributes supported by the given object class. + * Return the ldap schema. * - * @param string $class Determine the attributes for this class. + * @return Net_LDAP2_Schema The LDAP schema. * - * @return array The supported attributes. - * - * @throws Horde_Kolab_Server_Exception If the schema analysis fails. + * @throws Horde_Kolab_Server_Exception If retrieval of the schema failed. */ - public function &getAttributes($class) + private function _getSchema() { - static $cache = null; - static $lifetime; - - if (!isset($this->attributes)) { - if (!empty($GLOBALS['conf']['kolab']['server']['cache']['driver'])) { - $params = isset($GLOBALS['conf']['kolab']['server']['cache']['params']) - ? $GLOBALS['conf']['kolab']['server']['cache']['params'] : null; - $params['sub'] = 'attributes'; - $cache = Horde_Cache::singleton($GLOBALS['conf']['kolab']['server']['cache']['driver'], - $params); - register_shutdown_function(array($this, 'shutdown')); - $lifetime = isset($GLOBALS['conf']['kolab']['server']['cache']['lifetime']) - ? $GLOBALS['conf']['kolab']['server']['cache']['lifetime'] : 300; + if (!isset($this->_schema)) { + $result = $this->_ldap->schema(); + if ($result instanceOf PEAR_Error) { + throw new Horde_Kolab_Server_Exception($result->getMessage()); } + $this->_schema = &$result; } + return $this->_schema; + } - if (empty($this->attributes[$class])) { - - if (!empty($cache)) { - $this->attributes[$class] = @unserialize($cache->get($class, $lifetime)); - } - - if (empty($this->attributes[$class])) { - - $childclass = $class; - $classes = array(); - $level = 0; - while ($childclass != 'Horde_Kolab_Server_Object' - && $level < self::MAX_HIERARCHY) { - $classes[] = $childclass; - $childclass = get_parent_class($childclass); - $level++; - } - - /** Finally add the basic object class */ - $classes[] = $childclass; - - if ($level == self::MAX_HIERARCHY) { - Horde::logMessage(sprintf('The maximal level of the object hierarchy has been exceeded for class \"%s\"!', - $class), - __FILE__, __LINE__, PEAR_LOG_ERROR); - } - - /** - * Collect attributes from top to bottom. - */ - $classes = array_reverse($classes); - - $derived = array(); - $defaults = array(); - $locked = array(); - $object_classes = array(); - - foreach ($classes as $childclass) { - $vars = get_class_vars($childclass); - if (isset($vars['init_attributes'])) { - $derived = array_merge($derived, - $vars['init_attributes']['derived']); - $defaults = array_merge($defaults, - $vars['init_attributes']['defaults']); - $locked = array_merge($locked, - $vars['init_attributes']['locked']); - $object_classes = array_merge($object_classes, - $vars['init_attributes']['object_classes']); - } - } - - if ($this->schema_support === true) { - if (!isset($this->_schema)) { - $result = $this->_ldap->schema(); - if ($result instanceOf PEAR_Error) { - throw new Horde_Kolab_Server_Exception($result->getMessage()); - } - $this->_schema = &$result; - } - $supported = array(); - $required = array(); - foreach ($object_classes as $object_class) { - $info = $this->_schema->get('objectclass', $object_class); - if ($info instanceOf PEAR_Error) { - throw new Horde_Kolab_Server_Exception($info->getMessage()); - } - if (isset($info['may'])) { - $supported = array_merge($supported, $info['may']); - } - if (isset($info['must'])) { - $supported = array_merge($supported, $info['must']); - $required = array_merge($required, $info['must']); - } - } - if (empty($supported) && empty($required)) { - return false; - } - foreach ($supported as $attribute) { - $info = $this->_schema->get('attribute', $attribute); - if ($info instanceOf PEAR_Error) { - throw new Horde_Kolab_Server_Exception($info->getMessage()); - } - $attrs[$attribute] = $info; - } - foreach ($required as $attribute) { - $attrs[$attribute]['required'] = true; - } - foreach ($locked as $attribute) { - $attrs[$attribute]['locked'] = true; - } - foreach ($defaults as $attribute) { - $attrs[$attribute]['default'] = true; - } - $attrs[Horde_Kolab_Server_Object::ATTRIBUTE_OC]['default'] = $object_classes; - - $attrs = array_merge($attrs, $derived); - - $this->attributes[$class] = array($attrs, - array( - 'derived' => $derived, - 'locked' => $locked, - 'required' => $required, - )); - } else { - $this->attributes[$class] = array(array(), - array( - 'derived' => array(), - 'locked' => array(), - 'required' => array(), - )); - } + /** + * 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. + */ + protected function getObjectclassSchema($objectclass) + { + if (!empty($this->_config['schema_support'])) { + $schema = $this->_getSchema(); + $info = $schema->get('objectclass', $object_class); + if ($info instanceOf PEAR_Error) { + throw new Horde_Kolab_Server_Exception($info->getMessage()); } + return $info; } - return $this->attributes[$class]; + return parent::getObjectclassSchema($objectclass); } /** - * Stores the attribute definitions in the cache. + * 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. */ - function shutdown() + protected function getAttributeSchema($attribute) { - if (isset($this->attributes)) { - if (!empty($GLOBALS['conf']['kolab']['server']['cache']['driver'])) { - $params = isset($GLOBALS['conf']['kolab']['server']['cache']['params']) - ? $GLOBALS['conf']['kolab']['server']['cache']['params'] : null; - $params['sub'] = 'attributes'; - $cache = Horde_Cache::singleton($GLOBALS['conf']['kolab']['server']['cache']['driver'], - $params); - foreach ($this->attributes as $key => $value) { - $cache->set($key, @serialize($value)); - } + if (!empty($this->_config['schema_support'])) { + $schema = $this->_getSchema(); + $info = $schema->get('attribute', $attribute); + if ($info instanceOf PEAR_Error) { + throw new Horde_Kolab_Server_Exception($info->getMessage()); } } + return parent::getAttributeSchema($attribute); } - /** * Search for object data. * diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Test.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Test.php index 6e8332d3d..1e1889718 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Test.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Test.php @@ -534,18 +534,31 @@ class Horde_Kolab_Server_Test extends Horde_Kolab_Server_Kolab } /** - * Return the attributes of an entry. + * Return the schema for the given objectClass. * - * @param array $entry The LDAP entry. + * @param string $objectclass Fetch the schema for this objectClass. * - * @return array The attributes of the entry. + * @return array The schema for the given objectClass. + * + * @throws Horde_Kolab_Server_Exception If retrieval of the schema failed. */ - protected function getAttributes($entry) + public function getObjectclassSchema($objectclass) { - if (is_array($entry)) { - return $entry; - } - return false; + return array(); + } + + /** + * 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 array(); } /** -- 2.11.0