Code

Removed debug output
[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     var $initFailed = TRUE;
23     var $initialized = FALSE;
24     var $errorMessage = "";
27     /*! \brief  Initialize the plugin and finally update the data model.
28      */
29     function __construct($config, $dn)
30     {
31         $this->config = &$config;
32         $this->listing = new ConfigManagementListing($this->config, get_userinfo(), $this);
34         // Load the template engine and tell her what template
35         //  to use for the HTML it produces.
36         $this->TemplateEngine = new TemplateEngine($config);
37         $this->installationMethods = json_decode(file_get_contents(get_template_path('goto/Config/root.json', TRUE)), TRUE);
38     }
40     
41     function init()
42     {
43         $success = TRUE;
44         $success &= $this->loadInstallationMethods();
45         $success &= $this->updateDataModel();
46         $this->initFailed = !$success;
47         if($success){
48             $this->initialized = TRUE;
49             $this->listing->setListingTypes($this->getListingTypes());
50             $this->setCurrentContainer('/root');
51         }
52     }
55     /*! \brief  Intializes this plugin
56      *          All available installation methods will be loaded
57      */
58     function loadInstallationMethods()
59     {
60         // Load configuration via rpc.
61         $rpc = $this->config->getRpcHandle();
62         $res = $rpc->getSupportedInstallMethods();
63         if(!$rpc->success()){
64             $this->errorMessage = $rpc->get_error();;
65             return(FALSE);
66         }
68         // Populate install methods on success.
69         if(!count($res)){
70             $this->errorMessage = _("No selectable install methods returned!");
71             return(FALSE);
72         }else{
74             // Merge result with hard coded methods
75             $this->installationMethods = array_merge($this->installationMethods, $res);
77             // Walk through entries and create useful mappings.
78             $this->cfgItemMap = array();
79             $this->itemConfig = array();
80             $this->itemsPerMethod = array();
81             $rootElements = array();
82             foreach($this->installationMethods as $method => $items){
83                 foreach($items['items'] as $itemName => $item){
84                     $this->itemsPerMethod[$method][] = $itemName;
85                     $this->cfgItemMap[$itemName] = $method;
86                     $this->itemConfig[$itemName] = &$this->installationMethods[$method]['items'][$itemName];
87  
88                     // This enables us to create the first level of config items when 
89                     //  a release is selected.
90                     if($item['name'] == "/" && $itemName != 'root'){
91                         $rootElements = array_merge($rootElements, $item['container']);
92                     }
93                 }
94             }
96             // Merge in root elements to releases.
97             foreach($this->itemConfig as $item => $data){
98                 if(in_array('__CFG_ITEMS__', $data['container'])){
99                     $this->itemConfig[$item]['container'] = array_merge($this->itemConfig[$item]['container'], $rootElements );
100                 }
101             }
102         }
103         return(TRUE);
104     }
107     /*! \brief  Updates all distributions, releases, packages and items in the dataModel
108      *          Load information from the backend.
109      */
110     function updateDataModel()
111     {
112         // Recreate the data model, to have a clean and fresh instance.
113         $this->dataModel = new ConfigManagementDataModel();
116         // Load templates from the backend and append them on the base 
117         $rpc = $this->config->getRpcHandle();
118         $res = $rpc->installListTemplates();
119         if(!$rpc->success()){
120             $this->errorMessage = sprintf(_("Failed to load templates: %s"), $rpc->get_error());
121             return(FALSE);
122         } 
123         foreach($res as $tName => $tData){
124             $tData['name'] = $tName;
125             $this->dataModel->addItem('Template','/root', $tName, $tData, '-');
126         }
129         // Load distributions 
130         $rpc = $this->config->getRpcHandle();
131         $res = $rpc->getDistributions();
132         if(!$rpc->success()){
133             $this->errorMessage = sprintf(_("Failed to load distributions: %s"), $rpc->get_error());
134             return(FALSE);
135         }else{
136             if(is_array($res)){
138                 foreach($res as $dist){
139            
140                     // Simple strings 
141                     $values = array();
142                     foreach(array('origin','installation_method', 'installation_method','debian_security',
143                             'debian_volatile', 'name', 'mirror_sources', 'managed', 'path') as $attr){
144                         $values[$attr] = $dist[$attr];
145                     }
147                     // Boxed strings
148                     foreach(array('type') as $attr){
149                         $values[$attr] = $dist[$attr]['name'];
150                     }
152                     // Arrays
153                     foreach(array('releases', 'architectures', 'components', 'sections') as $attr){
154                         $values[$attr] = array();
155                         if(is_array($dist[$attr])){
156                             foreach($dist[$attr] as $aEntry){
157                                 $values[$attr][] = $aEntry['name'];
158                             }
159                         }
160                     }
161         
162                     $this->dataModel->addItem('Distribution','/root', $dist['name'], $values);
164                     if(isset($dist['releases'])){
166                         // Sort releases by name length
167                         $sort = array();
168                         foreach($dist['releases'] as $id => $release){
169                             $sort[strlen($release['name']) . $release['name']]  = $id;
170                         }
171                         uksort($sort, "strnatcasecmp");   
173                         // Append release tags
174                         foreach($sort as $id){
175                             $release = $dist['releases'][$id];
176                             $rPath = $release['name'];
177                             $rPath = "/root/{$dist['name']}/$rPath";
178                             $rName = preg_replace("/^.*\//","", $rPath);
179                             $rPath = preg_replace("/\/[^\/]*$/","", $rPath);
180                             $values = array('name' => $rName);
182                             if(!$this->dataModel->itemExistsByPath($rPath)){
183                                 trigger_error("Invalid release name '{$rName}' in path '{$rPath}' received! Skipping entry!");
184                             }else{
185                                 $id = $this->dataModel->addItem('Release',$rPath, $rName, $values);
186                             }
187                         }
188                     }
189                 }
190             }
191         }
192         return(TRUE);
193     }
196     /*! \brief  Keep track of posted values and populate those 
197      *           which are interesting for us.
198      *          Inspects the _POST and _GET values.
199      */
200     function save_object()
201     {
202         // Update the listing class, this is necessary to get post
203         //  actions from it.
204         $this->listing->save_object();
206         // Get the selected distribution and release from the listing widget.
207         $cont = $this->listing->getSelectedContainer();
208         if(isset($_POST['ROOT'])){
209             $this->setCurrentContainer('/root');
210         }elseif(isset($_POST['BACK'])){
211             $path = $this->selectedContainer;
212             if($this->dataModel->itemExistsByPath($path)){
213                 $data = $this->dataModel->getItemByPath($path);
214                 if($data['parentPath']){
215                     $this->setCurrentContainer($data['parentPath']);
216                 }
217             }
218         }else{
219             $this->setCurrentContainer($cont);
220         }
221     }
224     /*! \brief  Load extended sub-objecte like 'config items' or 'packages'
225      *           for the given release path.
226      *  @param  String  The release path to load sub-objects for.
227      *  @return NULL 
228      */
229     function updateItemList($path)
230     {
231         // Fist get Item and check if it is an release 
232         if($this->dataModel->itemExistsByPath($path)){
233             $data = $this->dataModel->getItemByPath($path);
235             // Only releases can contain config-items.
236             if($data['type'] == 'Release' && $data['status'] != "fetched"){
238                 // Request all config items for the selected release via rpc.
239                 $rpc = $this->config->getRpcHandle();
240                 $releasePath = $this->getReleasePart($path);
241                 $res = $rpc->listConfigItems($releasePath);
242                 if(!$rpc->success()){
243                     msg_dialog::display(_("Error"),sprintf(_("Failed to load distributions: %s"),$rpc->get_error()),ERROR_DIALOG);
244                     return;
245                 }else{
246             
247                     if(!$res) return;
249                     // Sort entries by path length 
250                     $sLen = array();
251                     foreach($res as $itemPath => $type){
252                         $sLen[strlen($itemPath)."_".$itemPath] = $itemPath;
253                     }
254                     uksort($sLen, "strnatcasecmp");   
256                     // Walk through each entry and then try to add it to the model
257                     foreach($sLen as $unused => $itemPath){
259                         // Do not add the root element '/'
260                         if($itemPath == "/") continue;
262                         $type = $res[$itemPath];
263                 
264                         // Append the items-path to the current path to create the 
265                         //  effective item path in the data model.
266                         $targetPath = trim($path."/".$itemPath);
268                         // Remove trailing and duplicated slashes
269                         $targetPath = rtrim($targetPath, '/');
270                         $targetPath = preg_replace("/\/\/*/","/", $targetPath);
272                         // Extract the items name
273                         $name = preg_replace("/^.*\//","", $targetPath);
274     
275                         // Cleanup the path and then add the item.
276                         $targetPath = preg_replace("/[^\/]*$/","", $targetPath);
277                         $targetPath = rtrim($targetPath,'/');
278                         $this->dataModel->addItem($type, $targetPath, $name,array(),'-' ); 
279                     }
280                     $this->dataModel->setItemStatus($path, 'fetched');
281                 }
282             }
283         }
284     }
287     /*! \brief  Sets the currently selected container and item path. 
288      *  @param  String  The path of the container to set.
289      *  @param  String  The path of the item to set.
290      *  @return 
291      */
292     function setCurrentContainer($cont)
293     {
294         // Do nothing while the service wasn't initialized.
295         if(!$this->initialized) return;
297         $this->selectedContainer = $cont;
299         // Update list of items within the selected container. 
300         $this->updateItemList($this->selectedContainer);
302         // Transfer checked values back to the listing class.
303         $this->listing->setContainers($this->getContainerList());
304         $this->listing->setContainer($cont);
306         // Update the list of addable sub objects
307         $this->addableContainerItems = $this->getAddableContainersPerPath($cont);
308     }
311     function getAddableContainersPerPath($path)
312     {
313         $currentItem = $this->dataModel->getItemByPath($path);
314         $method = $this->getInstallationMethodPerPath($path);
316         // Get allowed items for the currently selected method 
317         //  merge in root elements, they are allowed everywhere.
318         $allowedItems = $this->itemsPerMethod[$method];
319         $allowedItems = array_merge($allowedItems, $this->itemsPerMethod['root']);
321         // Get addable items
322         $possibleItems = $this->itemConfig[$currentItem['type']]['container'];
323         return(array_unique(array_intersect($allowedItems, $possibleItems)));
324     }
326     
327     function getInstallationMethodPerPath($path)
328     {
329         $path .= '/';
330         while(preg_match("/\//", $path)){
331             $path = preg_replace("/\/[^\/]*$/","",$path);
332             $item = $this->dataModel->getItemByPath($path);
333             if(isset($item['values']['installation_method'])){
334                 return($item['values']['installation_method']);
335             }
336         }
337         return('root'); 
338     }
341     /*! \brief  Generate the HTML content for this plugin.
342      *          Actually renders the listing widget..
343      */
344     function execute()
345     {
346         // Request an update of the data model
347         if(!$this->initialized){
348             $this->init();
349         }
351         // Act on init fails
352         if($this->initFailed){
353             $smarty = get_smarty();
354             $smarty->assign('error', $this->errorMessage);
355             return($smarty->fetch(get_template_path('rpcError.tpl', TRUE)));
356         }else{
358             // Get the selected release and store it in a session variable
359             //  to allow the configFilter to access it and display the
360             //  packages and items.
361             $res = $this->listing->execute();
362             $this->listing->setListingTypes($this->getListingTypes());
363             return($res);
364         }
365     }
368     /*! \brief      Returns a list of items which will then be displayed 
369      *               in the management-list. 
370      *              (The management class calls this method from its execute())
371      *  @return     Array   A list of items/objects for the listing. 
372      */
373     function getItemsToBeDisplayed()
374     {
375         $path = $this->selectedContainer;
376         $item = $this->dataModel->getItemByPath($path);
377         return($item);
378     }
381     /*! \brief  Returns a simply list of all distributions.
382      *          This list will then be used to generate the entries of the 
383      *           ItemSelectors in the listing class.
384      */
385     function getContainerList()
386     {
387         $data = $this->dataModel->getItemByPath('/root');
388         $res = array();
389         $res["/root"] = array("name" => "/", "desc" => "");
390         $res = array_merge($res,$this->__recurseItem($data));
391         return($res);
392     }
395     /*! \brief  Recursivly wlks through an item and collects all path and name info.
396      *          The reult can then be used to fill the ItemSelector.
397      *  @param  Array   The Item to recurse. 
398      *  @param  Array   The type of of objects to collect. 
399      *  @param  String  The parent path prefix which should be removed.
400      *  @return Array   An array containing Array[path] = name
401      */
402     function __recurseItem($item, $parent = "")
403     {
404         $res = array();
405         $path = preg_replace("/".preg_quote($parent,'/')."/","",$item['path']);
406         $res[$path] = array('name' => $item['name'],'desc'=>$item['type']);
407         if(count($item['children'])){
408             foreach($item['children'] as $child){
409                 $res = array_merge($res, $this->__recurseItem($child, $parent));
410             }
411         }
412         return($res);
413     }
416     /*! \brief   Returns a info list about all items we can manage,
417      *            this used to fill the listings <objectType> settings.
418      *  @return Array   An array with item info.
419      */
420     function getListingTypes()
421     {
422         $types= array();
423         $types['Distribution']['objectClass'] = 'Distribution';
424         $types['Distribution']['label'] = _('Distribution');
425         $types['Distribution']['image'] = 'images/lists/edit.png';
426         $types['Distribution']['category'] = 'Device';
427         $types['Distribution']['class'] = 'Device';
429         $types['Release']['objectClass'] = 'Release';
430         $types['Release']['label'] = _('Release');
431         $types['Release']['image'] = 'images/lists/delete.png';
432         $types['Release']['category'] = 'Device';
433         $types['Release']['class'] = 'Device';
435         $types['Component']['objectClass'] = 'Component';
436         $types['Component']['label'] = _('Component');
437         $types['Component']['image'] = 'plugins/users/images/select_user.png';
438         $types['Component']['category'] = 'Device';
439         $types['Component']['class'] = 'Device';
441         foreach($this->installationMethods as $method => $items){
442             foreach($items['items'] as $itemName => $item){
443                 $types[$itemName]['objectClass'] = $itemName;
444                 $types[$itemName]['label'] = $item['name'];
445                 $types[$itemName]['image'] = 'plugins/fai/images/fai_script.png';
446                 $types[$itemName]['category'] = 'Device';
447                 $types[$itemName]['class'] = 'Device';
448             }
449         }
451         return($types);
452     }
455     /*! \brief      The plugins ACL and plugin-property definition. 
456      *  @return 
457      */
458     public static function plInfo()
459     {
460         return (array(
461                     "plShortName"   => _("Config management"),
462                     "plDescription" => _("Config management"),
463                     "plSelfModify"  => FALSE,
464                     "plDepends"     => array(),
465                     "plPriority"    => 0,
466                     "plSection"     => array("administration"),
467                     "plCategory"    => array(
468                         "newConfigManagement" => array("description"  => _("Config management"),
469                             "objectClass"  => "FAKE_OC_newConfigManagement")),
470                     "plProvidedAcls"=> array()
471                     ));
472     }
475     /*! \brief  Acts on open requests.
476      *          (This action is received from the ConfigManagementListing class.)
477      *  @param  Array   The items ids. (May contain multiple ids)
478      *  @return
479      */
480     function openEntry($ids)
481     {
482         $id = $ids[0];
483         $item = $this->dataModel->getItemById($id);
484         $this->setCurrentContainer($item['path']);
485         return;
486     }
490     /*! \brief  Removes an entry from the listing.
491      */
492     function removeEntry($ids)
493     {
494         foreach($ids as $id){
495             $item = $this->dataModel->getItemById($id);
497             // Is an config item.
498             if($this->cfgItemMap[$item['type']] != 'root'){
499                 $release = $this->getReleasePart($item['path']);
500                 $path = $this->getItemPath($item['path']);
501                 $rpc = $this->config->getRpcHandle();
502                 $rpc->removeConfigItem($release, $path);
503                 if(!$rpc->success()){
504                     msg_dialog::display(_("Error"), sprintf(_("Failed to remove: %s"), $rpc->get_error()),ERROR_DIALOG);
505                     return(NULL);
506                 }else{
507                     $this->dataModel->removeItem($item['path']);
508                 }
509             }else{
511                 // Remove distribution
512                 if($item['type'] == 'Distribution'){
514                     $dist = $this->getDistributionPart($item['path']);
515                     $rpc = $this->config->getRpcHandle();
516                     $rpc->removeDistribution($dist, array('recursive' => TRUE));
517                     if(!$rpc->success()){
518                         msg_dialog::display(_("Error"), sprintf(_("Failed to remove the distribution: %s. Error was: %s"), 
519                                     $dist, $rpc->get_error()), ERROR_DIALOG);
520                         return(NULL);
521                     }else{
522                         $this->dataModel->removeItem($item['path']);
523                     }
524                 }elseif($item['type'] == 'Release'){
526                     // Remove release
527                     $release = preg_replace("/^.*\//","", $this->getReleasePart($item['path']));
528                     $rpc = $this->config->getRpcHandle();
529                     $rpc->removeRelease($release, array('recursive' => TRUE));
530                     if(!$rpc->success()){
531                         msg_dialog::display(_("Error"), sprintf(_("Failed to remove the release: %s. Error was: %s"), 
532                                     $release, $rpc->get_error()),ERROR_DIALOG);
533                         return(NULL);
534                     }else{
535                         $this->dataModel->removeItem($item['path']);
536                     }
538                 }else{
539                     trigger_error($item['type']." - are not handled yet!");
540                 }
541             }
542         }
543     }
546     /*! \brief  Returns a list of used item names for a given path.
547      */
548     function getUsedNamesForPath($path)
549     {
550         $item = $this->dataModel->getItemByPath($path);
551         $names = array();
552         foreach($item['children'] as $path => $data){
553             $names[] = $data['name'];
554         }
555         return($names);
556     }
559     /*! \brief      Edits a selected list item.
560      */
561     function editEntry($ids)
562     {
563         $item = $this->dataModel->getItemById($ids[0]);
564         $release = $this->getReleasePart($item['path']);
565         $path = $this->getItemPath($item['path']);
566         $method = $this->cfgItemMap[$item['type']];
568         // Load item values on demand
569         if($this->cfgItemMap[$item['type']] != 'root'){
570             if($item['status'] == '-'){
571                 $rpc = $this->config->getRpcHandle();
572                 $res = $rpc->getConfigItem($release, $path);
573                 if(!$rpc->success()){
574                     msg_dialog::display(_("Error"), sprintf(_("Failed to load config item details: %s"), $rpc->get_error()),ERROR_DIALOG);
575                     return;
576                 }else{
577                     $item['values'] = $res;
578                     $this->dataModel->setItemStatus($item['path'], 'fetched');
579                     $this->dataModel->setItemValues($item['path'], $item['values']);
580                 }
581             }
582         }elseif($item['type'] == 'Template'){
583             if($item['status'] == '-'){
584                 $rpc = $this->config->getRpcHandle();
585                 $res = $rpc->installGetTemplate($item['name']);
586                 if(!$rpc->success()){
587                     msg_dialog::display(_("Error"), sprintf(_("Failed to load template details: %s"), $rpc->get_error()),ERROR_DIALOG);
588                     return;
589                 }else{
590                     $item['values'] = $res;
591                     $this->dataModel->setItemStatus($item['path'], 'fetched');
592                     $this->dataModel->setItemValues($item['path'], $item['values']);
593                 }
594             }
595         }
597         $this->TemplateEngine->load($this->itemConfig);
598         $this->TemplateEngine->setTemplate($method.".tpl");
599         $this->TemplateEngine->editItem($item['type'],$item['values']);
600         $this->listing->setDialogObject($this->TemplateEngine);
601         $this->currentObject = $item;
602     }
605     /*! \brief  Initiates the creation of a new item
606      */
607     function newEntry($type)
608     {
609         // We've to add a config item
610         $this->TemplateEngine->load($this->itemConfig);
611         if($this->cfgItemMap[$type] != 'root'){
612             $method = $this->cfgItemMap[$type];
613             $this->TemplateEngine->setTemplate($method.".tpl");
614             $this->TemplateEngine->createItem($type,array());
615             $this->listing->setDialogObject($this->TemplateEngine);
616             $this->currentObject = NULL;
617         }else{
618             $this->TemplateEngine->setTemplate("root.tpl");
619             $this->TemplateEngine->createItem($type,array());
620             $this->listing->setDialogObject($this->TemplateEngine);
621             $this->currentObject = NULL;
622         }
623     }
626     /*! \brief  Extracts the item-path out of a path.
627      *          e.g. /debian/squeeze/test/module -> /test/module
628      */
629     function getItemPath($fullPath)
630     {
631         $fPath = $fullPath.'/';
632         while(preg_match("/\//", $fPath)){
633             $fPath = preg_replace("/\/[^\/]*$/","", $fPath);
634             $item = $this->dataModel->getItemByPath($fPath);
635             if(in_array($item['type'], array('Release', 'Distribution', 'root'))){
636                 return(preg_replace("/".preg_quote($item['path'],'/')."/", "", $fullPath));
637             }
638         }
639         return(NULL);
640     }
643     /*! \brief  Extracts the releaes path out of a path.
644      *          e.g. /debian/squeeze/test/module -> /debian/squeeze
645      */
646     function getReleasePath($fullPath)
647     {
648         $fullPath.='/';
649         while(preg_match("/\//", $fullPath)){
650             $fullPath = preg_replace("/\/[^\/]*$/","", $fullPath);
651             $item = $this->dataModel->getItemByPath($fullPath);
652             if($item['type'] == 'Release'){
653                 return($fullPath);
654             }
655         }
656         return(NULL);
657     }
658   
659     
660     /*! \brief  Extracts the distribution path out of a path.
661      *          e.g. /root/debian/squeeze/test/module -> /root/debian
662      */
663     function getDistributionPath($fullPath)
664     {
665         $fullPath.='/';
666         while(preg_match("/\//", $fullPath)){
667             $fullPath = preg_replace("/\/[^\/]*$/","", $fullPath);
668             $item = $this->dataModel->getItemByPath($fullPath);
669             if($item['type'] == 'Distribution'){
670                 return($fullPath);
671             }
672         }
673         return(NULL);
674     }
677     /*! \brief  Extracts the distribution-part out of a path.
678      *          e.g. /root/debian/squeeze/test/module -> debian
679      */
680     function getDistributionPart($fullPath)
681     {
682         return(trim(preg_replace("#^/root/#","", $this->getDistributionPath($fullPath)), '/'));
683     }
684     
685     
686     /*! \brief  Extracts the release-part out of a path.
687      *          e.g. /root/debian/squeeze/test/module -> squeeze/test
688      */
689     function getReleasePart($path)
690     {
691         $rPath = $this->getReleasePath($path);
692         $dPath = $this->getDistributionPath($path);
693         return(preg_replace("/^".preg_quote($dPath, '/')."\/?/", "", $rPath));
694     }
695  
696  
697     function saveItemChanges()
698     {
699         // Save template engine modifications and validate values.
700         $this->TemplateEngine->save_object();
701         $msgs = $this->TemplateEngine->check();
703         // Get values to be saved
704         $values = array();
705         foreach($this->TemplateEngine->getWidgets() as $w){
706             $values[$w->getName()] = $w->getValue();
707         }
708            
709         // No input error were found, now check that we do not use the same name twice
710         //  and that it is valid.
711         if(!count($msgs)){
713             // Get used item names for the current path
714             if($this->currentObject){
715     
716                 // Get used item names in the parent path.
717                 $usedNames = $this->getUsedNamesForPath($this->currentObject['parentPath']);
718             }else{
720                 // Get used items for the selected path.
721                 $usedNames = $this->getUsedNamesForPath($this->selectedContainer);
722             }
724             // Allow the item to keep its name.
725             if($this->currentObject != NULL && isset($this->currentObject['values']['name'])){
726                 $usedNames = array_remove_entries(array($this->currentObject['values']['name']), $usedNames);
727             }
728             if(in_array($values['name'],$usedNames)){
729                 $msgs[] = msgPool::duplicated(_("Name"));
730             #}elseif(preg_match("/[^a-z0-9\.]/i",$values['name'])){
731             #    $msgs[] = msgPool::invalid(_("Name"), $values['name'], '/[a-z0-9\.]/');
732             }
733         }
735         // Display errors
736         if(count($msgs)){
737             msg_dialog::displayChecks($msgs);
738             return;
739         }
741         // Get the item type to be saved
742         $item = $this->currentObject;
743         $type = $this->TemplateEngine->getItemType();
744         if($this->cfgItemMap[$type] == 'root'){
746             // We've to create a new distribution
747             if($type == 'Distribution'){
748                 
749                 // Distributions cannot be renamed!
750                 if(isset($item['name']) && $item['name'] != $values['name']){
751                     msg_dialog::displayChecks(array("Distributions cannot be renamed!"));
752                     return;
753                 }
755                 // Create a new distribution 
756                 if(!$item){
757                     $name = $values['name'];
758                     $itype = $values['installation_type'];
759                     $imethod = $values['installation_method'];
760                     $origin = $values['origin'];
762                     // Initiate the rpc request.
763                     $rpc = $this->config->getRpcHandle();
764                     $res = $rpc->createDistribution($name, $itype, array('mirror'=>$origin, 'install_method' => $imethod));
765                     if(!$rpc->success()){
766                         msg_dialog::display(_("Error"), sprintf(_("Failed to save distributions: %s"), 
767                             $rpc->get_error()),ERROR_DIALOG);
768                         return(NULL);
769                     }
770                 }
772                 // Collect distribution properties
773                 $data = array();
774                 $data['distribution'] = $values['name'];
775                 $data['arch'] = $values['architectures'];
776                 $data['component'] = $values['components'];
777                 $data['mirror_sources'] = $values['mirror_sources'];
779                 // Set distribution properties
780                 $rpc = $this->config->getRpcHandle();
781                 $rpc->setDistribution($data);
782                 if(!$rpc->success()){
783                     msg_dialog::display(_("Error"), sprintf(_("Failed to save distribution properties: %s"), 
784                                 $rpc->get_error()),ERROR_DIALOG);
785                     return(NULL);
786                 }
788                 // We've successfully added the item, now add it to the tree.
789                 $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],$values, '-' );
791                 // Finally - close the dialog. 
792                 $this->listing->clearDialogObject();
794             }elseif($type == 'Release'){
795            
796                 // We've to update a release. 
797                 if($item){
799                     // Check if we've to rename the item.
800                     $path = $this->getReleasePart($item['parentPath']);
801                     $curPath = $this->getReleasePart($item['path']);
802                     $newPath = trim($path."/".$values['name'], '/');
803                     if($curPath != $newPath){
804                         $rpc = $this->config->getRpcHandle();
805                         $res = $rpc->renameRelease($curPath, $newPath);
806                         if(!$rpc->success()){
807                             msg_dialog::display(_("Error"), sprintf(_("Failed to save release: %s"), $rpc->get_error()),ERROR_DIALOG);
808                             return(NULL);
809                         }else{
810                             $nP = $item['parentPath'].'/'.$values['name'];
811                             $this->dataModel->moveItem($item['path'], $nP);
812                             $this->dataModel->setItemValues($nP, $values);
813                             $this->listing->clearDialogObject();
814                         }
815                     }else{
816                         $this->listing->clearDialogObject();
817                     }
818                 
819  
820                 }else{
822                     // Build up the new release path.
823                     $name = $values['name'];
824                     $rPath = $this->getReleasePart($this->selectedContainer);
825                     $newPath = trim($rPath."/".$name, '/');
827                     // Detect the parent distribution
828                     $dist = $this->getDistributionPart($this->selectedContainer);
830                     // Initiate the rpc request.
831                     $rpc = $this->config->getRpcHandle();
832                     $res = $rpc->createRelease($dist, $newPath);
833                     if(!$rpc->success()){
834                         msg_dialog::display(_("Error"), sprintf(_("Failed to save release: %s"), $rpc->get_error()),ERROR_DIALOG);
835                         return(NULL);
836                     }else{
838                         // We've successfully added/saved the item, now add it to the tree.
839                         $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],$values, '-' );
840                         $this->listing->clearDialogObject();
841                     }
842                 }
843             }else{
844                 echo "{$type} Cannot be saved yet";
845                 $this->listing->clearDialogObject();
846                 return;
847             }
848         }
850         // Save a CONFIG-ITEM object.
851         if($this->cfgItemMap[$type] != 'root'){
853             // Get paths 
854             $release =  $this->getReleasePart($this->selectedContainer);
856             if($item){
857                 $oldPath = $item['path'];
858                 $oldItemPath = $this->getItemPath($item['path']);
859                 $newPath = $item['parentPath']."/".$values['name'];
860                 $newItemPath = $this->getItemPath($newPath);
861             }else{
862                 $newPath = $this->selectedContainer."/".$values['name'];
863                 $newItemPath = $this->getItemPath($this->selectedContainer)."/".$values['name'];
864             }
866             // If this is a new item, then create it now.
867             if($item == NULL){
869                 // Add the new item
870                 $rpc = $this->config->getRpcHandle();
871                 $res = $rpc->setConfigItem($release, $newItemPath, $type, $values);
872                 if(!$rpc->success()){
873                     msg_dialog::display(_("Error"), sprintf(_("Failed to save %s: %s"),$type, $rpc->get_error()),ERROR_DIALOG);
874                     return(NULL);
875                 }else{
877                     // We've successfully added the item, now add it to the tree.
878                     $this->dataModel->addItem($type, $this->selectedContainer, $values['name'],array(), '-' );
880                     // Finally - close the dialog. 
881                     $this->listing->clearDialogObject();
882                 }
883             }else{
885                 // Write the modifications back to the server.
886                 $rpc = $this->config->getRpcHandle();
887                 $res = $rpc->setConfigItem($release, $oldItemPath, $type, $values);
888                 if(!$rpc->success()){
889                     msg_dialog::display(_("Error"), sprintf(_("Failed to save config item: %s"), $rpc->get_error()),ERROR_DIALOG);
890                     return(NULL);
891                 }else{
892             
893                     // Update the data model
894                     $this->dataModel->setItemValues($oldPath, $values);
895                     if($oldPath != $newPath){
896                         $this->dataModel->moveItem($oldPath, $newPath);
897                     }
898                     $this->listing->clearDialogObject();
899                 }
900             }
901         }
902     }
903     function remove_lock() {}
907 ?>