Code

Replaced in_array calls with in_array_strict
[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->setInstallMethod('puppet');
69         $this->rebuildListing();
70     }
72     
73     /*! \brief  Sets the installation method to the given method.
74      *          Updates the template engine and adds the initial root 
75      *           object for the selected method.
76      *  @param  The method to use.
77      *  @return TRUE on success else FALSE. 
78      */
79     function setInstallMethod($str)
80     {
81         if(!isset($this->allItemConfigurations[$str])){
82             $this->itemConfig = array();
83             $this->invalidInstallMethod =TRUE;
84             $this->errorMessage = sprintf(_("Invalid installation method %s selected!"), bold($str));
85             msg_dialog::display(_("Setup"), $this->errorMessage, ERROR_DIALOG);
86             return(FALSE);
87         }else{
89             $this->itemConfig = $this->allItemConfigurations[$str]['items'];
90             $this->invalidInstallMethod =FALSE;
91             $this->TemplateEngine->load($this->itemConfig);
93             // Detect root item, its name is / 
94             $root = NULL;
95             foreach($this->itemConfig as $key => $item){
96                 if($item['name'] == '/') {
97                     $root = $key;
98                     break;
99                 }
100             }
101             if(!$root){
102                 $this->errorMessage = sprintf(_("Installation method %s is invalid: no root object found!"), bold($str));
103                 msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
104                 $this->initFailed = TRUE;
105                 $this->itemConfig = array();
106                 return(FALSE);
107             }
109             // Set current item to 'root', this is the minimum to get things running.
110             $idRoot = $this->addItem($root,'root',array());
111             $this->rootItemID = $idRoot;
112             $this->setCurrentItem($idRoot);
113             $this->setSelectedListItemID($idRoot);
114             $this->rebuildListing();
115             return(TRUE);
116         }
117     }
120     /*! \brief  Intializes this plugin
121      *          All available installation methods will be loaded
122      *           and populated.
123      */
124     function init()
125     {
126         // Reset erros
127         $this->rpcError = $this->initFailed = FALSE;
129         // Load configuration via rpc.
130         $rpc = $this->config->getRpcHandle();
132         // Populate install methods on success.
133         $res = $rpc->getSupportedInstallMethods();
134         if(!$rpc->success()){
135             $this->rpcError = TRUE;
136             $this->errorMessage = $rpc->get_error();;
137             return;
138         }       
139         $this->allItemConfigurations = $res;
140         if(!count($this->allItemConfigurations)){
141             $this->errorMessage = _("No selectable install methods available!");
142             msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
143             $this->initFailed = TRUE;
144             return;
145         }
146     }
149     /*! \brief      Add a new child-item to the currently selected one. 
150      *               
151      *  @param  String  type    The 'type' of the new object, eg. 'KickstartTemplate'
152      *  @param  String  name    The 'name' of the new object.
153      *  @param  Array   values  The initial values for this object.
154      *  @return 
155      */
156     function addItem($type,$name, $values = array())
157     {
158         if(!isset($this->itemConfig[$type])){
159             echo "Invalid type {$type}, skipping item!<br>";
160             return;
161         }
163         // Add missing values with the item-type defaults.
164         $allValuesSet = TRUE;
165         foreach($this->itemConfig[$type]['options'] as $oName => $oValue){
166             if(!isset($values[$oName])){
167                 $values[$oName] = (isset($oValue['default']))?$oValue['default']:"";
168             }
169         }
171         // Get the currently selected entry, its the parent for the newly 
172         //  added one. 
173         $current = &$this->currentItem; 
175         // Create a FAKE base to be able to use the management lists
176         //  which are currently ldap and thus dn based.
177         $base = (isset($current['base']))? ",".$current['base'] : '';
178         $base = "{$type}={$name}{$base}";
181         if(isset($this->mappingBaseToID[$base])){
182             echo "Cannot add entry, dn already in use! {$base}<br>";
183             return(null);
184         }
185     
186         // Get next free item slot.
187         $id = ($this->lastItemID ++);
188         $new = array(
189                 'base' => $base,
190                 'children' => array(),
191                 'id' => $id, 
192                 'type' => $type, 
193                 'name' => $name, 
194                 'values' => $values);
196         // Append the entry to the list of all items.
197         $this->allConfiguredItems[$id] = $new;
199         // Create a child referenc, this creates some kind of entry tree.
200         $current['children'][$id] = &$this->allConfiguredItems[$id];
202         // Add entries to the list of base and id mappings
203         //  this allows us to easily detect the base for an id and vice versa.
204         $this->mappingBaseToID[$id] = $base;
205         $this->mappingBaseToID[$base] = $id;
206         return($id);
207     }
210     /*! \brief      Selects an item as active.
211      *              All further add and remove actions will be performed
212      *               on the obejcts children.
213      *  @param  String  The 'id' of the item we want to select.
214      *  @return 
215      */
216     function setCurrentItem($item)
217     {
218         if(!isset($this->allConfiguredItems[$item])){
219             echo "Invalid item name {$name}! Skipping selection!";
220             return;
221         }
223         // Set the new item info.
224         $this->currentItem = &$this->allConfiguredItems[$item];
225         $this->currentItemType = $this->currentItem['type'];
226         $this->currentItemDescriptor = $this->itemConfig[$this->currentItem['type']];
227     }
230     /*! \brief      Removes a given item ID.
231      *  @param  String  The 'id' of the item we want to remove.
232      *  @return 
233      */
234     function removeItem($id, &$data = NULL)
235     {
236         if($data === NULL){
237             $data = &$this->allConfiguredItems;
238         }
240         // Remove the item and its children
241         if(isset($data[$id])){
242             foreach($data[$id]['children'] as $cid => $item){
243                 $this->removeItem($cid, $data);
244             }
245             unset($data[$id]);
246         }
247     
248         // Remove to current id from sub entries
249         foreach($data as $key => $item){
250             $this->removeItem($id, $data[$key]['children']);
251         }
252     }
255     /*! \brief      Initiate item edit.
256      *              An action send from the management list.
257      *  @param  See management::editEntry 
258      *  @return 
259      */
260     function editEntry($action="",$target=array(),$all=array(), 
261             $altTabClass ="", $altTabType = "", $altAclCategory="")
262     {
263         $this->setCurrentItem($target[0]);
264         $this->dialogObject = $this->TemplateEngine;
265         $this->skipFooter = TRUE;
266         $this->dialog = TRUE;
268         // Update the template engine to use another type of item and 
269         //  some other values.
270         $this->TemplateEngine->setValues($this->currentItemType,$this->currentItem['values']);
271     }
274     /*! \brief      Save changes for the currently edited item.
275      */
276     function saveItemChanges()
277     {
278         // Save eventually changed values
279         if($this->currentItem){
281             // Check if everything is fine.
282             $msgs = $this->TemplateEngine->save_object();
283             $msgs = $this->TemplateEngine->check();
284             if(count($msgs)){
285                 msg_dialog::displayChecks($msgs);
286             }else{
287                 foreach($this->TemplateEngine->getWidgets() as $widget){
288                     $this->currentItem['values'][$widget->getName()] = $widget->getValue();
289                 }
290                 $this->closeDialogs();
291             }
292         }
293     }
296     /*! \brief      React on open requests from the management list 
297      */
298     function openEntry($action="",$target=array(),$all=array(), 
299             $altTabClass ="", $altTabType = "", $altAclCategory="")
300     {
301         $this->setSelectedListItemID($target[0]);
302     }
305     /*! \brief   Overridden render method of class mangement.
306      *            this allows us to add a release selection box.
307      */
308     function renderList()
309     {
310         // In case of an error abort here.
311         if($this->rpcError || $this->initFailed || $this->invalidInstallMethod){
312             $smarty = get_smarty();
313             $smarty->assign('initFailed', $this->initFailed);
314             $smarty->assign('rpcError', $this->rpcError);
315             $smarty->assign('invalidInstallMethod', $this->invalidInstallMethod);
316             $smarty->assign('error', $this->errorMessage);
317             return($smarty->fetch(get_template_path('failed.tpl', TRUE)));
318         }
320         // Collect item container list to be able to render the fake-base selector
321         if(!$this->itemContainerSelector){
322             $this->itemContainerSelector = new releaseSelector(
323                     $this->getContainerList(), 
324                     $this->base, 
325                     $this->allConfiguredItems[$this->rootItemID]['base']);
326         }else{
327             $this->itemContainerSelector->setBases($this->getContainerList());
328         }
329         $this->itemContainerSelector->update(true);
330         $this->itemContainerSelector->setBase($this->base);
332         session::set('DEVICE_ITEMS', $this->allConfiguredItems);
333         $this->rebuildListing();
334         $filter = $this->getFilter();
335         $headpage = $this->getHeadpage();
337         $headpage->update();
338         $smarty = get_smarty();
339         $smarty->assign("RELEASE", $this->itemContainerSelector->render());
340         $display = $headpage->render();
341         return($this->getHeader().$display);
342     }
345     /*! \brief   Build up a list of items useable for the itemSelector.
346      */
347     function getContainerList($array = NULL)
348     {
349         $array = ($array == NULL)?$this->allConfiguredItems[$this->rootItemID]: $array;
350         $ret[$array['base']] = $array['type'];
351         if(count($array['children'])){
352             foreach($array['children'] as $subItem){
353                 $ret = array_merge($ret, $this->getContainerList($subItem));
354             }
355         }
356         return($ret);    
357     }
360     /*! \brief   Update the management class and tell her which 
361      *            items are available for the itemSelector (baseSelector).
362      */
363     function rebuildListing()
364     {
365         // Build filter
366         if (session::global_is_set(get_class($this)."_filter")){
367             $filter= session::global_get(get_class($this)."_filter");
368         } else {
369             $filter = new filter(get_template_path("DeviceConfig-filter.xml", true));
370             $filter->setObjectStorage($this->storagePoints);
371         }
372         $this->setFilter($filter);
374         // Load service xml file and fill in placeholders
375         $contents =file_get_contents(get_template_path("DeviceConfig-list.xml", true));
377         // Build up device-list configuration   
378         $types ="";
379         $images = array();
380         $images[] = 'images/lists/edit.png';
381         $images[] = 'images/caps.png';
382         $images[] = 'images/lists/trash.png';
383         $images[] = 'images/filter.png';
384         $images[] = 'images/find.png';
385         $i = 0; 
386         foreach($this->itemConfig as $type => $item){
387             $desc = $item['description'];
388             $img = $images[$i++];
389             $types .= 
390                 "   <objectType>".
391                 "     <label>{$desc}</label>".
392                 "     <objectClass>{$type}</objectClass>".
393                 "     <category>Device</category>".
394                 "     <class>dummy</class>".
395                 "     <image>{$img}</image>".
396                 "   </objectType>";
397         }
398         $contents = preg_replace("/%TYPES%/", $types, $contents);
401         $items = "";
402         $i = 0;
403         foreach($this->addableContainerItems as $item){
404             $desc = $this->itemConfig[$item]['description'];
405             $img = $images[$i++];
406             $items .=
407                 "<action>".
408                 "    <name>add_{$item}</name>".
409                 "    <type>entry</type>".
410                 "    <image>{$img}</image>".
411                 "    <label>{$desc}</label>".
412                 "</action>";
413         }
415         if(!empty($items)){
416             $items = 
418                 "<action>".
419                 " <type>sub</type>".
420                 " <image>images/lists/element.png[new]</image>".
421                 " <label>Create</label>".
422                 " {$items}".
423                 "</action>";
424         }
426         $contents = preg_replace("/%ITEMS%/", $items, $contents);
428         $headpage = new listing($contents,TRUE);
429         $headpage->setBase($this->base);
430         $headpage->setFilter($filter);
432         parent::__construct($this->config, $this->ui, "services", $headpage);
434         // Register default actions
435         $this->registerAction("new",        "newEntry");
436         $this->registerAction("edit",       "openEntry"); // !! We forward 'edit' to 'open' to have a department like navigation.
437         $this->registerAction("editEntry",  "editEntry");
439         $this->registerAction("saveItemChanges", "saveItemChanges");
440         $this->registerAction("cancelItemEdit", "closeDialogs");
441         $this->registerAction("cancelItemAdd", "closeDialogs");
442         $this->registerAction("saveItemAdd", "saveItemAdd");
443         foreach($this->itemConfig as $name => $item){
444             $this->registerAction("add_{$name}", "newEntry");
445         }
446     }
449     /*! \brief  This method intiates the object creation.
450      *
451      *  @param  String  'action'  The name of the action which was the used as trigger.
452      *  @param  Array   'target'  A list of object dns, which should be affected by this method.
453      *  @param  Array   'all'     A combination of both 'action' and 'target'.
454      */
455     function newEntry($action="",$target=array(),$all=array(), 
456             $altTabClass ="", $altTabType = "", $altAclCategory="")
457     {
458         $toAdd = preg_replace("/^add_/", "",$action);
459         $itemToAdd = $this->itemConfig[$toAdd];
461         $this->dialogObject = new AddItemDialog($this->config,$toAdd,$itemToAdd);
462         $this->dialog = true;
463     }
465     
466     /*! \brief   Saves newly created items and adds them as child to 
467      *            the currently selected item.
468      */
469     function saveItemAdd()
470     {
471         if(!$this->dialogObject instanceOf AddItemDialog) return;
473         $msgs = $this->dialogObject->save_object();
474         $msgs = $this->dialogObject->check();
475         if(count($msgs)){
476             msg_dialog::displayChecks($msgs);
477         }else{
478             $itemName = $this->dialogObject->getName();
479             $itemCfg = $this->dialogObject->getItemCfg();
480             $itemType = $this->dialogObject->getItemType();
482             $this->setCurrentItem($this->mappingBaseToID[$this->base]);
483     
484             $this->addItem($itemType, $itemName);
485             $this->closeDialogs();
487 #           $this->setCurrentItem($itemName);
488 #           $this->dialogObject = $this->TemplateEngine;
489 #           $this->skipFooter = TRUE;
490 #           $this->dialog = TRUE;
492         }
493     }
496     /*! \brief  Keep track of posted values, some may be interesting for us. 
497      *          Tell the template engine to take care of posted values too.
498      *  @param  String
499      *  @return 
500      */
501     function save_object()
502     {
503         if(isset($_POST['retryInit'])){
504             $this->init();
505             return;
506         }
507             
508         // Do nothing else in case of an error
509         if($this->rpcError || $this->initFailed) return;
511         // Add sub-module requested.
512         if(isset($_POST['addSubModule']) && isset($_POST['subModule'])){
513             $sub = get_post('subModule');
514             if(in_array_strict($sub, $this->currentItemDescriptor['container'])){
516                 // Check if this is a valid item
517                 if(!isset($this->itemConfig[$sub])) {
518                     echo "Invalid item type '{$sub}'!";
519                     $values = array();
520                 }else{
521                     $values = $this->itemConfig[$sub]['options'];
522                 }
523                 $name = 'test'.rand(0,99999);
524                 $this->addItem($sub,$name,$values);
525             }
526         }
528         // Get the selected item-id from the item list and populate it.
529         if($this->itemContainerSelector){
530             $this->itemContainerSelector->update();
531             $id  = $this->mappingBaseToID[$this->itemContainerSelector->getBase()]; 
532             $this->setSelectedListItemID($id);
533         }
534     }
537     /* \brief   Updates the currenlty seleted item in the management list
538      */   
539     function setSelectedListItemID($id)
540     {
541         $this->base = $this->mappingBaseToID[$id];
542         $type = $this->allConfiguredItems[$id]['type'];
543         $this->addableContainerItems = $this->itemConfig[$type]['container'];
544     }
547     /*! \brief    Forward plugin acls
548      */
549     function set_acl_base($base)
550     {
551         $this->acl_base = $base;
552     }
555     /*! \brief    Forward plugin acls
556      */
557     function set_acl_category($category)
558     {
559         $this->acl_category = $category;
560     }
562     function save()
563     {
564         foreach($this->allConfiguredItems as $name => $item){
565             foreach($item['values'] as $oName => $oValue){
566                 if(!is_array($oValue)) $oValue = array($oValue);
567                 foreach($oValue as $val){
568                     echo "<br>{$name} -- <i>{$item['type']}</i>: <b>{$oName}</b>: {$val}";
569                 }
570             }
571         }
572     }
575     /*! \brief  Initiates the removal for the given entries
576      *           and displays a confirmation dialog.
577      *
578      *  @param  String  'action'  The name of the action which was the used as trigger.
579      *  @param  Array   'target'  A list of object dns, which should be affected by this method.
580      *  @param  Array   'all'     A combination of both 'action' and 'target'.
581      */
582     protected function removeEntryRequested($action="",$target=array(),$all=array())
583     {
584         foreach($target as $id){
585             $this->removeItem($id);
586         }
587     }
589     
590     // Inject user actions
591     function detectPostActions()
592     {
593         if($this->rpcError || $this->initFailed) return(array('action' => ''));
595         $action = management::detectPostActions();
596         if(isset($_POST['saveItemEdit'])) $action['action'] = "saveItemChanges";
597         if(isset($_POST['saveItemAdd'])) $action['action'] = "saveItemAdd";
598         if(isset($_POST['cancelItemEdit'])) $action['action'] = "cancelItemEdit";
599         if(isset($_POST['cancelItemAdd'])) $action['action'] = "cancelItemAdd";
600         return($action);
601     }
603     
604     function closeDialogs()
605     {
606         parent::closeDialogs();
607         $this->dialog = false;
608     }
609    
610  
611     function check()
612     {
613         return(array());
614     }
616     function getRootItemId()
617     {
618         return($this->rootItemID);
619     }
622     public static function plInfo()
623     {
624         return (array(
625                     "plShortName"   => _("Config management"),
626                     "plDescription" => _("Config management"),
627                     "plSelfModify"  => FALSE,
628                     "plDepends"     => array(),
629                     "plPriority"    => 0,
630                     "plSection"     => array("administration"),
631                     "plCategory"    => array(
632                         "ConfigManagement" => array("description"  => _("Config management"),
633                             "objectClass"  => "FAKE_OC_ConfigManagement")),
634                     "plProvidedAcls"=> array()
635                     ));
636     }
638 ?>