Code

bf29fc9e9fb2541d033195379ddf098938d0fd97
[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 $cfgTypeMap = NULL;
17     var $cfgItemMap = NULL;
19     /*! \brief  Initialize the plugin and finally update the data model.
20      */
21     function __construct($config, $dn)
22     {
23         $this->config = &$config;
24         $this->listing = new ConfigManagementListing($this->config, get_userinfo(), $this);
26         // Load the template engine and tell her what template
27         //  to use for the HTML it produces.
28         $this->TemplateEngine = new TemplateEngine($config);
30         // Request an update of the data model
31         $this->loadInstallationMethods();
32         $this->updateDataModel();
33         $this->listing->setListingTypes($this->getListingTypes());
34     }
37     /*! \brief  Sets the installation method to the given method.
38      *          Updates the template engine and adds the initial root
39      *           object for the selected method.
40      *  @param  The method to use.
41      *  @return TRUE on success else FALSE.
42      */
43     function setInstallMethod($str)
44     {
45         if(!isset($this->installationMethods[$str])){
46             $this->itemConfig = array();
47             $this->invalidInstallMethod =TRUE;
48             $this->errorMessage = sprintf(_("Invalid installation method %s selected!"), bold($str));
49             msg_dialog::display(_("Setup"), $this->errorMessage, ERROR_DIALOG);
50             return(FALSE);
51         }else{
52     
53             $this->TemplateEngine->setTemplate($str.".tpl");
54             $this->itemConfig = $this->installationMethods[$str]['items'];
55             $this->invalidInstallMethod =FALSE;
56             $this->TemplateEngine->load($this->itemConfig);
58             // Detect root item, its name is /
59             $root = NULL;
60             foreach($this->itemConfig as $key => $item){
61                 if($item['name'] == '/') {
62                     $root = $key;
63                     break;
64                 }
65             }
66             if(!$root){
67                 $this->errorMessage = sprintf(_("Installation method %s is invalid: no root object found!"), bold($str));
68                 msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
69                 $this->initFailed = TRUE;
70                 $this->itemConfig = array();
71                 return(FALSE);
72             }
73         }
74     }
77     /*! \brief  Updates all distributions, releases, packages and items in the dataModel
78      *          Load information from the backend.
79      */
80     function updateDataModel()
81     {
82         // Recreate the data model, to have a clean and fresh instance.
83         $this->dataModel = new ConfigManagementDataModel();
85         // Load distributions 
86         $rpc = $this->config->getRpcHandle();
87         $res = $rpc->getDistributions();
89         if(!$rpc->success()){
90             msg_dialog::display(_("Error"), sprintf(_("Failed to load distributions: %s"), $rpc->get_error()),ERROR_DIALOG);
91             return(NULL);
92         }else{
93             $this->cfgTypeMap = array();
94             foreach($res as $dist){
95                 $dist['__removeable'] = TRUE;
96                 $this->dataModel->addItem('Distribution','/root', $dist['name'], $dist);
97                 $this->cfgTypeMap['/root/'.$dist['name']] = $dist['installation_method'];
98                 foreach($dist['releases'] as $release){
99                     $distPath = "/root/{$dist['name']}";
100                     $release['__removeable'] = TRUE;
101                     $this->dataModel->addItem('Release',$distPath, $release['name'], $release);
102                 }
103             }
104         }
105     }
108     /*! \brief  Keep track of posted values and populate those 
109      *           which are interesting for us.
110      *          Inspects the _POST and _GET values.
111      */
112     function save_object()
113     {
114         // Update the listing class, this is necessary to get post
115         //  actions from it.
116         $this->listing->save_object();
118         // Get the selected distribution and release from the listing widget.
119         $cont = $this->listing->getSelectedContainer();
120         if(isset($_POST['ROOT'])){
121             $this->setCurrentContainer('/root');
122         }elseif(isset($_POST['BACK'])){
124             $path = $this->selectedContainer;
125             if($this->dataModel->itemExistsByPath($path)){
126                 $data = $this->dataModel->getItemByPath($path);
127                 if($data['parentPath']){
128                     $this->setCurrentContainer($data['parentPath']);
129                 }
130             }
131         }else{
132             $this->setCurrentContainer($cont);
133         }
134     }
137     /*! \brief  Load extended sub-objecte like 'config items' or 'packages'
138      *           for the given release path.
139      *  @param  String  The release path to load sub-objects for.
140      *  @return NULL 
141      */
142     function updateItemList($path)
143     {
144         // Fist get Item and check if it is an release 
145         if($this->dataModel->itemExistsByPath($path)){
146             $data = $this->dataModel->getItemByPath($path);
148             // Only releases can contain config-items.
149             if($data['type'] == 'Release' && $data['status'] != "fetched"){
151                 $rpc = $this->config->getRpcHandle();
152                 $res = $rpc->listConfigItems($data['name']);
153                 if(!$rpc->success()){
154                     msg_dialog::display(_("Error"), 
155                             sprintf(_("Failed to load distributions: %s"), 
156                                 $rpc->get_error()),ERROR_DIALOG);
157                 }else{
159                     // Sort entries by path length 
160                     $sLen = array();
161                     foreach($res as $itemPath => $type){
162                         $sLen[strlen($itemPath)."_".$itemPath] = $itemPath;
163                     }
164                     uksort($sLen, "strnatcasecmp");   
166                     // Walk through each entry and then try to add it to the model
167                     foreach($sLen as $unused => $itemPath){
169                         $type = $res[$itemPath];
170                 
171                         // Root installation objects do not have a name, so we use 'root' here.
172                         $targetPath = trim($path."/root/".$itemPath);
174                         // Remove trailing and duplicated slashes
175                         $targetPath = rtrim($targetPath, '/');
176                         $targetPath = preg_replace("/\/\/*/","/", $targetPath);
178                         // Extract the items name
179                         $name = preg_replace("/^.*\//","", $targetPath);
180     
181                         // Cleanup the path and then add the item.
182                         $targetPath = preg_replace("/[^\/]*$/","", $targetPath);
183                         $targetPath = rtrim($targetPath,'/');
184                         $this->dataModel->addItem($type, $targetPath, $name, 
185                                 array(    
186                                         '__editable' => TRUE,
187                                         '__removeable' => TRUE,
188                                         '__path' => $itemPath,
189                                         '__release' => $path
190                                     ),'-' ); 
191                     }
192                     $this->dataModel->setItemStatus($path, 'fetched');
193                 }
194             }
195         }
196     }
199     /*! \brief  Sets the currently selected container and item path. 
200      *  @param  String  The path of the container to set.
201      *  @param  String  The path of the item to set.
202      *  @return 
203      */
204     function setCurrentContainer($cont)
205     {
207         $this->selectedContainer = $cont;
209         // Update list of items within the selected container. 
210         $this->updateItemList($this->selectedContainer);
212         // Transfer checked values back to the listing class.
213         $this->listing->setContainers($this->getContainerList());
214         $this->listing->setContainer($cont);
216         // Set the correct installation method for the selected item
217         if(isset($this->cfgTypeMap[$cont])){
218             $method = $this->cfgTypeMap[$cont];
219             $this->setInstallMethod($method);
220         }
222         // Update the list of addable sub objects
223         $item = $this->dataModel->getItemByPath($cont);
224         if(isset($this->itemConfig[$item['type']]['container'])){
225             $this->addableContainerItems = $this->itemConfig[$item['type']]['container'];
226         }else{
227             $this->addableContainerItems = array();
228         }
229     }
232     /*! \brief  Generate the HTML content for this plugin.
233      *          Actually renders the listing widget..
234      */
235     function execute()
236     {
237         // Get the selected release and store it in a session variable
238         //  to allow the configFilter to access it and display the
239         //  packages and items.
240         $res = $this->listing->execute();
241         $this->listing->setListingTypes($this->getListingTypes());
242         return($res);
243     }
246     /*! \brief      Returns a list of items which will then be displayed 
247      *               in the management-list. 
248      *              (The management class calls this method from its execute())
249      *  @return     Array   A list of items/objects for the listing. 
250      */
251     function getItemsToBeDisplayed()
252     {
254         $path = $this->selectedContainer;
255         $item = $this->dataModel->getItemByPath($path);
256         return($item);
257     }
260     /*! \brief  Returns a simply list of all distributions.
261      *          This list will then be used to generate the entries of the 
262      *           ItemSelectors in the listing class.
263      */
264     function getContainerList()
265     {
266         $data = $this->dataModel->getItemByPath('/root');
267         $res = array();
268         $res["/root"] = array("name" => "/", "desc" => "");
269         $res = array_merge($res,$this->__recurseItem($data, array('Distribution','Release')));
270         return($res);
271     }
274     /*! \brief  Recursivly walks through an item and collects all path and name info.
275      *          The reult can then be used to fill the ItemSelector.
276      *  @param  Array   The Item to recurse. 
277      *  @param  Array   The type of of objects to collect. 
278      *  @param  String  The parent path prefix which should be removed.
279      *  @return Array   An array containing Array[path] = name
280      */
281     function __recurseItem($item, $types, $parent = "")
282     {
283         $res = array();
284         if(1 ||  in_array($item['type'], $types)){
285             $path = preg_replace("/".preg_quote($parent,'/')."/","",$item['path']);
286             $res[$path] = array('name' => $item['name'],'desc'=>$item['type']);
287         }
288         if(count($item['children'])){
289             foreach($item['children'] as $child){
290                 $res = array_merge($res, $this->__recurseItem($child, $types, $parent));
291             }
292         }
293         return($res);
294     }
297     /*! \brief  Intializes this plugin
298      *          All available installation methods will be loaded
299      */
300     function loadInstallationMethods()
301     {
302         // Reset erros
303         $this->rpcError = $this->initFailed = FALSE;
305         // Load configuration via rpc.
306         $rpc = $this->config->getRpcHandle();
308         // Populate install methods on success.
309         $res = $rpc->getSupportedInstallMethods();
310         if(!$rpc->success()){
311             $this->rpcError = TRUE;
312             $this->errorMessage = $rpc->get_error();;
313             return;
314         }
315         $this->installationMethods = $res;
316         if(!count($this->installationMethods)){
317             $this->errorMessage = _("No selectable install methods returned!");
318             msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
319             $this->initFailed = TRUE;
320             return;
321         }else{
322             $this->cfgItemMap = array();
323             foreach($this->installationMethods as $method => $items){
324                 foreach($items['items'] as $itemName => $item){
325                     $this->cfgItemMap[$itemName] = $method;
326                 }
327             }
328         }
329     }
332     /*! \brief   Returns a info list about all items we can manage,
333      *            this used to fill the listings <objectType> settings.
334      *  @return Array   An array with item info.
335      */
336     function getListingTypes()
337     {
338         $types= array();
339         $types['Distribution']['objectClass'] = 'Distribution';
340         $types['Distribution']['label'] = _('Distribution');
341         $types['Distribution']['image'] = 'images/lists/edit.png';
342         $types['Distribution']['category'] = 'Device';
343         $types['Distribution']['class'] = 'Device';
345         $types['Release']['objectClass'] = 'Release';
346         $types['Release']['label'] = _('Release');
347         $types['Release']['image'] = 'images/lists/delete.png';
348         $types['Release']['category'] = 'Device';
349         $types['Release']['class'] = 'Device';
351         $types['Component']['objectClass'] = 'Component';
352         $types['Component']['label'] = _('Component');
353         $types['Component']['image'] = 'plugins/users/images/select_user.png';
354         $types['Component']['category'] = 'Device';
355         $types['Component']['class'] = 'Device';
357         foreach($this->installationMethods as $method => $items){
358             foreach($items['items'] as $itemName => $item){
359                 $types[$itemName]['objectClass'] = $itemName;
360                 $types[$itemName]['label'] = $item['name'];
361                 $types[$itemName]['image'] = 'plugins/fai/images/fai_script.png';
362                 $types[$itemName]['category'] = 'Device';
363                 $types[$itemName]['class'] = 'Device';
364             }
365         }
367         return($types);
368     }
371     /*! \brief      The plugins ACL and plugin-property definition. 
372      *  @return 
373      */
374     public static function plInfo()
375     {
376         return (array(
377                     "plShortName"   => _("Config management"),
378                     "plDescription" => _("Config management"),
379                     "plSelfModify"  => FALSE,
380                     "plDepends"     => array(),
381                     "plPriority"    => 0,
382                     "plSection"     => array("administration"),
383                     "plCategory"    => array(
384                         "newConfigManagement" => array("description"  => _("Config management"),
385                             "objectClass"  => "FAKE_OC_newConfigManagement")),
386                     "plProvidedAcls"=> array()
387                     ));
388     }
391     /*! \brief  Acts on open requests.
392      *          (This action is received from the ConfigManagementListing class.)
393      *  @param  Array   The items ids. (May contain multiple ids)
394      *  @return
395      */
396     function openEntry($ids)
397     {
398         $id = $ids[0];
399         $item = $this->dataModel->getItemById($id);
400         $this->setCurrentContainer($item['path']);
401         return;
402     }
406     /*! \brief   
407      *  @param  
408      *  @return 
409      */
410     function remove_lock()
411     {
412     }
415     function editEntry($ids)
416     {
417         // Update the template engine to use another type of item and
418         //  some other values.
419         $item = $this->dataModel->getItemById($ids[0]);
421         if(isset($this->cfgItemMap[$item['type']])){
422             $release = preg_replace("/^.*\//","",$item['values']['__release']);
423             $path = $item['values']['__path'];
424             $method = $this->cfgItemMap[$item['type']];
426             // Load item values on demand
427             if($item['status'] == '-'){
428                 $rpc = $this->config->getRpcHandle();
429                 $item['values']['itemValues'] = $rpc->getConfigItem($release, $path);
430                 $this->dataModel->setItemStatus($item['path'], 'fetched');
431                 $this->dataModel->setItemValues($item['path'], $item['values']);
432             }
434             $this->setInstallMethod($method);
435             $this->TemplateEngine->setValues($item['type'],$item['values']['itemValues']);
436             $this->listing->setDialogObject($this->TemplateEngine);
437         }
438     }
442 ?>