Code

Updated strings
[gosa.git] / gosa-plugins / goto / admin / ConfigManagement / class_ConfigManagement.inc
1 <?php
3 /*! \brief  A GOsa plugin which generates a device configuration dialog  
4  */
5 class ConfigManagement extends management
6 {
8     // Used to render the item-configuration dialog 
9     private $TemplateEngine = NULL;
11     // A list of all configured items for this device.
12     private $allConfiguredItems = array();
14     // The currently active item
15     // Add add and remove action will be performed on this item
16     private $currentItem = array();
17     
18     // A baseSelector which will be fed with a simulated 
19     //  department list. All entries will get a fake base
20     //  which can then be used to fill the baseSelector widget.
21     private $itemContainerSelector = NULL;
23     // The currently selected base within management list.
24     private $base ;
26     // This array contains a list of all item-types we can add 
27     //  to the currently selected item (currentItem) 
28     private $addableContainerItems = array();
30     // Due to the fakt that we use a fake 'base/dn' for all items
31     //  we've to map this 'base/dn' to the items 'id'.
32     private $mappingBaseToID = array();
34     private $rootItemID;
35     private $itemConfig = array();
36     private $lastItemID = 1;
38     private $rpcError = FALSE;
39     private $initFailed = FALSE;
40     private $invalidInstallMethod = FALSE;
41     private $errorMessage = "";
43     // Some plugin related memebers which are not member of 
44     //  the management class. See class plugin.
45     public $initTime;
46     public $ignore_account = FALSE;
47     public $pl_notify;
48     public $read_only;
50     public $allItemConfigurations = NULL;
52     /*! \brief  Constructs the device configuration plugin 
53      *  @param  Config  The GOsa configuration object.
54      */
55     function __construct(&$config, $dn)
56     {
57         // Load the template engine and tell her what template
58         //  to use for the HTML it produces.
59         $this->TemplateEngine = new TemplateEngine($config);
60         $this->TemplateEngine->setTemplate('puppet.tpl');
61         $this->config = $config;
63         // Set storage points - We do not have any - We just create a fake list which lists all items
64         $this->storagePoints = array("");
65         
66         // Try to initialize
67         $this->init();
68         $this->rebuildListing();
69     }
71     
72     /*! \brief  Sets the installation method to the given method.
73      *          Updates the template engine and adds the initial root 
74      *           object for the selected method.
75      *  @param  The method to use.
76      *  @return TRUE on success else FALSE. 
77      */
78     function setInstallMethod($str)
79     {
80         if(!isset($this->allItemConfigurations[$str])){
81             $this->itemConfig = array();
82             $this->invalidInstallMethod =TRUE;
83             $this->errorMessage = sprintf(_("Invalid installation method %s selected!"), bold($str));
84             msg_dialog::display(_("Setup"), $this->errorMessage, ERROR_DIALOG);
85             return(FALSE);
86         }else{
88             $this->itemConfig = $this->allItemConfigurations[$str]['items'];
89             $this->invalidInstallMethod =FALSE;
90             $this->TemplateEngine->load($this->itemConfig);
92             // Detect root item, its name is / 
93             $root = NULL;
94             foreach($this->itemConfig as $key => $item){
95                 if($item['name'] == '/') {
96                     $root = $key;
97                     break;
98                 }
99             }
100             if(!$root){
101                 $this->errorMessage = sprintf(_("Installation method %s is invalid: no root object found!"), bold($str));
102                 msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
103                 $this->initFailed = TRUE;
104                 $this->itemConfig = array();
105                 return(FALSE);
106             }
108             // Set current item to 'root', this is the minimum to get things running.
109             $idRoot = $this->addItem($root,'root',array());
110             $this->rootItemID = $idRoot;
111             $this->setCurrentItem($idRoot);
112             $this->setSelectedListItemID($idRoot);
113             $this->rebuildListing();
114             return(TRUE);
115         }
116     }
119     /*! \brief  Intializes this plugin
120      *          All available installation methods will be loaded
121      *           and populated.
122      */
123     function init()
124     {
125         // Reset erros
126         $this->rpcError = $this->initFailed = FALSE;
128         // Load configuration via rpc.
129         $rpc = $this->config->getRpcHandle();
131         // Populate install methods on success.
132         $res = $rpc->getSupportedInstallMethods();
133         if(!$rpc->success()){
134             $this->rpcError = TRUE;
135             $this->errorMessage = $rpc->get_error();;
136             return;
137         }       
138         $this->allItemConfigurations = $res;
139         if(!count($this->allItemConfigurations)){
140             $this->errorMessage = _("No selectable install methods available!");
141             msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
142             $this->initFailed = TRUE;
143             return;
144         }
145     }
148     /*! \brief      Add a new child-item to the currently selected one. 
149      *               
150      *  @param  String  type    The 'type' of the new object, eg. 'KickstartTemplate'
151      *  @param  String  name    The 'name' of the new object.
152      *  @param  Array   values  The initial values for this object.
153      *  @return 
154      */
155     function addItem($type,$name, $values = array())
156     {
157         if(!isset($this->itemConfig[$type])){
158             echo "Invalid type {$type}, skipping item!<br>";
159             return;
160         }
162         // Add missing values with the item-type defaults.
163         $allValuesSet = TRUE;
164         foreach($this->itemConfig[$type]['options'] as $oName => $oValue){
165             if(!isset($values[$oName])){
166                 $values[$oName] = (isset($oValue['default']))?$oValue['default']:"";
167             }
168         }
170         // Get the currently selected entry, its the parent for the newly 
171         //  added one. 
172         $current = &$this->currentItem; 
174         // Create a FAKE base to be able to use the management lists
175         //  which are currently ldap and thus dn based.
176         $base = (isset($current['base']))? ",".$current['base'] : '';
177         $base = "{$type}={$name}{$base}";
180         if(isset($this->mappingBaseToID[$base])){
181             echo "Cannot add entry, dn already in use! {$base}<br>";
182             return(null);
183         }
184     
185         // Get next free item slot.
186         $id = ($this->lastItemID ++);
187         $new = array(
188                 'base' => $base,
189                 'children' => array(),
190                 'id' => $id, 
191                 'type' => $type, 
192                 'name' => $name, 
193                 'values' => $values);
195         // Append the entry to the list of all items.
196         $this->allConfiguredItems[$id] = $new;
198         // Create a child referenc, this creates some kind of entry tree.
199         $current['children'][$id] = &$this->allConfiguredItems[$id];
201         // Add entries to the list of base and id mappings
202         //  this allows us to easily detect the base for an id and vice versa.
203         $this->mappingBaseToID[$id] = $base;
204         $this->mappingBaseToID[$base] = $id;
205         return($id);
206     }
209     /*! \brief      Selects an item as active.
210      *              All further add and remove actions will be performed
211      *               on the obejcts children.
212      *  @param  String  The 'id' of the item we want to select.
213      *  @return 
214      */
215     function setCurrentItem($item)
216     {
217         if(!isset($this->allConfiguredItems[$item])){
218             echo "Invalid item name {$name}! Skipping selection!";
219             return;
220         }
222         // Set the new item info.
223         $this->currentItem = &$this->allConfiguredItems[$item];
224         $this->currentItemType = $this->currentItem['type'];
225         $this->currentItemDescriptor = $this->itemConfig[$this->currentItem['type']];
226     }
229     /*! \brief      Removes a given item ID.
230      *  @param  String  The 'id' of the item we want to remove.
231      *  @return 
232      */
233     function removeItem($id, &$data = NULL)
234     {
235         if($data === NULL){
236             $data = &$this->allConfiguredItems;
237         }
239         // Remove the item and its children
240         if(isset($data[$id])){
241             foreach($data[$id]['children'] as $cid => $item){
242                 $this->removeItem($cid, $data);
243             }
244             unset($data[$id]);
245         }
246     
247         // Remove to current id from sub entries
248         foreach($data as $key => $item){
249             $this->removeItem($id, $data[$key]['children']);
250         }
251     }
254     /*! \brief      Initiate item edit.
255      *              An action send from the management list.
256      *  @param  See management::editEntry 
257      *  @return 
258      */
259     function editEntry($action="",$target=array(),$all=array(), 
260             $altTabClass ="", $altTabType = "", $altAclCategory="")
261     {
262         $this->setCurrentItem($target[0]);
263         $this->dialogObject = $this->TemplateEngine;
264         $this->skipFooter = TRUE;
265         $this->dialog = TRUE;
267         // Update the template engine to use another type of item and 
268         //  some other values.
269         $this->TemplateEngine->setValues($this->currentItemType,$this->currentItem['values']);
270     }
273     /*! \brief      Save changes for the currently edited item.
274      */
275     function saveItemChanges()
276     {
277         // Save eventually changed values
278         if($this->currentItem){
280             // Check if everything is fine.
281             $msgs = $this->TemplateEngine->save_object();
282             $msgs = $this->TemplateEngine->check();
283             if(count($msgs)){
284                 msg_dialog::displayChecks($msgs);
285             }else{
286                 foreach($this->TemplateEngine->getWidgets() as $widget){
287                     $this->currentItem['values'][$widget->getName()] = $widget->getValue();
288                 }
289                 $this->closeDialogs();
290             }
291         }
292     }
295     /*! \brief      React on open requests from the management list 
296      */
297     function openEntry($action="",$target=array(),$all=array(), 
298             $altTabClass ="", $altTabType = "", $altAclCategory="")
299     {
300         $this->setSelectedListItemID($target[0]);
301     }
304     /*! \brief   Overridden render method of class mangement.
305      *            this allows us to add a release selection box.
306      */
307     function renderList()
308     {
309         // In case of an error abort here.
310         if($this->rpcError || $this->initFailed || $this->invalidInstallMethod){
311             $smarty = get_smarty();
312             $smarty->assign('initFailed', $this->initFailed);
313             $smarty->assign('rpcError', $this->rpcError);
314             $smarty->assign('invalidInstallMethod', $this->invalidInstallMethod);
315             $smarty->assign('error', $this->errorMessage);
316             return($smarty->fetch(get_template_path('failed.tpl', TRUE)));
317         }
319         // Collect item container list to be able to render the fake-base selector
320         if(!$this->itemContainerSelector){
321             $this->itemContainerSelector = new releaseSelector(
322                     $this->getContainerList(), 
323                     $this->base, 
324                     $this->allConfiguredItems[$this->rootItemID]['base']);
325         }else{
326             $this->itemContainerSelector->setBases($this->getContainerList());
327         }
328         $this->itemContainerSelector->update(true);
329         $this->itemContainerSelector->setBase($this->base);
331         session::set('DEVICE_ITEMS', $this->allConfiguredItems);
332         $this->rebuildListing();
333         $filter = $this->getFilter();
334         $headpage = $this->getHeadpage();
336         $headpage->update();
337         $smarty = get_smarty();
338         $smarty->assign("RELEASE", $this->itemContainerSelector->render());
339         $display = $headpage->render();
340         return($this->getHeader().$display);
341     }
344     /*! \brief   Build up a list of items useable for the itemSelector.
345      */
346     function getContainerList($array = NULL)
347     {
348         $array = ($array == NULL)?$this->allConfiguredItems[$this->rootItemID]: $array;
349         $ret[$array['base']] = $array['type'];
350         if(count($array['children'])){
351             foreach($array['children'] as $subItem){
352                 $ret = array_merge($ret, $this->getContainerList($subItem));
353             }
354         }
355         return($ret);    
356     }
359     /*! \brief   Update the management class and tell her which 
360      *            items are available for the itemSelector (baseSelector).
361      */
362     function rebuildListing()
363     {
364         // Build filter
365         if (session::global_is_set(get_class($this)."_filter")){
366             $filter= session::global_get(get_class($this)."_filter");
367         } else {
368             $filter = new filter(get_template_path("DeviceConfig-filter.xml", true));
369             $filter->setObjectStorage($this->storagePoints);
370         }
371         $this->setFilter($filter);
373         // Load service xml file and fill in placeholders
374         $contents =file_get_contents(get_template_path("DeviceConfig-list.xml", true));
376         // Build up device-list configuration   
377         $types ="";
378         $images = array();
379         $images[] = 'images/lists/edit.png';
380         $images[] = 'images/caps.png';
381         $images[] = 'images/lists/trash.png';
382         $images[] = 'images/filter.png';
383         $images[] = 'images/find.png';
384         $i = 0; 
385         foreach($this->itemConfig as $type => $item){
386             $desc = $item['description'];
387             $img = $images[$i++];
388             $types .= 
389                 "   <objectType>".
390                 "     <label>{$desc}</label>".
391                 "     <objectClass>{$type}</objectClass>".
392                 "     <category>Device</category>".
393                 "     <class>dummy</class>".
394                 "     <image>{$img}</image>".
395                 "   </objectType>";
396         }
397         $contents = preg_replace("/%TYPES%/", $types, $contents);
400         $items = "";
401         $i = 0;
402         foreach($this->addableContainerItems as $item){
403             $desc = $this->itemConfig[$item]['description'];
404             $img = $images[$i++];
405             $items .=
406                 "<action>".
407                 "    <name>add_{$item}</name>".
408                 "    <type>entry</type>".
409                 "    <image>{$img}</image>".
410                 "    <label>{$desc}</label>".
411                 "</action>";
412         }
414         if(!empty($items)){
415             $items = 
417                 "<action>".
418                 " <type>sub</type>".
419                 " <image>images/lists/element.png[new]</image>".
420                 " <label>Create</label>".
421                 " {$items}".
422                 "</action>";
423         }
425         $contents = preg_replace("/%ITEMS%/", $items, $contents);
427         $headpage = new listing($contents,TRUE);
428         $headpage->setBase($this->base);
429         $headpage->setFilter($filter);
431         parent::__construct($this->config, $this->ui, "services", $headpage);
433         // Register default actions
434         $this->registerAction("new",        "newEntry");
435         $this->registerAction("edit",       "openEntry"); // !! We forward 'edit' to 'open' to have a department like navigation.
436         $this->registerAction("editEntry",  "editEntry");
438         $this->registerAction("saveItemChanges", "saveItemChanges");
439         $this->registerAction("cancelItemEdit", "closeDialogs");
440         $this->registerAction("cancelItemAdd", "closeDialogs");
441         $this->registerAction("saveItemAdd", "saveItemAdd");
442         foreach($this->itemConfig as $name => $item){
443             $this->registerAction("add_{$name}", "newEntry");
444         }
445     }
448     /*! \brief  This method intiates the object creation.
449      *
450      *  @param  String  'action'  The name of the action which was the used as trigger.
451      *  @param  Array   'target'  A list of object dns, which should be affected by this method.
452      *  @param  Array   'all'     A combination of both 'action' and 'target'.
453      */
454     function newEntry($action="",$target=array(),$all=array(), 
455             $altTabClass ="", $altTabType = "", $altAclCategory="")
456     {
457         $toAdd = preg_replace("/^add_/", "",$action);
458         $itemToAdd = $this->itemConfig[$toAdd];
460         $this->dialogObject = new AddItemDialog($this->config,$toAdd,$itemToAdd);
461         $this->dialog = true;
462     }
464     
465     /*! \brief   Saves newly created items and adds them as child to 
466      *            the currently selected item.
467      */
468     function saveItemAdd()
469     {
470         if(!$this->dialogObject instanceOf AddItemDialog) return;
472         $msgs = $this->dialogObject->save_object();
473         $msgs = $this->dialogObject->check();
474         if(count($msgs)){
475             msg_dialog::displayChecks($msgs);
476         }else{
477             $itemName = $this->dialogObject->getName();
478             $itemCfg = $this->dialogObject->getItemCfg();
479             $itemType = $this->dialogObject->getItemType();
481             $this->setCurrentItem($this->mappingBaseToID[$this->base]);
482     
483             $this->addItem($itemType, $itemName);
484             $this->closeDialogs();
486 #           $this->setCurrentItem($itemName);
487 #           $this->dialogObject = $this->TemplateEngine;
488 #           $this->skipFooter = TRUE;
489 #           $this->dialog = TRUE;
491         }
492     }
495     /*! \brief  Keep track of posted values, some may be interesting for us. 
496      *          Tell the template engine to take care of posted values too.
497      *  @param  String
498      *  @return 
499      */
500     function save_object()
501     {
502         if(isset($_POST['retryInit'])){
503             $this->init();
504             return;
505         }
506             
507         // Do nothing else in case of an error
508         if($this->rpcError || $this->initFailed) return;
510         // Add sub-module requested.
511         if(isset($_POST['addSubModule']) && isset($_POST['subModule'])){
512             $sub = get_post('subModule');
513             if(in_array($sub, $this->currentItemDescriptor['container'])){
515                 // Check if this is a valid item
516                 if(!isset($this->itemConfig[$sub])) {
517                     echo "Invalid item type '{$sub}'!";
518                     $values = array();
519                 }else{
520                     $values = $this->itemConfig[$sub]['options'];
521                 }
522                 $name = 'test'.rand(0,99999);
523                 $this->addItem($sub,$name,$values);
524             }
525         }
527         // Get the selected item-id from the item list and populate it.
528         if($this->itemContainerSelector){
529             $this->itemContainerSelector->update();
530             $id  = $this->mappingBaseToID[$this->itemContainerSelector->getBase()]; 
531             $this->setSelectedListItemID($id);
532         }
533     }
536     /* \brief   Updates the currenlty seleted item in the management list
537      */   
538     function setSelectedListItemID($id)
539     {
540         $this->base = $this->mappingBaseToID[$id];
541         $type = $this->allConfiguredItems[$id]['type'];
542         $this->addableContainerItems = $this->itemConfig[$type]['container'];
543     }
546     /*! \brief    Forward plugin acls
547      */
548     function set_acl_base($base)
549     {
550         $this->acl_base = $base;
551     }
554     /*! \brief    Forward plugin acls
555      */
556     function set_acl_category($category)
557     {
558         $this->acl_category = $category;
559     }
561     function save()
562     {
563         foreach($this->allConfiguredItems as $name => $item){
564             foreach($item['values'] as $oName => $oValue){
565                 if(!is_array($oValue)) $oValue = array($oValue);
566                 foreach($oValue as $val){
567                     echo "<br>{$name} -- <i>{$item['type']}</i>: <b>{$oName}</b>: {$val}";
568                 }
569             }
570         }
571     }
574     /*! \brief  Initiates the removal for the given entries
575      *           and displays a confirmation dialog.
576      *
577      *  @param  String  'action'  The name of the action which was the used as trigger.
578      *  @param  Array   'target'  A list of object dns, which should be affected by this method.
579      *  @param  Array   'all'     A combination of both 'action' and 'target'.
580      */
581     protected function removeEntryRequested($action="",$target=array(),$all=array())
582     {
583         foreach($target as $id){
584             $this->removeItem($id);
585         }
586     }
588     
589     // Inject user actions
590     function detectPostActions()
591     {
592         if($this->rpcError || $this->initFailed) return(array('action' => ''));
594         $action = management::detectPostActions();
595         if(isset($_POST['saveItemEdit'])) $action['action'] = "saveItemChanges";
596         if(isset($_POST['saveItemAdd'])) $action['action'] = "saveItemAdd";
597         if(isset($_POST['cancelItemEdit'])) $action['action'] = "cancelItemEdit";
598         if(isset($_POST['cancelItemAdd'])) $action['action'] = "cancelItemAdd";
599         return($action);
600     }
602     
603     function closeDialogs()
604     {
605         parent::closeDialogs();
606         $this->dialog = false;
607     }
608    
609  
610     function check()
611     {
612         return(array());
613     }
615     function getRootItemId()
616     {
617         return($this->rootItemID);
618     }
621     public static function plInfo()
622     {
623         return (array(
624                     "plShortName"   => _("Config management"),
625                     "plDescription" => _("Config management"),
626                     "plSelfModify"  => FALSE,
627                     "plDepends"     => array(),
628                     "plPriority"    => 0,
629                     "plSection"     => array("administration"),
630                     "plCategory"    => array(
631                         "ConfigManagement" => array("description"  => _("Config management"),
632                             "objectClass"  => "FAKE_OC_ConfigManagement")),
633                     "plProvidedAcls"=> array()
634                     ));
635     }
637 ?>