From: Gunnar Wrobel
Date: Sun, 12 Apr 2009 19:55:09 +0000 (+0200) Subject: Rewrote collapsed arguments. They are separate from derived values now. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=50d1417df9ffbadd7dc52140c81bbba91b4fb837;p=horde.git Rewrote collapsed arguments. They are separate from derived values now. --- diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server.php b/framework/Kolab_Server/lib/Horde/Kolab/Server.php index 2c3707c86..4ffd5eab7 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server.php @@ -390,7 +390,6 @@ abstract class Horde_Kolab_Server ? $GLOBALS['conf']['kolab']['server']['cache']['lifetime'] : 300; } } - if (empty($this->attributes[$class])) { if (!empty($cache)) { @@ -423,8 +422,8 @@ abstract class Horde_Kolab_Server */ $classes = array_reverse($classes); - $types = array('defined', 'required', 'derived', 'defaults', - 'locked', 'object_classes'); + $types = array('defined', 'required', 'derived', 'collapsed', + 'defaults', 'locked', 'object_classes'); foreach ($types as $type) { $$type = array(); } @@ -483,34 +482,49 @@ abstract class Horde_Kolab_Server } $attrs[Horde_Kolab_Server_Object::ATTRIBUTE_OC]['default'] = $object_classes; } - foreach ($derived as $key => $attribute) { - if (isset($attribute['base'])) { - if (!is_array($attribute['base'])) { - $bases = array($attribute['base']); - } else { - $bases = $attribute['base']; + foreach ($derived as $key => $attributes) { + $supported = true; + if (isset($attributes['base'])) { + foreach ($attributes['base'] as $attribute) { + /** + * Usually derived attribute are determined on basis + * of one or more attributes. If any of these is not + * supported the derived attribute should not be + * included into the set of supported attributes. + */ + if (!isset($attrs[$attrs])) { + unset($derived[$attribute]); + $supported = false; + break; + } } - /** - * Usually derived attribute are determined on basis - * of one or more attributes. If any of these is not - * supported the derived attribute should not be - * included into the set of supported attributes. - */ - foreach ($bases as $base) { - if (!isset($attrs[$base])) { - continue; + } + if ($supported) { + $attrs[$key] = $attributes; + } + } + $check_collapsed = $collapsed; + foreach ($check_collapsed as $key => $attributes) { + if (isset($attributes['base'])) { + foreach ($attributes['base'] as $attribute) { + /** + * Usually collapsed attribute are determined on basis + * of one or more attributes. If any of these is not + * supported the collapsed attribute should not be + * included into the set of supported attributes. + */ + if (!isset($attrs[$attrs])) { + unset($collapsed[$attribute]); } - $attrs[$key] = $attribute; } - } else { - $attrs[$key] = $attribute; } } $this->attributes[$class] = array($attrs, array( - 'derived' => array_keys($derived), - 'locked' => $locked, - 'required' => $required)); + 'derived' => array_keys($derived), + 'collapsed' => $collapsed, + 'locked' => $locked, + 'required' => $required)); } } return $this->attributes[$class]; diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php index c607da807..40dd24c5f 100644 --- a/framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php +++ b/framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php @@ -120,7 +120,18 @@ class Horde_Kolab_Server_Object * Derived attributes are calculated based on other attribute values. */ 'derived' => array( - self::ATTRIBUTE_ID => array(), + self::ATTRIBUTE_UID => array( + 'method' => 'getUid', + ), + self::ATTRIBUTE_ID => array( + 'method' => 'getId', + ), + ), + /** + * Attributes that are written using the information from several other + * attributes. + */ + 'collapsed' => array( ), /** * Attributes that are required for this object type. It is not @@ -291,31 +302,22 @@ class Horde_Kolab_Server_Object */ public function get($attr, $single = true) { - if ($attr != self::ATTRIBUTE_UID) { - // FIXME: This wont work this way. - 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)); - } - if (!$this->_cache) { - $this->read(); - } + 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)); + } + if (!$this->_cache) { + $this->read(); } - if (!empty($this->attribute_map['derived']) - && in_array($attr, $this->attribute_map['derived'])) { + if (isset($this->attribute_map['derived'][$attr])) { return $this->derive($attr); } - switch ($attr) { - case self::ATTRIBUTE_UID: - return $this->uid; - default: - return $this->_get($attr, $single); - } + return $this->_get($attr, $single); } /** @@ -348,89 +350,48 @@ class Horde_Kolab_Server_Object */ protected function derive($attr) { - switch ($attr) { - case self::ATTRIBUTE_ID: - return substr($this->uid, 0, - strlen($this->uid) - strlen($this->server->getBaseUid()) - 1); - default: + 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 $this->getField($attr); - } - } - - /** - * Get a derived attribute value. - * - * @param string $attr The attribute to derive. - * @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($attr, $separator = '$', $max_count = null) - { - $basekey = $this->attributes[$attr]['base']; - $base = $this->_get($basekey); - if (empty($base)) { - return; + return call_user_func_array(array($this, + $this->attributes[$attr]['method']), + $args); } - if (!empty($max_count)) { - $fields = explode($separator, $base, $max_count); - } else { - $fields = explode($separator, $base); - } - return isset($fields[$this->attributes[$attr]['order']]) ? $this->unquote($fields[$this->attributes[$attr]['order']]) : null; + return false; } /** * Collapse derived values back into the main attributes. * * @param string $key The attribute to collapse into. - * @param array $attributes The attribute to collapse. + * @param array $attributes The attributes to collapse. * @param array $info The information currently working on. - * @param string $separator Separate the fields using this character. * * @return NULL. */ - protected function collapse($key, $attributes, &$info, $separator = '$') + protected function collapse($key, $attributes, &$info) { - switch ($key) { - default: - /** - * 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 = count($attributes); - foreach ($attributes as $attribute) { - if (empty($info[$attribute])) { - $empty--; - } else { - break; - } - } - if ($empty == 0) { - return; + $changes = false; + foreach ($attributes as $attribute) { + if (isset($info[$attribute])) { + $changes = true; } - ksort($attributes); - $unset = $attributes; - $result = ''; - for ($i = 0; $i < $empty; $i++) { - $akey = array_shift($attributes); - $value = isset($info[$akey]) ? $info[$akey] : ''; - if (is_array($value)) { - $value = $value[0]; - } - $result .= $this->quote($value); - if ($i != ($empty - 1)) { - $result .= $separator; + } + 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); } - foreach ($unset as $attribute) { - unset($info[$attribute]); - } - - $info[$key] = $result; } } @@ -500,6 +461,110 @@ class Horde_Kolab_Server_Object } /** + * 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. + * + * @param string $attr The attribute to derive. + * @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($base, $field = 0, $separator = '$', $max_count = null) + { + $basekey = $this->attributes[$attr]['base']; + $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. + * + * @return NULL. + */ + protected function setField($key, $attributes, &$info, $separator = '$') + { + /** + * 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 = 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($info[$attribute]); + if (!empty($old)) { + $info[$attribute] = $old; + } + } + if (empty($info[$attribute])) { + $empty--; + } else { + break; + } + } + if ($empty == 0) { + return; + } + ksort($attributes); + $unset = $attributes; + $result = ''; + for ($i = 0; $i < $empty; $i++) { + $akey = array_shift($attributes); + $value = $info[$akey]; + if (is_array($value)) { + $value = $value[0]; + } + $result .= $this->quote($value); + if ($i != ($empty - 1)) { + $result .= $separator; + } + } + foreach ($unset as $attribute) { + unset($info[$attribute]); + } + $info[$key] = $result; + } + + /** + * Get an empty value + * + * @return string An empty string. + */ + public function getEmpty() + { + return ''; + } + + /** * Generates an ID for the given information. * * @param array $info The data of the object. @@ -546,15 +611,6 @@ class Horde_Kolab_Server_Object } } - $collapse = array(); - foreach ($this->attribute_map['derived'] as $key) { - $attribute = $this->attributes[$key]; - if (empty($attribute['readonly']) && isset($attribute['base']) - && isset($attribute['order'])) { - $collapse[$attribute['base']][$attribute['order']] = $key; - } - } - if (!$this->exists()) { foreach ($this->attribute_map['required'] as $key) { if (!in_array($key, array_keys($info)) || $info[$key] === null @@ -575,24 +631,25 @@ class Horde_Kolab_Server_Object } } } else { - $old_keys = array_keys($this->_cache); + $old_keys = array_keys($this->attributes); $submitted = $info; foreach ($submitted as $key => $value) { /** - * Empty values are ignored in case there is also no old value - * stored or the value is locked. If there is an old value we - * must assume the value was removed. + * 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); if (($value === null || $info[$key] === '') - && (!isset($this->_cache[$key]) + && (empty($old) || in_array($key, $this->attribute_map['locked']))) { unset($info[$key]); continue; } if (in_array($key, $old_keys)) { - if (!is_array($value) && !is_array($this->_cache[$key])) { - if ($value == $this->_cache[$key]) { + if (!is_array($value) && !is_array($old)) { + if ($value == $old) { // Unchanged value unset($info[$key]); } @@ -601,10 +658,8 @@ class Horde_Kolab_Server_Object $value = array($value); $info[$key] = $value; } - if (!is_array($this->_cache[$key])) { - $old = array($this->_cache[$key]); - } else { - $old = $this->_cache[$key]; + if (!is_array($old)) { + $old = array($old); } $changes = array_merge(array_diff($old, $value), array_diff($value, $old)); @@ -637,7 +692,7 @@ class Horde_Kolab_Server_Object } } - foreach ($collapse as $key => $attributes) { + foreach ($this->attribute_map['collapsed'] as $key => $attributes) { $this->collapse($key, $attributes, $info); } diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/ObjectTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/ObjectTest.php index d150bc49b..5ada2626d 100644 --- a/framework/Kolab_Server/test/Horde/Kolab/Server/ObjectTest.php +++ b/framework/Kolab_Server/test/Horde/Kolab/Server/ObjectTest.php @@ -135,10 +135,26 @@ class DummyDB { public function getAttributes() { - return array(array(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_FN => array()), + return array(array(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_UID => array( + 'method' => 'getUid', + ), + Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_FN => array( + 'method' => 'getFn', + )), array( - 'derived' => array(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_FN), + 'derived' => array(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_UID => array( + 'method' => 'getUid', + ), + Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_FN => array( + 'method' => 'getFn', + ), + ), 'locked' => array(), 'required' => array())); } + + public function read() + { + return false; + } }