Code

Apply fix for #4170
[gosa.git] / trunk / gosa-plugins / fai / admin / fai / class_faiDebconfConfigurations.inc
1 <?php
3 class faiDebconfConfigurations extends plugin
4 {
5     /* attribute list for save action */
6     var $ignore_account = TRUE;
7     var $attributes     = array();
8     var $objectclasses  = array();
9     var $FAIstate = "";
10     var $DebconfConfigurations = array();
11     var $DebconfDefaults = array();
12     var $DebconfAll = array();
13     var $to_remove = array();
14     var $removed = array();
15     var $package_list = FALSE;
16     var $parent = FALSE;
17     var $packages = array();
19     /* Some settings */
20     var $query_gosa_si = TRUE;
21     var $merge_defaults_into_view = TRUE;
22     var $bool_mapping = array(
23                             "0" => 'false',
24                             "1" => 'true',
25                             "true" => 'true',
26                             "false" => 'false'
27                           );
29     /*! \brief  Configure all debconf configurations of a given package list
30         @param  Object  $config GOsa configuration object;
31         @param  String  The DN of the current package list.
32      */
33     function faiDebconfConfigurations (&$config, $dn= NULL, &$parent)
34     {
35       plugin::plugin ($config, $dn);
37       /* Store some information we need from the parent object */
38       $this->FAIstate = $parent->FAIstate;
39       $this->package_list = $parent->cn;
40       $this->parent = $parent;
42       /* Get the list of configurations from the parent object */
43       $this->DebconfConfigurations = $this->parent->ConfiguredPackages;
45       /* Load packages */
46       foreach(array_keys($this->parent->usedPackages) as $package) {
47           $this->packages[$package] = $package;
48       }
49       ksort($this->packages);
52       /* Determine and assemble release name */
53       $release = $this->parent->parent->parent->fai_release;
54       $tmp= preg_replace('/[,]*'.preg_quote(get_ou('faiBaseRDN'), '/').'.*$/', '', $release);
55       $tmp= preg_replace('/ou=/', '', $tmp);
56       $rev= array_reverse(split(',', $tmp));
57       $this->release= "/";
58       foreach ($rev as $part){
59         $this->release.= "/$part";
60       }
61       $this->release= preg_replace('#^[/]*#', '', $this->release);
62    
63       /* Get the list of debconf configuration for the given package list */
64       $ldap = $config->get_ldap_link();
66       /* Get the defaults from gosa-si */
67       if ($this->query_gosa_si == TRUE) {
68         $q = new gosaSupportDaemon();
69         $ret = $q->FAI_get_packages($this->release,array("package","template"),$this->packages);
70         if($q->is_error()){
71             msg_dialog::display(_("Service infrastructure"),msgPool::siError($q->get_error()),ERROR_DIALOG);
72         }
73         else {
74           foreach($ret as $res) {
75             $package = $res['PACKAGE'];
76             if (isset($res['TEMPLATE'])) {
77               $template = base64_decode($res['TEMPLATE']);
78               $debconf_handle = new debconf(preg_replace('/_.*$/', '', get_browser_language()));
79               $debconf_handle->load_from_string($template);
80               $templates = $debconf_handle->template;
81               unset($debconf_handle);
82               foreach($templates as $template) {
83                 $template['Save'] = FALSE;
84                 if (!isset($this->DebconfDefaults[$package][$template['Name']])) {
85                   $this->DebconfDefaults[$package][$template['Name']] = $template;
86                 }
87               } 
88             }
89           }
90         }
91       }
92     }
95     /*! \brief Return a save toggle */
96     function getSaveToggle ($identifier) {
97       list($package, $name) = $this->getIdentifierComponents(base64_decode($identifier));
99       /* We do not need a save toggle for manually entered parameters */
100       if (isset($this->DebconfDefaults[$package][$name])) {
101         $template = "
102           <input type='hidden' name='save_%s' value='%s'>
103           <input type='image' src='%s' width='18' name='toggle_%s_%s' value='%s' title='%s'>
104           ";
105         if (isset($this->DebconfConfigurations[$package][$name])) {
106           if ($this->DebconfConfigurations[$package][$name]['Save'] == TRUE) {
107             return(sprintf($template, $identifier, '0', 'images/save.png', 'nosave', $identifier, '0', _("Currently saved")));
108           }
109           else {
110             return(sprintf($template, $identifier, '1', 'images/empty.png', 'save', $identifier, '1', _("Currently not saved")));
111           };
112         } else {
113             /* Defaults w/o corresponding configuration entry are not saved by default
114             * so give the user the chance to change that */
115             return(sprintf($template, $identifier, '1', 'images/empty.png', 'save', $identifier, '1', _("Currently not saved")));
116         }
117       }
118     } 
119     /*! \brief  Returns a html interface, that allow to modify 
120                  the package attributes.
121         @return String  HTML content/ui for this plugin
122      */
123     function execute()
124     {
125       /* Call parent execute */
126       plugin::execute();
128       ksort($this->DebconfConfigurations);
130       if(is_object($this->dialog)) {
131         $this->dialog->save_object();
132       $display = $this->dialog->execute();
133       return($display);
134     }
136     $divlist = new divSelectBox("faiDebconfConfigurations");
137     $divlist->setHeight(400);
139     /* Define header */
140     $field1 = array ("string" => "<b>" . _("Package") . "</b>");
141     $field2 = array ("string" => "<b>" . _("Variable") . "</b>");
142     $field3 = array ("string" => "<b>" . _("Type"). "</b>");
143     $field4 = array ("string" => "<b>" . _("Value") . "</b>");
144     $field5 = array ("string" => "");
145     $divlist->AddEntry(array($field1,$field2,$field3,$field4,$field5));
147     /* Define some vars we will need in the following loop */
148     $str_reset = "<input type='image' title='"._("Reset")."'
149       src='images/lists/reload.png' name='reset_%s'>&nbsp;";
150     $str_delete = "<input type='image' title='"._("Delete")."'
151       src='images/lists/trash.png' name='reset_%s'>&nbsp;";
152     $str_edit = "<input type='image' title='"._("Edit")."'
153       src='images/lists/edit.png' name='edit_%s'>&nbsp;";
154     $str_input = "<input type=text length=100 value=\"%s\" name='val_%s' %s>";
156     /* Merge defaults into display */
157     if ($this->merge_defaults_into_view) {
158       $defaults = array();
159       foreach($this->DebconfDefaults as $package => $package_data){
160         foreach($package_data as $debconf_info) {
161             $name = $debconf_info['Name'];
162             $value = $debconf_info['Default'];
163             $type = $debconf_info['Type'];
164             if(!in_array($type,array("boolean","multiselect","password","select","string","text"))){
165               continue;
166             }
167             $defaults[$package][$name] = array( 
168                                                  'Name' => $name,
169                                                  'Value' => $value, 
170                                                  'Type' => $type,
171                                                  'Save' => FALSE
172                                          );
173         }
174       }
175       $this->DebconfAll = $this->DebconfConfigurations;
176       
177       foreach($this->packages as $package) {
178         if (isset($defaults[$package])) {
179           if (isset($this->DebconfConfigurations[$package])) {
180             $this->DebconfAll[$package] = array_merge($defaults[$package], $this->DebconfConfigurations[$package]);
181           }else {
182             $this->DebconfAll[$package] = $defaults[$package];
183           }
185         }
187       }
188     } else {
189       $this->DebconfAll = $this->DebconfConfigurations;
190     }
191     ksort($this->DebconfAll);
193     /* Build package list */
194     $defaults_count = count($this->DebconfDefaults);
195     foreach($this->DebconfAll as $package => $package_data) {
196       foreach($package_data as $debconf_info) {
197         /* Do not show removed entries */
198         if (isset($debconf_info['Status']) && $debconf_info['Status'] == 'removed') {
199           continue;
200         }
202         /* Base64-encoded identifier for every package/debconf_data combination
203          * is in the form of packge/Name e.g. locales/locales/locales_to_generate */
204         $identifier = base64_encode(sprintf("%s/%s",$package, $debconf_info['Name']));
206         /* Define actions for this entry */ 
207         $actions = "";
208         if(!preg_match('/^freeze/', $this->FAIstate) && 
209           $this->acl_is_writeable("FAIdebconfInfo")) {
210             /* Don't enable actions if no gosa-si defaults available */
211             $show_reset = FALSE;
212             $show_edit = FALSE;
213             $show_blank = FALSE;
214             if ($defaults_count != 0) {
215                 $name = $debconf_info['Name'];
217                 if (isset($this->DebconfDefaults[$package][$name])) {
218                   $show_edit = TRUE;
219                 }
220                 else {
221                   $show_delete = TRUE;
222                 }
224                 if (isset($this->DebconfConfigurations[$package][$name]) && isset($this->DebconfDefaults[$package][$name])) {
225                   $val = $this->DebconfConfigurations[$package][$name]['Value'];
226                   $default_val = $this->DebconfDefaults[$package][$name]['Default'];
227                   /* Make values comparable */
228                   if (is_array($val)) {
229                     $val = "";
230                   }
231                   if ($val != $default_val) {
232                     $show_reset = TRUE;
233                   }
234                   else {
235                     $show_blank = TRUE;
236                   }
237                 }elseif (!isset($this->DebconfConfigurations[$package][$name]) && isset($this->DebconfDefaults[$package][$name])) {
238                   $show_blank = TRUE;
239                 }
240             }
242             if ($show_reset) {
243                 $actions .= sprintf("$str_reset", $identifier);
244             } elseif ($show_blank) {
245                 $actions .= $this->getSaveToggle($identifier);
246             } else {
247                 $actions .= sprintf("$str_delete", $identifier);
248             }
249             if ($show_edit) {
250               $actions .= sprintf("$str_edit", $identifier);
251             }
252         }
254         /* Do not allow editing if FAIstate is freeze */
255         $input_disabled = "";
256         if (preg_match('/^freeze/', $this->FAIstate)) {
257           $input_disabled = "disabled";
258         }
260         /* Pre-Fill input field with the defined value */
261         $input_value = "";
262         if (!empty($debconf_info['Value'])) {
263           $input_value = htmlentities($debconf_info['Value']);
264         }
265         $input_field = sprintf("$str_input", $input_value, $identifier, $input_disabled);
268         $field1 = array( "string" => $package, "attach" => "style='width:120px;'" );
269         $field2 = array( "string" => $debconf_info['Name']);
270         $field3 = array( "string" => $debconf_info['Type'],"attach" => "style='width:100px;'");
271         $field4 = array( "string" => $input_field);
272         $field5 = array( "string" => $actions, "attach" => "style='width:60px; border-right:0px;'");
273         $divlist->AddEntry(array($field1, $field2, $field3, $field4, $field5));
274       }
275     }
276     /* Fill templating stuff */
277     $smarty     = get_smarty();
278     $smarty->assign("divlist", $divlist->DrawList());
279     $smarty->assign("headline", sprintf(_("Debconf information for package list '%s'"), $this->package_list));
280     return($smarty->fetch(get_template_path('faiDebconfConfigurations.tpl', TRUE)));
281   }
284   function normalize_bool($bool_value, $check_mode=FALSE) {
285     $bool_value = strtolower($bool_value);
286     if(isset($this->bool_mapping[$bool_value])) {
287       return $this->bool_mapping[$bool_value];
288     } else {
289       return ($check_mode) ? FALSE : $bool_value;
290     }
291   }
293   /*! \brief Return the components of an identifier as an array of two elements */
294   function getIdentifierComponents($identifier) {
295     $identifier_components = explode('/', $identifier);
296     $package = $identifier_components[0];
297     $name = preg_replace("/^".$package."\//", "", $identifier, 1);
298     return(array($package, $name));
299   }
301   function DeleteEntry($identifier) {
302     list($package, $name) = $this->getIdentifierComponents($identifier);
303     if (isset($this->DebconfConfigurations[$package][$name])) {
304       $this->DebconfConfigurations[$package][$name]['Save'] = FALSE;
305       if (!isset($this->DebconfDefaults[$package][$name])) {
306         $this->DebconfConfigurations[$package][$name]['Status'] = "removed";
307       } else {
308         $this->DebconfConfigurations[$package][$name]['Value'] = $this->DebconfDefaults[$package][$name]['Default'];
309       }
310     }
312     /* Check if the package entry is still justified */
313     if (is_array($this->DebconfConfigurations[$package])) {
314       if (!count($this->DebconfConfigurations[$package]) > 0) {
315         unset($this->DebconfConfigurations[$package]);
316       }
317     }
318   }
320   function UpdateEntry($identifier, $newval="") {
321     list($package, $name) = $this->getIdentifierComponents($identifier);
322     if (!isset($this->DebconfConfigurations[$package][$name])) {
323       $this->DebconfConfigurations[$package][$name] = $this->DebconfDefaults[$package][$name];
324     }
326     /* Normalize boolean values */
327     if ($this->DebconfConfigurations[$package][$name]['Type'] == 'boolean') {
328       $newval = $this->normalize_bool($newval);
329     }
331     /* If the value changed, toggle the save flag */
332     $previous_value = "";
333     if (isset($this->DebconfConfigurations[$package][$name]['Value'])) {
334       $previous_value = $this->DebconfConfigurations[$package][$name]['Value'];
335     }
336     else {
337       $previous_value = $this->DebconfConfigurations[$package][$name]['Default'];
338     }
339     if (is_array($previous_value)) {
340       $previous_value = "";
341     }
343     if ($previous_value != $newval) {
344       $this->DebconfConfigurations[$package][$name]['Save'] = TRUE;
345     }
347     $this->DebconfConfigurations[$package][$name]['Value'] = $newval;
350     /* Set empty values to an array */
351     if (isset($this->DebconfConfigurations[$package][$name]) && !$this->DebconfConfigurations[$package][$name]['Value']) {
352         $this->DebconfConfigurations[$package][$name]['Value'] = array();
353     }
354   }
356   /*!\brief Toggle the save status of a given identifier */
357   function ToggleSave($identifier, $value) {
358     list($package, $name) = $this->getIdentifierComponents($identifier);
360     $save = ($value == 1) ? TRUE : FALSE;
362     if (!isset($this->DebconfConfigurations[$package][$name])) {
363       $this->DebconfConfigurations[$package][$name] = $this->DebconfDefaults[$package];
364     }
366     $this->DebconfConfigurations[$package][$name]['Save'] = $save;
367   }
369   /* Save data to object */
370   function save_object()
371   {
372      /* Process values */
373     if (isset($_POST['update_values'])) {
374       foreach($this->DebconfAll as $package => $package_data) {
375           foreach($package_data as $debconf_info) {
376               $identifier = sprintf("%s/%s",$package, $debconf_info['Name']);
377               $post_key = sprintf("val_%s", base64_encode($identifier));
378               if (isset($_POST[$post_key])) {
379                 $this->UpdateEntry($identifier, get_post($post_key));
380               }
381               else {
382                 $this->UpdateEntry($identifier);
383               }
384           }
385       }
386     }
388     foreach($_POST as $key => $value) {
389       if (preg_match("/^toggle_save_/", $key)) {
390         $identifier = base64_decode(str_replace("toggle_save_", "", $key));
391         $this->ToggleSave($identifier, 1);
392       }
394       if(preg_match("/^toggle_nosave_/", $key)) {
395         $identifier = base64_decode(str_replace("toggle_nosave_", "", $key));
396         $this->ToggleSave($identifier, 0);
397       }
399       if (preg_match("/^reset_/", $key)) {
400         $identifier = base64_decode(str_replace("reset_", "", $key));
401         $this->DeleteEntry($identifier);
402         break;
403       }
405       if (preg_match("/^edit_/", $key)) {
406         $identifier = base64_decode(str_replace("edit_", "", $key));
407         list($package, $name) = $this->getIdentifierComponents($identifier);
408         $this->dialog = new faiPackageConfiguration($this->config, $this->parent->dn, $package, $this->release, $this->DebconfConfigurations[$package]);
409         $this->dialog->used_by_faiDebconfConfigurations = TRUE;
410         break;
411       }
412       if (preg_match("/^NewDebconfEntry$/", $key)) {
413         $this->dialog = new NewDebconfConfiguration($this->config, $this->parent->dn, $this);
414         $this->is_dialog = TRUE;
415         break;
416       }
417     }
418  
419     /* Cancel add debconf dialog */
420     if (isset($_POST['cancel_AddDeconf'])) {
421       $this->dialog = FALSE;
422     }
424     /* Save add debconf dialog */
425     if (isset($_POST['save_AddDebconf'])) {
426       $this->dialog->save_object();
427       $msgs = $this->dialog->check();
428       if (count($msgs)>0) {
429         foreach($msgs as $msg){
430           msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
431         }
432       }else {
433           $new_config = $this->dialog->DebconfConfiguration;
434           $this->dialog = FALSE;
435           $package = $new_config['Package'];
436           $name = $new_config['FAIvariable'];
437           $data = array(
438                         'Name' => $name,
439                         'Value' => $new_config['FAIvariableContent'],
440                         'Type' => $new_config['FAIvariableType'],
441                         'Save' => TRUE,
442                         'Status' => 'manually_added',
443                        );
444           $this->DebconfConfigurations[$package][$name] = $data;
445       }
446     }
448     /* Handle the classical debconf dialog */
449     /* Cancel configuration */
450     if(isset($_POST['CancelObjectConfig'])){
451       $this->dialog = false;
452       $this->is_dialog=false;
453     }
455     /* Save Configuration */
456     if(isset($_POST['SaveObjectConfig'])){
457       if(!preg_match("/^freeze/", $this->FAIstate)){
458         $result = $this->dialog->save();
459         foreach($this->packages as $package) {
460           if (isset($result[$package])) {
461             foreach($result[$package] as $attr => $data) {
462                 $identifier = sprintf("%s/%s", $package, $attr);
463                 $this->UpdateEntry($identifier, $data['Value']);
464                 $this->ToggleSave($identifier, $data['Save']);
465             }
466           }
467         }
468       }
469       $this->dialog = false;
470       $this->is_dialog=false;
471     }
473   }
475   /* Check supplied data */
476   function check()
477   {
478     /* Call common method to give check the hook */
479     $message= plugin::check();
480     $message = array();
482     foreach($this->DebconfConfigurations as $package => $package_data) {
483       foreach($package_data as $debconf_info) {
484         /* Do not show errors for values which are not saved to LDAP */
485         if (!$debconf_info['Save'] or (isset($debconf_info['Status']) && $debconf_info['Status']=='removed')) {
486           continue;
487         }
488         if ($debconf_info['Type'] == 'boolean') {
489           if (!empty($debconf_info['Value'])) {
490             $value = strtolower($debconf_info['Value']);
491           } else {
492             $value = "";
493           }
495           if (!$this->normalize_bool($value, TRUE)) {
496             $message[] = sprintf(_("The specified value '%s' for variable '%s' is not valid with the specified boolean variable type.<br><i>Allowed values: true, false, 1, 0.</i>"), $debconf_info['Value'], $debconf_info['Name']);
497           }
498       }
499      }
500     }
502     return ($message);
503   }
505   function save()
506   {
507     $this->save_object();
508     return($this->DebconfConfigurations);
509   }
511 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
512 ?>