Code

a6a7e8ac6f7f48c311a7bfe6e94b632ff6e9af8a
[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;
44       
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                 if (!isset($this->DebconfDefaults[$package][$template['Name']])) {
84                   $this->DebconfDefaults[$package][$template['Name']] = $template;
85                 }
86               } 
87             }
88           }
89         }
90       }
91     }
94     /*! \brief  Returns a html interface, that allow to modify 
95                  the package attributes.
96         @return String  HTML content/ui for this plugin
97      */
98     function execute()
99     {
100       /* Call parent execute */
101       plugin::execute();
103       ksort($this->DebconfConfigurations);
105       if(is_object($this->dialog)) {
106         $this->dialog->save_object();
107       $display = $this->dialog->execute();
108       return($display);
109     }
111     $divlist = new divSelectBox("faiDebconfConfigurations");
112     $divlist->setHeight(400);
114     /* Define header */
115     $field1 = array ("string" => "<b>" . _("Package") . "</b>");
116     $field2 = array ("string" => "<b>" . _("Variable") . "</b>");
117     $field3 = array ("string" => "<b>" . _("Type"). "</b>");
118     $field4 = array ("string" => "<b>" . _("Value") . "</b>");
119     $field5 = array ("string" => "");
120     $divlist->AddEntry(array($field1,$field2,$field3,$field4,$field5));
122     /* Define some vars we will need in the following loop */
123     $str_reset = "<input type='image' title='"._("Reset")."'
124       src='images/lists/reload.png' name='reset_%s'>&nbsp;";
125     $str_delete = "<input type='image' title='"._("Delete")."'
126       src='images/lists/trash.png' name='reset_%s'>&nbsp;";
127     $str_edit = "<input type='image' title='"._("Edit")."'
128       src='images/lists/edit.png' name='edit_%s'>&nbsp;";
129     $str_input = "<input type=text length=100 value=\"%s\" name='val_%s' %s>";
131     /* Merge defaults into display */
132     if ($this->merge_defaults_into_view) {
133       $defaults = array();
134       foreach($this->DebconfDefaults as $package => $package_data){
135         foreach($package_data as $debconf_info) {
136             $name = $debconf_info['Name'];
137             $value = $debconf_info['Default'];
138             $type = $debconf_info['Type'];
139             if(!in_array($type,array("boolean","multiselect","password","select","string","text"))){
140               continue;
141             }
142             $defaults[$package][$name] = array( 'Name' => $name, 'Value' => $value, 'Type' => $type);
143         }
144       }
145       $this->DebconfAll = $this->DebconfConfigurations;
146       
147       foreach($this->packages as $package) {
148         if (isset($defaults[$package])) {
149           if (isset($this->DebconfConfigurations[$package])) {
150             $this->DebconfAll[$package] = array_merge($defaults[$package], $this->DebconfConfigurations[$package]);
151           }else {
152             $this->DebconfAll[$package] = $defaults[$package];
153           }
155         }
157       }
158     } else {
159       $this->DebconfAll = $this->DebconfConfigurations;
160     }
161     ksort($this->DebconfAll);
163     /* Build package list */
164     $defaults_count = count($this->DebconfDefaults);
165     foreach($this->DebconfAll as $package => $package_data) {
166       foreach($package_data as $debconf_info) {
167         /* Do not show removed entries */
168         if (isset($debconf_info['Status']) && $debconf_info['Status'] == 'removed') {
169           continue;
170         }
172         /* Base64-encoded identifier for every package/debconf_data combination
173          * is in the form of packge/Name e.g. locales/locales/locales_to_generate */
174         $identifier = base64_encode(sprintf("%s/%s",$package, $debconf_info['Name']));
176         /* Define actions for this entry */ 
177         $actions = "";
178         if(!preg_match('/^freeze/', $this->FAIstate) && 
179           $this->acl_is_writeable("FAIdebconfInfo")) {
180             /* Don't enable actions if no gosa-si defaults available */
181             $show_reset = FALSE;
182             $show_edit = FALSE;
183             $show_blank = FALSE;
184             if ($defaults_count != 0) {
185                 $name = $debconf_info['Name'];
187                 if (isset($this->DebconfDefaults[$package][$name])) {
188                   $show_edit = TRUE;
189                 }
190                 else {
191                   $show_delete = TRUE;
192                 }
194                 if (isset($this->DebconfConfigurations[$package][$name]) && isset($this->DebconfDefaults[$package][$name])) {
195                   $val = $this->DebconfConfigurations[$package][$name]['Value'];
196                   $default_val = $this->DebconfDefaults[$package][$name]['Default'];
197                   /* Make values comparable */
198                   if (is_array($val)) {
199                     $val = "";
200                   }
201                   if ($val != $default_val) {
202                     $show_reset = TRUE;
203                   }
204                   else {
205                     $show_blank = TRUE;
206                   }
207                 }elseif (!isset($this->DebconfConfigurations[$package][$name]) && isset($this->DebconfDefaults[$package][$name])) {
208                   $show_blank = TRUE;
209                 }
210             }
212             if ($show_reset) {
213                 $actions .= sprintf("$str_reset", $identifier);
214             } elseif ($show_blank) {
215                 $actions .= "<img src='images/empty.png' width=18>";
216             } else {
217                 $actions .= sprintf("$str_delete", $identifier);
218             }
219             if ($show_edit) {
220               $actions .= sprintf("$str_edit", $identifier);
221             }
222         }
224         /* Do not allow editing if FAIstate is freeze */
225         $input_disabled = "";
226         if (preg_match('/^freeze/', $this->FAIstate)) {
227           $input_disabled = "disabled";
228         }
230         /* Pre-Fill input field with the defined value */
231         $input_value = "";
232         if (!empty($debconf_info['Value'])) {
233           $input_value = htmlentities($debconf_info['Value']);
234         }
235         $input_field = sprintf("$str_input", $input_value, $identifier, $input_disabled);
238         $field1 = array( "string" => $package, "attach" => "style='width:120px;'" );
239         $field2 = array( "string" => $debconf_info['Name']);
240         $field3 = array( "string" => $debconf_info['Type'],"attach" => "style='width:100px;'");
241         $field4 = array( "string" => $input_field);
242         $field5 = array( "string" => $actions, "attach" => "style='width:50px; border-right:0px;'");
243         $divlist->AddEntry(array($field1, $field2, $field3, $field4, $field5));
244       }
245     }
246     /* Fill templating stuff */
247     $smarty     = get_smarty();
248     $smarty->assign("divlist", $divlist->DrawList());
249     $smarty->assign("headline", sprintf(_("Debconf information for package list '%s'"), $this->package_list));
250     return($smarty->fetch(get_template_path('faiDebconfConfigurations.tpl', TRUE)));
251   }
254   function normalize_bool($bool_value, $check_mode=FALSE) {
255     $bool_value = strtolower($bool_value);
256     if(isset($this->bool_mapping[$bool_value])) {
257       return $this->bool_mapping[$bool_value];
258     } else {
259       return ($check_mode) ? FALSE : $bool_value;
260     }
261   }
263   /*! \brief Return the components of an identifier as an array of two elements */
264   function getIdentifierComponents($identifier) {
265     $identifier_components = explode('/', $identifier);
266     $package = $identifier_components[0];
267     $name = preg_replace("/^".$package."\//", "", $identifier, 1);
268     return(array($package, $name));
269   }
271   function DeleteEntry($identifier) {
272     list($package, $name) = $this->getIdentifierComponents($identifier);
273     if (isset($this->DebconfConfigurations[$package][$name])) {
274       $this->to_remove[$package][$name] = $this->DebconfConfigurations[$package][$name];
275       unset($this->DebconfConfigurations[$package][$name]);
276     }
277   }
279   function UpdateEntry($identifier, $newval="") {
280     list($package, $name) = $this->getIdentifierComponents($identifier);
281     if (!isset($this->DebconfConfigurations[$package][$name])) {
282       $this->DebconfConfigurations[$package][$name] = $this->DebconfDefaults[$package][$name];
283     }
285     /* Normalize boolean values */
286     if ($this->DebconfConfigurations[$package][$name]['Type'] == 'boolean') {
287       $newval = $this->normalize_bool($newval);
288     }
290     $this->DebconfConfigurations[$package][$name]['Value'] = $newval;
292     if (isset($this->DebconfDefaults[$package][$name])) {
293       $default_value = $this->DebconfDefaults[$package][$name]['Default'];
295       if ($default_value == $newval) {
296         $dn = "FAIvariable=".$name.",".$this->parent->dn;
297         $ldap = $this->config->get_ldap_link();
298         $ldap->cat($dn);
299         if ($ldap->count()) {
300           $attrs = $ldap->fetch();
301           if (isset($attrs['FAIvariableContent']) && $attrs['FAIvariableContent'][0] == $newval) {
302             /* Do not store default values unless its still a change compared to the LDAP */
303             unset($this->DebconfConfigurations[$package][$name]);
304           } else {
305             /* Values different from the default reset removal status */
306             unset($this->to_remove[$package][$name]);
307           }
308         } else {
309           unset($this->DebconfConfigurations[$package][$name]);
310         }
311       }
312       else {
313         /* Values different from the default reset removal status */
314         unset($this->to_remove[$package][$name]);
315       }
316     }
317     else {
318       /* This is no entry with a default value setting, so a new value removes
319        * the removal status */
320       if (isset($this->to_remove[$package][$name])) {
321         unset($this->to_remove[$package][$name]);
322       }
323     }
325     if (isset($this->DebconfConfigurations[$package][$name]) && !$this->DebconfConfigurations[$package][$name]['Value']) {
326         $this->DebconfConfigurations[$package][$name]['Value'] = array();
327     }
328   }
330   /* Save data to object */
331   function save_object()
332   {
333      /* Process values */
334     if (isset($_POST['update_values'])) {
335       foreach($this->DebconfAll as $package => $package_data) {
336           foreach($package_data as $debconf_info) {
337               $identifier = sprintf("%s/%s",$package, $debconf_info['Name']);
338               $post_key = sprintf("val_%s", base64_encode($identifier));
339               if (isset($_POST[$post_key])) {
340                 $this->UpdateEntry($identifier, get_post($post_key));
341               }
342               else {
343                 $this->UpdateEntry($identifier);
344               }
345           }
346       }
347     }
349     foreach($_POST as $key => $value) {
350       if (preg_match("/^reset_/", $key)) {
351         $identifier = base64_decode(str_replace("reset_", "", $key));
352         $this->DeleteEntry($identifier);
353         break;
354       }
356       if (preg_match("/^edit_/", $key)) {
357         $identifier = base64_decode(str_replace("edit_", "", $key));
358         list($package, $name) = $this->getIdentifierComponents($identifier);
359         $this->dialog = new faiPackageConfiguration($this->config, $this->parent->dn, $package, $this->release, $this->DebconfConfigurations[$package]);
360         $this->dialog->used_by_faiDebconfConfigurations = TRUE;
361         break;
362       }
363       if (preg_match("/^NewDebconfEntry$/", $key)) {
364         $this->dialog = new NewDebconfConfiguration($this->config, $this->parent->dn, $this);
365         $this->is_dialog = TRUE;
366         break;
367       }
368     }
369  
370     /* Cancel add debconf dialog */
371     if (isset($_POST['cancel_AddDeconf'])) {
372       $this->dialog = FALSE;
373     }
375     /* Save add debconf dialog */
376     if (isset($_POST['save_AddDebconf'])) {
377       $this->dialog->save_object();
378       $msgs = $this->dialog->check();
379       if (count($msgs)>0) {
380         foreach($msgs as $msg){
381           msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
382         }
383       }else {
384           $new_config = $this->dialog->DebconfConfiguration;
385           $this->dialog = FALSE;
386           $package = $new_config['Package'];
387           $name = $new_config['FAIvariable'];
388           $data = array(
389                         'Name' => $name,
390                         'Value' => $new_config['FAIvariableContent'],
391                         'Type' => $new_config['FAIvariableType'],
392                         'Status' => 'manually_added',
393                        );
394           $this->DebconfConfigurations[$package][$name] = $data;
395       }
396     }
398     /* Handle the classical debconf dialog */
399     /* Cancel configuration */
400     if(isset($_POST['CancelObjectConfig'])){
401       $this->dialog = false;
402       $this->is_dialog=false;
403     }
405     /* Save Configuration */
406     if(isset($_POST['SaveObjectConfig'])){
407       if(!preg_match("/^freeze/", $this->FAIstate)){
408         $result = $this->dialog->save();
409         foreach($this->packages as $package) {
410           if (isset($result[$package])) {
411             foreach($result[$package] as $attr => $data) {
412                 $identifier = sprintf("%s/%s", $package, $attr);
413                 $this->UpdateEntry($identifier, $data['Value']);
414             }
415           }
416         }
417       }
418       $this->dialog = false;
419       $this->is_dialog=false;
420     }
421   }
423   /* Check supplied data */
424   function check()
425   {
426     /* Call common method to give check the hook */
427     $message= plugin::check();
428     $message = array();
430     foreach($this->DebconfConfigurations as $package => $package_data) {
431       foreach($package_data as $debconf_info) {
432         if ($debconf_info['Type'] == 'boolean') {
433           if (!empty($debconf_info['Value'])) {
434             $value = strtolower($debconf_info['Value']);
435           } else {
436             $value = "";
437           }
439           if (!$this->normalize_bool($value, TRUE)) {
440             $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']);
441           }
442       }
443      }
444     }
446     return ($message);
447   }
449   function save()
450   {
451     $this->save_object();
452     return($this->DebconfConfigurations);
453   }
455 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
456 ?>