Code

Updated release part detection
[gosa.git] / gosa-plugins / goto-ng / admin / newConfigManagement / class_newConfigManagement.inc
index 2633eda4004eec32ca3188d126358120b76e99ab..2b92346270e932a952ff6b6fead2b49751747f86 100644 (file)
@@ -13,7 +13,11 @@ class newConfigManagement extends plugin
     var $dataModel = NULL;
     var $listing = NULL;
 
-    var $cfgTypeMap = NULL;
+    var $cfgItemMap = NULL;
+
+    var $addableContainerItems = array();
+    var $currentObject = NULL;
+    var $itemsPerMethod = NULL;
 
     /*! \brief  Initialize the plugin and finally update the data model.
      */
@@ -26,49 +30,106 @@ class newConfigManagement extends plugin
         //  to use for the HTML it produces.
         $this->TemplateEngine = new TemplateEngine($config);
 
+        // Preset item config - with Distribution and Release objects.
+        $items = array();
+        $items['root']['container'] = array('Distribution');
+        $items['root']['name'] = '/';
+        $items['root']['description'] = _('Root');
+
+        // Define distribution paramters.
+        $dOpt1 = array('description' => _('Name'), 'default' => '', 'value' => '', 'required' => true,
+                'type' => 'string', 'display' => _('Name'));
+        $dOpt2 = array('description' => _('Distribution type'), 'default' => 'deb', 'value' => 'deb', 'required' => true,
+                'type' => 'combobox', 'display' => _('Distribution type'), 'values' => array("deb" => 'deb', "rpm" => 'rpm'));
+        $dOpt3 = array('description' => _('Mirror Url'), 'default' => '', 'value' => '', 'required' => false,
+                'type' => 'string', 'display' => _('Mirror Url'));
+        $dOpt4 = array('description' => _('Method'), 'default' => 'puppet', 'value' => 'puppet', 'required' => false,
+                'type' => 'combobox', 'display' => _('Installation method'), 'values'=>array('puppet'=>_('Puppet')));
+
+        // Define release parameters
+        $rOpt1 = array('description' => _('Name'), 'default' => '', 'value' => '', 'required' => true,
+                'type' => 'string', 'display' => _('Name'));
+
+        $items['Distribution']['container'] = array('Release');
+        $items['Distribution']['name'] = 'Distribution';
+        $items['Distribution']['description'] = _('Distribution');
+        $items['Distribution']['options']['name'] = $dOpt1;
+        $items['Distribution']['options']['mirror'] = $dOpt3;
+        $items['Distribution']['options']['installation_type'] = $dOpt2;
+        $items['Distribution']['options']['installation_method'] = $dOpt4;
+
+        $items['Release']['container'] = array('Release', '__CFG_ITEMS__');
+        $items['Release']['name'] = 'Release';
+        $items['Release']['description'] = _('Release');
+        $items['Release']['options']['name'] = $rOpt1;
+
+        $this->installationMethods = array();
+        $this->installationMethods['root']['description'] = _('root');
+        $this->installationMethods['root']['name'] = 'root';
+        $this->installationMethods['root']['title'] = _('root');
+        $this->installationMethods['root']['items']['Distribution'] = &$items['Distribution'];
+        $this->installationMethods['root']['items']['Release'] = &$items['Release'];
+        $this->installationMethods['root']['items']['root'] = &$items['root'];
+
         // Request an update of the data model
-        $this->cfgTypeMap = array();
         $this->loadInstallationMethods();
         $this->updateDataModel();
         $this->listing->setListingTypes($this->getListingTypes());
     }
 
 
-    /*! \brief  Sets the installation method to the given method.
-     *          Updates the template engine and adds the initial root
-     *           object for the selected method.
-     *  @param  The method to use.
-     *  @return TRUE on success else FALSE.
+    /*! \brief  Intializes this plugin
+     *          All available installation methods will be loaded
      */
-    function setInstallMethod($str)
+    function loadInstallationMethods()
     {
-        if(!isset($this->installationMethods[$str])){
-            $this->itemConfig = array();
-            $this->invalidInstallMethod =TRUE;
-            $this->errorMessage = sprintf(_("Invalid installation method %s selected!"), bold($str));
-            msg_dialog::display(_("Setup"), $this->errorMessage, ERROR_DIALOG);
-            return(FALSE);
+        // Reset erros
+        $this->rpcError = $this->initFailed = FALSE;
+
+        // Load configuration via rpc.
+        $rpc = $this->config->getRpcHandle();
+        $res = $rpc->getSupportedInstallMethods();
+        if(!$rpc->success()){
+            $this->rpcError = TRUE;
+            $this->errorMessage = $rpc->get_error();;
+            return;
+        }
+
+        // Populate install methods on success.
+        if(!count($res)){
+            $this->errorMessage = _("No selectable install methods returned!");
+            msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
+            $this->initFailed = TRUE;
+            return;
         }else{
-    
-            $this->TemplateEngine->setTemplate($str.".tpl");
-            $this->itemConfig = $this->installationMethods[$str]['items'];
-            $this->invalidInstallMethod =FALSE;
-            $this->TemplateEngine->load($this->itemConfig);
-
-            // Detect root item, its name is /
-            $root = NULL;
-            foreach($this->itemConfig as $key => $item){
-                if($item['name'] == '/') {
-                    $root = $key;
-                    break;
+
+            // Merge result with hard coded methods
+            $this->installationMethods = array_merge($this->installationMethods, $res);
+
+            // Walk through entries and create useful mappings.
+            $this->cfgItemMap = array();
+            $this->itemConfig = array();
+            $this->itemsPerMethod = array();
+            $rootElements = array();
+            foreach($this->installationMethods as $method => $items){
+                foreach($items['items'] as $itemName => $item){
+                    $this->itemsPerMethod[$method][] = $itemName;
+                    $this->cfgItemMap[$itemName] = $method;
+                    $this->itemConfig[$itemName] = &$this->installationMethods[$method]['items'][$itemName];
+                    // This enables us to create the first level of config items when 
+                    //  a release is selected.
+                    if($item['name'] == "/" && $itemName != 'root'){
+                        $rootElements = array_merge($rootElements, $item['container']);
+                    }
                 }
             }
-            if(!$root){
-                $this->errorMessage = sprintf(_("Installation method %s is invalid: no root object found!"), bold($str));
-                msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
-                $this->initFailed = TRUE;
-                $this->itemConfig = array();
-                return(FALSE);
+
+            // Merge in root elements to releases.
+            foreach($this->itemConfig as $item => $data){
+                if(in_array('__CFG_ITEMS__', $data['container'])){
+                    $this->itemConfig[$item]['container'] = array_merge($this->itemConfig[$item]['container'], $rootElements );
+                }
             }
         }
     }
@@ -85,17 +146,35 @@ class newConfigManagement extends plugin
         // Load distributions 
         $rpc = $this->config->getRpcHandle();
         $res = $rpc->getDistributions();
-
         if(!$rpc->success()){
             msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
             return(NULL);
         }else{
             foreach($res as $dist){
                 $this->dataModel->addItem('Distribution','/root', $dist['name'], $dist);
-                $this->cfgTypeMap['/root/'.$dist['name']] = $dist['installation_method'];
-                foreach($dist['releases'] as $release){
-                    $distPath = "/root/{$dist['name']}";
-                    $this->dataModel->addItem('Release',$distPath, $release['name'], $release);
+
+                if(isset($dist['releases'])){
+
+                    // Sort releases by name length
+                    $sort = array();
+                    foreach($dist['releases'] as $id => $release){
+                        $sort[strlen($release['name']) . $release['name']]  = $id;
+                    }
+                    uksort($sort, "strnatcasecmp");   
+
+                    // Append release tags
+                    foreach($sort as $id){
+                        $release = $dist['releases'][$id];
+                        $names = preg_split("/\//", $release['name']);
+    
+                        $rPath = "";
+                        $distPath = "/root/{$dist['name']}";
+                        foreach($names as $rName){
+                            $rPath .= '/'.$rName;
+                            $this->dataModel->addItem('Release',$distPath, $rName, $release);
+                            $distPath .= $rPath;
+                        }
+                    }
                 }
             }
         }
@@ -117,7 +196,6 @@ class newConfigManagement extends plugin
         if(isset($_POST['ROOT'])){
             $this->setCurrentContainer('/root');
         }elseif(isset($_POST['BACK'])){
-
             $path = $this->selectedContainer;
             if($this->dataModel->itemExistsByPath($path)){
                 $data = $this->dataModel->getItemByPath($path);
@@ -145,13 +223,16 @@ class newConfigManagement extends plugin
             // Only releases can contain config-items.
             if($data['type'] == 'Release' && $data['status'] != "fetched"){
 
+
+                // Request all config items for the selected release via rpc.
                 $rpc = $this->config->getRpcHandle();
-                $res = $rpc->listConfigItems($data['name']);
+                $releasePath = $this->getReleasePart($path);
+                $res = $rpc->listConfigItems($releasePath);
                 if(!$rpc->success()){
-                    msg_dialog::display(_("Error"), 
-                            sprintf(_("Failed to load distributions: %s"), 
-                                $rpc->get_error()),ERROR_DIALOG);
+                    msg_dialog::display(_("Error"),sprintf(_("Failed to load distributions: %s"),$rpc->get_error()),ERROR_DIALOG);
                 }else{
+            
+                    if(!$res) return;
 
                     // Sort entries by path length 
                     $sLen = array();
@@ -163,10 +244,14 @@ class newConfigManagement extends plugin
                     // Walk through each entry and then try to add it to the model
                     foreach($sLen as $unused => $itemPath){
 
+                        // Do not add the root element '/'
+                        if($itemPath == "/") continue;
+
                         $type = $res[$itemPath];
                 
-                        // Root installation objects do not have a name, so we use 'root' here.
-                        $targetPath = trim($path."/root/".$itemPath);
+                        // Append the items-path to the current path to create the 
+                        //  effective item path in the data model.
+                        $targetPath = trim($path."/".$itemPath);
 
                         // Remove trailing and duplicated slashes
                         $targetPath = rtrim($targetPath, '/');
@@ -178,11 +263,7 @@ class newConfigManagement extends plugin
                         // Cleanup the path and then add the item.
                         $targetPath = preg_replace("/[^\/]*$/","", $targetPath);
                         $targetPath = rtrim($targetPath,'/');
-                        $this->dataModel->addItem($type, $targetPath, $name, 
-                                array(    
-                                        '__path' => $itemPath,
-                                        '__release' => $path
-                                    ),'-' ); 
+                        $this->dataModel->addItem($type, $targetPath, $name,array(),'-' ); 
                     }
                     $this->dataModel->setItemStatus($path, 'fetched');
                 }
@@ -207,11 +288,38 @@ class newConfigManagement extends plugin
         $this->listing->setContainers($this->getContainerList());
         $this->listing->setContainer($cont);
 
-        // Set the correct installation method for the selected item
-        if(isset($this->cfgTypeMap[$cont])){
-            $method = $this->cfgTypeMap[$cont];
-            $this->setInstallMethod($method);
+        // Update the list of addable sub objects
+        $this->addableContainerItems = $this->getAddableContainersPerPath($cont);
+    }
+
+
+    function getAddableContainersPerPath($path)
+    {
+        $currentItem = $this->dataModel->getItemByPath($path);
+        $method = $this->getInstallationMethodPerPath($path);
+
+        // Get allowed items for the currently selected method 
+        //  merge in root elements, they are allowed everywhere.
+        $allowedItems = $this->itemsPerMethod[$method];
+        $allowedItems = array_merge($allowedItems, $this->itemsPerMethod['root']);
+
+        // Get addable items
+        $possibleItems = $this->itemConfig[$currentItem['type']]['container'];
+        return(array_unique(array_intersect($allowedItems, $possibleItems)));
+    }
+
+    
+    function getInstallationMethodPerPath($path)
+    {
+        $path .= '/';
+        while(preg_match("/\//", $path)){
+            $path = preg_replace("/\/[^\/]*$/","",$path);
+            $item = $this->dataModel->getItemByPath($path);
+            if(isset($item['values']['installation_method'])){
+                return($item['values']['installation_method']);
+            }
         }
+        return('root'); 
     }
 
 
@@ -236,7 +344,6 @@ class newConfigManagement extends plugin
      */
     function getItemsToBeDisplayed()
     {
-
         $path = $this->selectedContainer;
         $item = $this->dataModel->getItemByPath($path);
         return($item);
@@ -252,68 +359,32 @@ class newConfigManagement extends plugin
         $data = $this->dataModel->getItemByPath('/root');
         $res = array();
         $res["/root"] = array("name" => "/", "desc" => "");
-        $res = array_merge($res,$this->__recurseItem($data, array('Distribution','Release')));
+        $res = array_merge($res,$this->__recurseItem($data));
         return($res);
     }
 
 
-    /*! \brief  Recursivly walks through an item and collects all path and name info.
+    /*! \brief  Recursivly wlks through an item and collects all path and name info.
      *          The reult can then be used to fill the ItemSelector.
      *  @param  Array   The Item to recurse. 
      *  @param  Array   The type of of objects to collect. 
      *  @param  String  The parent path prefix which should be removed.
      *  @return Array   An array containing Array[path] = name
      */
-    function __recurseItem($item, $types, $parent = "")
+    function __recurseItem($item, $parent = "")
     {
         $res = array();
-        if(1 ||  in_array($item['type'], $types)){
-            $path = preg_replace("/".preg_quote($parent,'/')."/","",$item['path']);
-            $res[$path] = array('name' => $item['name'],'desc'=>$item['type']);
-        }
+        $path = preg_replace("/".preg_quote($parent,'/')."/","",$item['path']);
+        $res[$path] = array('name' => $item['name'],'desc'=>$item['type']);
         if(count($item['children'])){
             foreach($item['children'] as $child){
-                $res = array_merge($res, $this->__recurseItem($child, $types, $parent));
+                $res = array_merge($res, $this->__recurseItem($child, $parent));
             }
         }
         return($res);
     }
 
 
-    /*! \brief  Intializes this plugin
-     *          All available installation methods will be loaded
-     */
-    function loadInstallationMethods()
-    {
-        // Reset erros
-        $this->rpcError = $this->initFailed = FALSE;
-
-        // Load configuration via rpc.
-        $rpc = $this->config->getRpcHandle();
-
-        // Populate install methods on success.
-        $res = $rpc->getSupportedInstallMethods();
-        if(!$rpc->success()){
-            $this->rpcError = TRUE;
-            $this->errorMessage = $rpc->get_error();;
-            return;
-        }
-        $this->installationMethods = $res;
-        if(!count($this->installationMethods)){
-            $this->errorMessage = _("No selectable install methods returned!");
-            msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
-            $this->initFailed = TRUE;
-            return;
-        }else{
-            foreach($this->installationMethods as $method => $items){
-                foreach($items['items'] as $itemName => $item){
-                    $this->cfgTypeMap[$itemName] = $method;
-                }
-            }
-        }
-    }
-
-
     /*! \brief   Returns a info list about all items we can manage,
      *            this used to fill the listings <objectType> settings.
      *  @return Array   An array with item info.
@@ -388,38 +459,273 @@ class newConfigManagement extends plugin
 
 
 
-    /*! \brief   
-     *  @param  
-     *  @return 
+    /*! \brief  Removes an entry from the listing.
      */
-    function remove_lock()
+    function removeEntry($ids)
+    {
+        foreach($ids as $id){
+            $item = $this->dataModel->getItemById($id);
+
+            // Is an config item.
+            if($this->cfgItemMap[$item['type']] != 'root'){
+                $release = preg_replace("/^.*\//","", $this->getReleasePath($item['path']));
+                $path = $this->getItemPath($item['path']);
+
+                $rpc = $this->config->getRpcHandle();
+                $rpc->removeConfigItem($release, $path);
+                if(!$rpc->success()){
+                    msg_dialog::display(_("Error"), sprintf(_("Failed to remove: %s"), $rpc->get_error()),ERROR_DIALOG);
+                    return(NULL);
+                }else{
+                    $this->dataModel->removeItem($item['path']);
+                }
+            }else{
+                echo $item['type']." - are not handled yet!";
+            }
+        }
+    }
+
+    function getUsedNamesForPath($path)
     {
+        $item = $this->dataModel->getItemByPath($path);
+        $names = array();
+        foreach($item['children'] as $path => $data){
+            $names[] = $data['name'];
+        }
+        return($names);
     }
 
 
+    /*! \brief      Edits a selected list item.
+     */
     function editEntry($ids)
     {
-        // Update the template engine to use another type of item and
-        //  some other values.
         $item = $this->dataModel->getItemById($ids[0]);
-        $release = preg_replace("/^.*\//","",$item['values']['__release']);
-        $path = $item['values']['__path'];
+        $release = preg_replace("/^.*\//","", $this->getReleasePath($item['path']));
+        $path = $this->getItemPath($item['path']);
+        $method = $this->cfgItemMap[$item['type']];
 
         // Load item values on demand
-        if($item['status'] == '-'){
-            $rpc = $this->config->getRpcHandle();
-            $item['values']['itemValues'] = $rpc->getConfigItem($release, $path);
-            $this->dataModel->setItemStatus($item['path'], 'fetched');
-            $this->dataModel->setItemValues($item['path'], $item['values']);
+        if($this->cfgItemMap[$item['type']] != 'root'){
+            if($item['status'] == '-'){
+                $rpc = $this->config->getRpcHandle();
+                $item['values'] = $rpc->getConfigItem($release, $path);
+                $this->dataModel->setItemStatus($item['path'], 'fetched');
+                $this->dataModel->setItemValues($item['path'], $item['values']);
+            }
         }
 
-        $method = $this->cfgTypeMap[$item['type']];
-        $this->setInstallMethod($method);
-        echo $method;
-        $this->TemplateEngine->setValues($item['type'],$item['values']['itemValues']);
+        $this->TemplateEngine->load($this->itemConfig);
+        $this->TemplateEngine->setTemplate($method.".tpl");
+        $this->TemplateEngine->setValues($item['type'],$item['values']);
         $this->listing->setDialogObject($this->TemplateEngine);
+        $this->currentObject = $item;
     }
 
 
+    /*! \brief  Initiates the creation of a new item
+     */
+    function newEntry($type)
+    {
+        // We've to add a config item
+        $this->TemplateEngine->load($this->itemConfig);
+        if($this->cfgItemMap[$type] != 'root'){
+            $method = $this->cfgItemMap[$type];
+            $this->TemplateEngine->setTemplate($method.".tpl");
+            $this->TemplateEngine->setValues($type,array());
+            $this->listing->setDialogObject($this->TemplateEngine);
+            $this->currentObject = NULL;
+        }else{
+            $this->TemplateEngine->setTemplate("root.tpl");
+            $this->TemplateEngine->setValues($type,array());
+            $this->listing->setDialogObject($this->TemplateEngine);
+            $this->currentObject = NULL;
+        }
+    }
+
+
+    /*! \brief  Extracts the item-path out of a path.
+     *          e.g. /debian/squeeze/test/module -> /test/module
+     */
+    function getItemPath($fullPath)
+    {
+        $fPath = $fullPath.'/';
+        while(preg_match("/\//", $fPath)){
+            $fPath = preg_replace("/\/[^\/]*$/","", $fPath);
+            $item = $this->dataModel->getItemByPath($fPath);
+            if(in_array($item['type'], array('Release', 'Distribution', 'root'))){
+                return(preg_replace("/".preg_quote($item['path'],'/')."/", "", $fullPath));
+            }
+        }
+        return(NULL);
+    }
+
+
+    /*! \brief  Extracts the releaes path out of a path.
+     *          e.g. /debian/squeeze/test/module -> /debian/squeeze
+     */
+    function getReleasePath($fullPath)
+    {
+        $fullPath.='/';
+        while(preg_match("/\//", $fullPath)){
+            $fullPath = preg_replace("/\/[^\/]*$/","", $fullPath);
+            $item = $this->dataModel->getItemByPath($fullPath);
+            if($item['type'] == 'Release'){
+                return($fullPath);
+            }
+        }
+        return(NULL);
+    }
+  
+    
+    /*! \brief  Extracts the distribution path out of a path.
+     *          e.g. /root/debian/squeeze/test/module -> /root/debian
+     */
+    function getDistributionPath($fullPath)
+    {
+        $fullPath.='/';
+        while(preg_match("/\//", $fullPath)){
+            $fullPath = preg_replace("/\/[^\/]*$/","", $fullPath);
+            $item = $this->dataModel->getItemByPath($fullPath);
+            if($item['type'] == 'Distribution'){
+                return($fullPath);
+            }
+        }
+        return(NULL);
+    }
+
+    
+    /*! \brief  Extracts the release-part out of a path.
+     *          e.g. /root/debian/squeeze/test/module -> squeeze/test
+     */
+    function getReleasePart($path)
+    {
+        $rPath = $this->getReleasePath($path);
+        $dPath = $this->getDistributionPath($path);
+        return(preg_replace("/^".preg_quote($dPath, '/')."\/?/", "", $rPath));
+    }
+    function saveItemChanges()
+    {
+        // Save template engine modifications and validate values.
+        $this->TemplateEngine->save_object();
+        $msgs = $this->TemplateEngine->check();
+
+        // Get values to be saved
+        $values = array();
+        foreach($this->TemplateEngine->getWidgets() as $w){
+            $values[$w->getName()] = $w->getValue();
+        }
+           
+        // No input error were found, now check that we do not use the same name twice.
+        if(!count($msgs)){
+            $usedNames = $this->getUsedNamesForPath($this->selectedContainer);
+
+            // Allow the item to keep its name.
+            if($this->currentObject != NULL && isset($this->currentObject['values']['name'])){
+                $usedNames = array_remove_entries(array($this->currentObject['values']['name']), $usedNames);
+            }
+            if(in_array($values['name'],$usedNames)){
+                $msgs[] = msgPool::duplicated(_("Name"));
+            }
+        }
+
+        // Display errors
+        if(count($msgs)){
+            msg_dialog::displayChecks($msgs);
+            return;
+        }
+
+        // Get the item type to be saved
+        $item = $this->currentObject;
+        $type = $this->TemplateEngine->getItemType();
+        if($this->cfgItemMap[$type] == 'root'){
+
+            // We've to create a new distribution
+            if($type == 'Distribution'){
+                $name = $values['name'];
+                $itype = $values['installation_type'];
+                $imethod = $values['installation_method'];
+                $mirror = $values['mirror'];
+
+                // Initiate the rpc request.
+                $rpc = $this->config->getRpcHandle();
+                $res = $rpc->createDistribution($name, $itype, array('mirror'=>$mirror, 'install_method' => $imethod));
+                if(!$rpc->success()){
+                    msg_dialog::display(_("Error"), sprintf(_("Failed to save distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
+                    return(NULL);
+                }else{
+
+                    // We've successfully added the item, now add it to the tree.
+                    $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],array(), '-' );
+
+                    // Finally - close the dialog. 
+                    $this->listing->clearDialogObject();
+                }
+                
+
+                $this->listing->clearDialogObject();
+
+            }else{
+
+                echo "{$type} Cannot be saved yet";
+                $this->listing->clearDialogObject();
+                return;
+            }
+        }
+
+        // Save a CONFIG-ITEM object.
+        if($this->cfgItemMap[$type] != 'root'){
+
+            // Get paths 
+            $release = preg_replace("/^.*\//","", $this->getReleasePath($this->selectedContainer));
+            $newPath = $this->selectedContainer."/".$values['name'];
+            $newItemPath = $this->getItemPath($this->selectedContainer)."/".$values['name'];
+            if($item){
+                $oldPath = $item['path'];
+                $oldItemPath = $this->getItemPath($item['path']);
+            }
+
+            // If this is a new item, then create it now.
+            if($item == NULL){
+
+                // Add the new item
+                $rpc = $this->config->getRpcHandle();
+                $res = $rpc->setConfigItem($release, $newItemPath, $type, $values);
+                if(!$rpc->success()){
+                    msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
+                    return(NULL);
+                }else{
+
+                    // We've successfully added the item, now add it to the tree.
+                    $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],array(), '-' );
+
+                    // Finally - close the dialog. 
+                    $this->listing->clearDialogObject();
+                }
+            }else{
+
+                // Write the modifications back to the server.
+                $rpc = $this->config->getRpcHandle();
+                $res = $rpc->setConfigItem($release, $oldItemPath, $type, $values);
+                if(!$rpc->success()){
+                    msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
+                    return(NULL);
+                }else{
+            
+                    // Update the data model
+                    $this->dataModel->setItemValues($oldPath, $values);
+                    if($oldPath != $newPath){
+                        $this->dataModel->moveItem($oldPath, $newPath);
+                    }
+                    $this->listing->clearDialogObject();
+                }
+            }
+        }
+    }
+    function remove_lock() {}
 }
+
+
 ?>