From 5c66c7d1623a86e32e134938dc54c5f11308181e Mon Sep 17 00:00:00 2001 From: Klaus Leithoff Date: Thu, 14 Oct 2010 15:33:10 +0000 Subject: [PATCH] categories: better handling of editing/moving categories within the cat-tree --- admin/inc/class.admin_categories.inc.php | 10 +++- phpgwapi/inc/class.categories.inc.php | 71 +++++++++++++++++++++++- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/admin/inc/class.admin_categories.inc.php b/admin/inc/class.admin_categories.inc.php index 04852c8ba9..76575629ce 100644 --- a/admin/inc/class.admin_categories.inc.php +++ b/admin/inc/class.admin_categories.inc.php @@ -136,8 +136,14 @@ class admin_categories case 'apply': if ($content['id'] && self::$acl_edit) { - $cats->edit($content); - $msg = lang('Category saved.'); + try { + $cats->edit($content); + $msg = lang('Category saved.'); + } + catch (egw_exception_wrong_userinput $e) + { + $msg = lang('Unwilling to save category with current settings. Check for inconsistency:').$e->getMessage(); // display conflicts etc. + } } elseif (!$content['id'] && ( $content['parent'] && self::$acl_add_sub || diff --git a/phpgwapi/inc/class.categories.inc.php b/phpgwapi/inc/class.categories.inc.php index 7d87af0fba..6ad0ac9ffd 100644 --- a/phpgwapi/inc/class.categories.inc.php +++ b/phpgwapi/inc/class.categories.inc.php @@ -414,6 +414,10 @@ class categories $values['level'] = $this->id2name($values['parent'],'level')+1; $values['main'] = $this->id2name($values['parent'],'main'); } + else + { + $values['level'] = 0; + } $this->db->insert(self::TABLE,array( 'cat_parent' => $values['parent'], 'cat_owner' => $this->account_id, @@ -595,34 +599,95 @@ class categories self::invalidate_cache($cat_id); } + /** + * adapt_level_in_subtree of a category + * + * Owner and appname are set from the values used to instanciate the class! + * + * @param array $values array with cat-data (it need to be complete, as everything get's written) + * @return void + */ + function adapt_level_in_subtree($values) + { + foreach ((array) $this->return_sorted_array('',False,'','','',False, $values['id']) as $cat) + { + if ($cat['parent'] == $values['id']) + { + $this->db->update(self::TABLE,array( + 'cat_level' => $values['level']+1, + 'last_mod' => time(), + ),array( + 'cat_id' => $cat['id'], + 'cat_appname' => $this->app_name, + ),__LINE__,__FILE__); + $cat['level'] = $values['level'] + 1; + self::invalidate_cache($cat['id']); + $this->adapt_level_in_subtree($cat); + } + else + { + continue; + } + } + } + + /** + * check_consistency4update - for edit + * + * @param array $values array with cat-data (it need to be complete, as everything get's written) + * @return mixed string/boolean errorstring if consitency check failed / true if the consistency check did not fail + */ + function check_consistency4update($values) + { + // check if we try to move an element down its own subtree, which will fail + foreach ($this->return_sorted_array('',False,'','','',False, $values['id']) as $cat) if ($cat['id'] == $values['parent']) return lang('Cannot set a category as parent, which is part of this categorys subtree!'); + // check if we try to be our own parent + if ($values['parent']==$values['id']) return lang('Cannot set this cat as its own parent!'); // deny to be our own parent + // check if parent still exists + if ((int)$values['parent']>0 && !$this->read($values['parent'])) return lang('Chosen parent category no longer exists'); + return true; + } + /** * edit / update a category * * Owner and appname are set from the values used to instanciate the class! * * @param array $values array with cat-data (it need to be complete, as everything get's written) - * @return int cat-id + * @return int cat-id or false if it failed */ function edit($values) { if (isset($values['old_parent']) && (int)$values['old_parent'] != (int)$values['parent']) { - $this->delete($values['id'],False,True); - + $ret = $this->check_consistency4update($values); + if ($ret !== true) throw new egw_exception_wrong_userinput($ret); + // everything seems in order -> proceed + $values['level'] = ($values['parent'] ? $this->id2name($values['parent'],'level')+1:0); + $this->adapt_level_in_subtree($values); + return $this->add($values); } else { + //echo "old parent not set
"; if ($values['parent'] > 0) { + $ret = $this->check_consistency4update($values); + if ($ret !== true) throw new egw_exception_wrong_userinput($ret); + + // everything seems in order -> proceed $values['main'] = $this->id2name($values['parent'],'main'); $values['level'] = $this->id2name($values['parent'],'level') + 1; } else { + //echo "new parent not set
"; $values['main'] = $values['id']; $values['level'] = 0; } + // adapt the level info in each child + $this->adapt_level_in_subtree($values); } $this->db->update(self::TABLE,array( 'cat_name' => $values['name'],