Code

Updated release part detection
[gosa.git] / gosa-plugins / goto-ng / admin / newConfigManagement / class_newConfigManagement.inc
1 <?php
3 /*! \brief  This class allows to manage backend config items and packages.
4  */
5 class newConfigManagement extends plugin
6 {
7     var $initTime;
8     var $plHeadline = "Config management";
9     var $plDescription = "Config management";
11     var $selectedContainer;
13     var $dataModel = NULL;
14     var $listing = NULL;
16     var $cfgItemMap = NULL;
18     var $addableContainerItems = array();
19     var $currentObject = NULL;
20     var $itemsPerMethod = NULL;
22     /*! \brief  Initialize the plugin and finally update the data model.
23      */
24     function __construct($config, $dn)
25     {
26         $this->config = &$config;
27         $this->listing = new ConfigManagementListing($this->config, get_userinfo(), $this);
29         // Load the template engine and tell her what template
30         //  to use for the HTML it produces.
31         $this->TemplateEngine = new TemplateEngine($config);
33         // Preset item config - with Distribution and Release objects.
34         $items = array();
35         $items['root']['container'] = array('Distribution');
36         $items['root']['name'] = '/';
37         $items['root']['description'] = _('Root');
39         // Define distribution paramters.
40         $dOpt1 = array('description' => _('Name'), 'default' => '', 'value' => '', 'required' => true,
41                 'type' => 'string', 'display' => _('Name'));
42         $dOpt2 = array('description' => _('Distribution type'), 'default' => 'deb', 'value' => 'deb', 'required' => true,
43                 'type' => 'combobox', 'display' => _('Distribution type'), 'values' => array("deb" => 'deb', "rpm" => 'rpm'));
44         $dOpt3 = array('description' => _('Mirror Url'), 'default' => '', 'value' => '', 'required' => false,
45                 'type' => 'string', 'display' => _('Mirror Url'));
46         $dOpt4 = array('description' => _('Method'), 'default' => 'puppet', 'value' => 'puppet', 'required' => false,
47                 'type' => 'combobox', 'display' => _('Installation method'), 'values'=>array('puppet'=>_('Puppet')));
49         // Define release parameters
50         $rOpt1 = array('description' => _('Name'), 'default' => '', 'value' => '', 'required' => true,
51                 'type' => 'string', 'display' => _('Name'));
53         $items['Distribution']['container'] = array('Release');
54         $items['Distribution']['name'] = 'Distribution';
55         $items['Distribution']['description'] = _('Distribution');
56         $items['Distribution']['options']['name'] = $dOpt1;
57         $items['Distribution']['options']['mirror'] = $dOpt3;
58         $items['Distribution']['options']['installation_type'] = $dOpt2;
59         $items['Distribution']['options']['installation_method'] = $dOpt4;
61         $items['Release']['container'] = array('Release', '__CFG_ITEMS__');
62         $items['Release']['name'] = 'Release';
63         $items['Release']['description'] = _('Release');
64         $items['Release']['options']['name'] = $rOpt1;
66         $this->installationMethods = array();
67         $this->installationMethods['root']['description'] = _('root');
68         $this->installationMethods['root']['name'] = 'root';
69         $this->installationMethods['root']['title'] = _('root');
70         $this->installationMethods['root']['items']['Distribution'] = &$items['Distribution'];
71         $this->installationMethods['root']['items']['Release'] = &$items['Release'];
72         $this->installationMethods['root']['items']['root'] = &$items['root'];
74         // Request an update of the data model
75         $this->loadInstallationMethods();
76         $this->updateDataModel();
77         $this->listing->setListingTypes($this->getListingTypes());
78     }
81     /*! \brief  Intializes this plugin
82      *          All available installation methods will be loaded
83      */
84     function loadInstallationMethods()
85     {
86         // Reset erros
87         $this->rpcError = $this->initFailed = FALSE;
89         // Load configuration via rpc.
90         $rpc = $this->config->getRpcHandle();
91         $res = $rpc->getSupportedInstallMethods();
92         if(!$rpc->success()){
93             $this->rpcError = TRUE;
94             $this->errorMessage = $rpc->get_error();;
95             return;
96         }
98         // Populate install methods on success.
99         if(!count($res)){
100             $this->errorMessage = _("No selectable install methods returned!");
101             msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
102             $this->initFailed = TRUE;
103             return;
104         }else{
106             // Merge result with hard coded methods
107             $this->installationMethods = array_merge($this->installationMethods, $res);
109             // Walk through entries and create useful mappings.
110             $this->cfgItemMap = array();
111             $this->itemConfig = array();
112             $this->itemsPerMethod = array();
113             $rootElements = array();
114             foreach($this->installationMethods as $method => $items){
115                 foreach($items['items'] as $itemName => $item){
116                     $this->itemsPerMethod[$method][] = $itemName;
117                     $this->cfgItemMap[$itemName] = $method;
118                     $this->itemConfig[$itemName] = &$this->installationMethods[$method]['items'][$itemName];
119  
120                     // This enables us to create the first level of config items when 
121                     //  a release is selected.
122                     if($item['name'] == "/" && $itemName != 'root'){
123                         $rootElements = array_merge($rootElements, $item['container']);
124                     }
125                 }
126             }
128             // Merge in root elements to releases.
129             foreach($this->itemConfig as $item => $data){
130                 if(in_array('__CFG_ITEMS__', $data['container'])){
131                     $this->itemConfig[$item]['container'] = array_merge($this->itemConfig[$item]['container'], $rootElements );
132                 }
133             }
134         }
135     }
138     /*! \brief  Updates all distributions, releases, packages and items in the dataModel
139      *          Load information from the backend.
140      */
141     function updateDataModel()
142     {
143         // Recreate the data model, to have a clean and fresh instance.
144         $this->dataModel = new ConfigManagementDataModel();
146         // Load distributions 
147         $rpc = $this->config->getRpcHandle();
148         $res = $rpc->getDistributions();
149         if(!$rpc->success()){
150             msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
151             return(NULL);
152         }else{
153             foreach($res as $dist){
154                 $this->dataModel->addItem('Distribution','/root', $dist['name'], $dist);
156                 if(isset($dist['releases'])){
158                     // Sort releases by name length
159                     $sort = array();
160                     foreach($dist['releases'] as $id => $release){
161                         $sort[strlen($release['name']) . $release['name']]  = $id;
162                     }
163                     uksort($sort, "strnatcasecmp");   
165                     // Append release tags
166                     foreach($sort as $id){
167                         $release = $dist['releases'][$id];
168                         $names = preg_split("/\//", $release['name']);
169     
170                         $rPath = "";
171                         $distPath = "/root/{$dist['name']}";
172                         foreach($names as $rName){
173                             $rPath .= '/'.$rName;
174                             $this->dataModel->addItem('Release',$distPath, $rName, $release);
175                             $distPath .= $rPath;
176                         }
177                     }
178                 }
179             }
180         }
181     }
184     /*! \brief  Keep track of posted values and populate those 
185      *           which are interesting for us.
186      *          Inspects the _POST and _GET values.
187      */
188     function save_object()
189     {
190         // Update the listing class, this is necessary to get post
191         //  actions from it.
192         $this->listing->save_object();
194         // Get the selected distribution and release from the listing widget.
195         $cont = $this->listing->getSelectedContainer();
196         if(isset($_POST['ROOT'])){
197             $this->setCurrentContainer('/root');
198         }elseif(isset($_POST['BACK'])){
199             $path = $this->selectedContainer;
200             if($this->dataModel->itemExistsByPath($path)){
201                 $data = $this->dataModel->getItemByPath($path);
202                 if($data['parentPath']){
203                     $this->setCurrentContainer($data['parentPath']);
204                 }
205             }
206         }else{
207             $this->setCurrentContainer($cont);
208         }
209     }
212     /*! \brief  Load extended sub-objecte like 'config items' or 'packages'
213      *           for the given release path.
214      *  @param  String  The release path to load sub-objects for.
215      *  @return NULL 
216      */
217     function updateItemList($path)
218     {
219         // Fist get Item and check if it is an release 
220         if($this->dataModel->itemExistsByPath($path)){
221             $data = $this->dataModel->getItemByPath($path);
223             // Only releases can contain config-items.
224             if($data['type'] == 'Release' && $data['status'] != "fetched"){
227                 // Request all config items for the selected release via rpc.
228                 $rpc = $this->config->getRpcHandle();
229                 $releasePath = $this->getReleasePart($path);
230                 $res = $rpc->listConfigItems($releasePath);
231                 if(!$rpc->success()){
232                     msg_dialog::display(_("Error"),sprintf(_("Failed to load distributions: %s"),$rpc->get_error()),ERROR_DIALOG);
233                 }else{
234             
235                     if(!$res) return;
237                     // Sort entries by path length 
238                     $sLen = array();
239                     foreach($res as $itemPath => $type){
240                         $sLen[strlen($itemPath)."_".$itemPath] = $itemPath;
241                     }
242                     uksort($sLen, "strnatcasecmp");   
244                     // Walk through each entry and then try to add it to the model
245                     foreach($sLen as $unused => $itemPath){
247                         // Do not add the root element '/'
248                         if($itemPath == "/") continue;
250                         $type = $res[$itemPath];
251                 
252                         // Append the items-path to the current path to create the 
253                         //  effective item path in the data model.
254                         $targetPath = trim($path."/".$itemPath);
256                         // Remove trailing and duplicated slashes
257                         $targetPath = rtrim($targetPath, '/');
258                         $targetPath = preg_replace("/\/\/*/","/", $targetPath);
260                         // Extract the items name
261                         $name = preg_replace("/^.*\//","", $targetPath);
262     
263                         // Cleanup the path and then add the item.
264                         $targetPath = preg_replace("/[^\/]*$/","", $targetPath);
265                         $targetPath = rtrim($targetPath,'/');
266                         $this->dataModel->addItem($type, $targetPath, $name,array(),'-' ); 
267                     }
268                     $this->dataModel->setItemStatus($path, 'fetched');
269                 }
270             }
271         }
272     }
275     /*! \brief  Sets the currently selected container and item path. 
276      *  @param  String  The path of the container to set.
277      *  @param  String  The path of the item to set.
278      *  @return 
279      */
280     function setCurrentContainer($cont)
281     {
282         $this->selectedContainer = $cont;
284         // Update list of items within the selected container. 
285         $this->updateItemList($this->selectedContainer);
287         // Transfer checked values back to the listing class.
288         $this->listing->setContainers($this->getContainerList());
289         $this->listing->setContainer($cont);
291         // Update the list of addable sub objects
292         $this->addableContainerItems = $this->getAddableContainersPerPath($cont);
293     }
296     function getAddableContainersPerPath($path)
297     {
298         $currentItem = $this->dataModel->getItemByPath($path);
299         $method = $this->getInstallationMethodPerPath($path);
301         // Get allowed items for the currently selected method 
302         //  merge in root elements, they are allowed everywhere.
303         $allowedItems = $this->itemsPerMethod[$method];
304         $allowedItems = array_merge($allowedItems, $this->itemsPerMethod['root']);
306         // Get addable items
307         $possibleItems = $this->itemConfig[$currentItem['type']]['container'];
308         return(array_unique(array_intersect($allowedItems, $possibleItems)));
309     }
311     
312     function getInstallationMethodPerPath($path)
313     {
314         $path .= '/';
315         while(preg_match("/\//", $path)){
316             $path = preg_replace("/\/[^\/]*$/","",$path);
317             $item = $this->dataModel->getItemByPath($path);
318             if(isset($item['values']['installation_method'])){
319                 return($item['values']['installation_method']);
320             }
321         }
322         return('root'); 
323     }
326     /*! \brief  Generate the HTML content for this plugin.
327      *          Actually renders the listing widget..
328      */
329     function execute()
330     {
331         // Get the selected release and store it in a session variable
332         //  to allow the configFilter to access it and display the
333         //  packages and items.
334         $res = $this->listing->execute();
335         $this->listing->setListingTypes($this->getListingTypes());
336         return($res);
337     }
340     /*! \brief      Returns a list of items which will then be displayed 
341      *               in the management-list. 
342      *              (The management class calls this method from its execute())
343      *  @return     Array   A list of items/objects for the listing. 
344      */
345     function getItemsToBeDisplayed()
346     {
347         $path = $this->selectedContainer;
348         $item = $this->dataModel->getItemByPath($path);
349         return($item);
350     }
353     /*! \brief  Returns a simply list of all distributions.
354      *          This list will then be used to generate the entries of the 
355      *           ItemSelectors in the listing class.
356      */
357     function getContainerList()
358     {
359         $data = $this->dataModel->getItemByPath('/root');
360         $res = array();
361         $res["/root"] = array("name" => "/", "desc" => "");
362         $res = array_merge($res,$this->__recurseItem($data));
363         return($res);
364     }
367     /*! \brief  Recursivly wlks through an item and collects all path and name info.
368      *          The reult can then be used to fill the ItemSelector.
369      *  @param  Array   The Item to recurse. 
370      *  @param  Array   The type of of objects to collect. 
371      *  @param  String  The parent path prefix which should be removed.
372      *  @return Array   An array containing Array[path] = name
373      */
374     function __recurseItem($item, $parent = "")
375     {
376         $res = array();
377         $path = preg_replace("/".preg_quote($parent,'/')."/","",$item['path']);
378         $res[$path] = array('name' => $item['name'],'desc'=>$item['type']);
379         if(count($item['children'])){
380             foreach($item['children'] as $child){
381                 $res = array_merge($res, $this->__recurseItem($child, $parent));
382             }
383         }
384         return($res);
385     }
388     /*! \brief   Returns a info list about all items we can manage,
389      *            this used to fill the listings <objectType> settings.
390      *  @return Array   An array with item info.
391      */
392     function getListingTypes()
393     {
394         $types= array();
395         $types['Distribution']['objectClass'] = 'Distribution';
396         $types['Distribution']['label'] = _('Distribution');
397         $types['Distribution']['image'] = 'images/lists/edit.png';
398         $types['Distribution']['category'] = 'Device';
399         $types['Distribution']['class'] = 'Device';
401         $types['Release']['objectClass'] = 'Release';
402         $types['Release']['label'] = _('Release');
403         $types['Release']['image'] = 'images/lists/delete.png';
404         $types['Release']['category'] = 'Device';
405         $types['Release']['class'] = 'Device';
407         $types['Component']['objectClass'] = 'Component';
408         $types['Component']['label'] = _('Component');
409         $types['Component']['image'] = 'plugins/users/images/select_user.png';
410         $types['Component']['category'] = 'Device';
411         $types['Component']['class'] = 'Device';
413         foreach($this->installationMethods as $method => $items){
414             foreach($items['items'] as $itemName => $item){
415                 $types[$itemName]['objectClass'] = $itemName;
416                 $types[$itemName]['label'] = $item['name'];
417                 $types[$itemName]['image'] = 'plugins/fai/images/fai_script.png';
418                 $types[$itemName]['category'] = 'Device';
419                 $types[$itemName]['class'] = 'Device';
420             }
421         }
423         return($types);
424     }
427     /*! \brief      The plugins ACL and plugin-property definition. 
428      *  @return 
429      */
430     public static function plInfo()
431     {
432         return (array(
433                     "plShortName"   => _("Config management"),
434                     "plDescription" => _("Config management"),
435                     "plSelfModify"  => FALSE,
436                     "plDepends"     => array(),
437                     "plPriority"    => 0,
438                     "plSection"     => array("administration"),
439                     "plCategory"    => array(
440                         "newConfigManagement" => array("description"  => _("Config management"),
441                             "objectClass"  => "FAKE_OC_newConfigManagement")),
442                     "plProvidedAcls"=> array()
443                     ));
444     }
447     /*! \brief  Acts on open requests.
448      *          (This action is received from the ConfigManagementListing class.)
449      *  @param  Array   The items ids. (May contain multiple ids)
450      *  @return
451      */
452     function openEntry($ids)
453     {
454         $id = $ids[0];
455         $item = $this->dataModel->getItemById($id);
456         $this->setCurrentContainer($item['path']);
457         return;
458     }
462     /*! \brief  Removes an entry from the listing.
463      */
464     function removeEntry($ids)
465     {
466         foreach($ids as $id){
467             $item = $this->dataModel->getItemById($id);
469             // Is an config item.
470             if($this->cfgItemMap[$item['type']] != 'root'){
471                 $release = preg_replace("/^.*\//","", $this->getReleasePath($item['path']));
472                 $path = $this->getItemPath($item['path']);
474                 $rpc = $this->config->getRpcHandle();
475                 $rpc->removeConfigItem($release, $path);
476                 if(!$rpc->success()){
477                     msg_dialog::display(_("Error"), sprintf(_("Failed to remove: %s"), $rpc->get_error()),ERROR_DIALOG);
478                     return(NULL);
479                 }else{
480                     $this->dataModel->removeItem($item['path']);
481                 }
482             }else{
483                 echo $item['type']." - are not handled yet!";
484             }
485         }
486     }
488     function getUsedNamesForPath($path)
489     {
490         $item = $this->dataModel->getItemByPath($path);
491         $names = array();
492         foreach($item['children'] as $path => $data){
493             $names[] = $data['name'];
494         }
495         return($names);
496     }
499     /*! \brief      Edits a selected list item.
500      */
501     function editEntry($ids)
502     {
503         $item = $this->dataModel->getItemById($ids[0]);
504         $release = preg_replace("/^.*\//","", $this->getReleasePath($item['path']));
505         $path = $this->getItemPath($item['path']);
506         $method = $this->cfgItemMap[$item['type']];
508         // Load item values on demand
509         if($this->cfgItemMap[$item['type']] != 'root'){
510             if($item['status'] == '-'){
511                 $rpc = $this->config->getRpcHandle();
512                 $item['values'] = $rpc->getConfigItem($release, $path);
513                 $this->dataModel->setItemStatus($item['path'], 'fetched');
514                 $this->dataModel->setItemValues($item['path'], $item['values']);
515             }
516         }
518         $this->TemplateEngine->load($this->itemConfig);
519         $this->TemplateEngine->setTemplate($method.".tpl");
520         $this->TemplateEngine->setValues($item['type'],$item['values']);
521         $this->listing->setDialogObject($this->TemplateEngine);
522         $this->currentObject = $item;
523     }
526     /*! \brief  Initiates the creation of a new item
527      */
528     function newEntry($type)
529     {
530         // We've to add a config item
531         $this->TemplateEngine->load($this->itemConfig);
532         if($this->cfgItemMap[$type] != 'root'){
533             $method = $this->cfgItemMap[$type];
534             $this->TemplateEngine->setTemplate($method.".tpl");
535             $this->TemplateEngine->setValues($type,array());
536             $this->listing->setDialogObject($this->TemplateEngine);
537             $this->currentObject = NULL;
538         }else{
539             $this->TemplateEngine->setTemplate("root.tpl");
540             $this->TemplateEngine->setValues($type,array());
541             $this->listing->setDialogObject($this->TemplateEngine);
542             $this->currentObject = NULL;
543         }
544     }
547     /*! \brief  Extracts the item-path out of a path.
548      *          e.g. /debian/squeeze/test/module -> /test/module
549      */
550     function getItemPath($fullPath)
551     {
552         $fPath = $fullPath.'/';
553         while(preg_match("/\//", $fPath)){
554             $fPath = preg_replace("/\/[^\/]*$/","", $fPath);
555             $item = $this->dataModel->getItemByPath($fPath);
556             if(in_array($item['type'], array('Release', 'Distribution', 'root'))){
557                 return(preg_replace("/".preg_quote($item['path'],'/')."/", "", $fullPath));
558             }
559         }
560         return(NULL);
561     }
564     /*! \brief  Extracts the releaes path out of a path.
565      *          e.g. /debian/squeeze/test/module -> /debian/squeeze
566      */
567     function getReleasePath($fullPath)
568     {
569         $fullPath.='/';
570         while(preg_match("/\//", $fullPath)){
571             $fullPath = preg_replace("/\/[^\/]*$/","", $fullPath);
572             $item = $this->dataModel->getItemByPath($fullPath);
573             if($item['type'] == 'Release'){
574                 return($fullPath);
575             }
576         }
577         return(NULL);
578     }
579   
580     
581     /*! \brief  Extracts the distribution path out of a path.
582      *          e.g. /root/debian/squeeze/test/module -> /root/debian
583      */
584     function getDistributionPath($fullPath)
585     {
586         $fullPath.='/';
587         while(preg_match("/\//", $fullPath)){
588             $fullPath = preg_replace("/\/[^\/]*$/","", $fullPath);
589             $item = $this->dataModel->getItemByPath($fullPath);
590             if($item['type'] == 'Distribution'){
591                 return($fullPath);
592             }
593         }
594         return(NULL);
595     }
597     
598     /*! \brief  Extracts the release-part out of a path.
599      *          e.g. /root/debian/squeeze/test/module -> squeeze/test
600      */
601     function getReleasePart($path)
602     {
603         $rPath = $this->getReleasePath($path);
604         $dPath = $this->getDistributionPath($path);
605         return(preg_replace("/^".preg_quote($dPath, '/')."\/?/", "", $rPath));
606     }
607  
608  
609     function saveItemChanges()
610     {
611         // Save template engine modifications and validate values.
612         $this->TemplateEngine->save_object();
613         $msgs = $this->TemplateEngine->check();
615         // Get values to be saved
616         $values = array();
617         foreach($this->TemplateEngine->getWidgets() as $w){
618             $values[$w->getName()] = $w->getValue();
619         }
620            
621         // No input error were found, now check that we do not use the same name twice.
622         if(!count($msgs)){
623             $usedNames = $this->getUsedNamesForPath($this->selectedContainer);
625             // Allow the item to keep its name.
626             if($this->currentObject != NULL && isset($this->currentObject['values']['name'])){
627                 $usedNames = array_remove_entries(array($this->currentObject['values']['name']), $usedNames);
628             }
629             if(in_array($values['name'],$usedNames)){
630                 $msgs[] = msgPool::duplicated(_("Name"));
631             }
632         }
634         // Display errors
635         if(count($msgs)){
636             msg_dialog::displayChecks($msgs);
637             return;
638         }
640         // Get the item type to be saved
641         $item = $this->currentObject;
642         $type = $this->TemplateEngine->getItemType();
643         if($this->cfgItemMap[$type] == 'root'){
645             // We've to create a new distribution
646             if($type == 'Distribution'){
647                 $name = $values['name'];
648                 $itype = $values['installation_type'];
649                 $imethod = $values['installation_method'];
650                 $mirror = $values['mirror'];
652                 // Initiate the rpc request.
653                 $rpc = $this->config->getRpcHandle();
654                 $res = $rpc->createDistribution($name, $itype, array('mirror'=>$mirror, 'install_method' => $imethod));
655                 if(!$rpc->success()){
656                     msg_dialog::display(_("Error"), sprintf(_("Failed to save distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
657                     return(NULL);
658                 }else{
660                     // We've successfully added the item, now add it to the tree.
661                     $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],array(), '-' );
663                     // Finally - close the dialog. 
664                     $this->listing->clearDialogObject();
665                 }
666                 
668                 $this->listing->clearDialogObject();
670             }else{
672                 echo "{$type} Cannot be saved yet";
673                 $this->listing->clearDialogObject();
674                 return;
675             }
676         }
678         // Save a CONFIG-ITEM object.
679         if($this->cfgItemMap[$type] != 'root'){
681             // Get paths 
682             $release = preg_replace("/^.*\//","", $this->getReleasePath($this->selectedContainer));
683             $newPath = $this->selectedContainer."/".$values['name'];
684             $newItemPath = $this->getItemPath($this->selectedContainer)."/".$values['name'];
685             if($item){
686                 $oldPath = $item['path'];
687                 $oldItemPath = $this->getItemPath($item['path']);
688             }
690             // If this is a new item, then create it now.
691             if($item == NULL){
693                 // Add the new item
694                 $rpc = $this->config->getRpcHandle();
695                 $res = $rpc->setConfigItem($release, $newItemPath, $type, $values);
696                 if(!$rpc->success()){
697                     msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
698                     return(NULL);
699                 }else{
701                     // We've successfully added the item, now add it to the tree.
702                     $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],array(), '-' );
704                     // Finally - close the dialog. 
705                     $this->listing->clearDialogObject();
706                 }
707             }else{
709                 // Write the modifications back to the server.
710                 $rpc = $this->config->getRpcHandle();
711                 $res = $rpc->setConfigItem($release, $oldItemPath, $type, $values);
712                 if(!$rpc->success()){
713                     msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
714                     return(NULL);
715                 }else{
716             
717                     // Update the data model
718                     $this->dataModel->setItemValues($oldPath, $values);
719                     if($oldPath != $newPath){
720                         $this->dataModel->moveItem($oldPath, $newPath);
721                     }
722                     $this->listing->clearDialogObject();
723                 }
724             }
725         }
726     }
727     function remove_lock() {}
731 ?>