Code

7b1867c7926adde5ccc49082dd57c0017d871e43
[gosa.git] / gosa-core / include / class_filter.inc
1 <?php
3 class filter {
5   var $xmlData;
6   var $elements= array();
7   var $elementValues= array();
8   var $alphabetElements= array();
9   var $search;
10   var $definition;
11   var $category= "";
12   var $objectStorage= array();
13   var $objectBase= "";
14   var $base= "";
15   var $bases= array();
16   var $scope= "";
17   var $query;
18   var $baseMode= false;
19   var $scopeMode= "auto";
20   var $alphabet= null;
21   var $templatePath= "";
22   var $target= "";
24   function filter($filename)
25   {
26     if (!$this->load($filename)) {
27       die("Cannot parse $filename!");
28     }
29   }
31   function load($filename)
32   {
33     // Load data into array
34     $xmlData= simplexml_load_file($filename);
35     if ($xmlData === false) {
36       return false;
37     }
39     // Load definition
40     if (isset($xmlData->definition)) {
41       foreach ($xmlData->definition as $entry) {
42         if (!isset($entry->target) || !isset($entry->template)) {
43           return false;
44         }
46         // Move information
47         $this->templatePath= (string)$entry->template;
48         $this->target= (string)$entry->target;
50         // One is enough
51         break;
52       }
53     }
55     // Load filter
56     if (isset($xmlData->search)) {
57       foreach ($xmlData->search as $entry) {
58         if (!isset($entry->query) || !isset($entry->base) || !isset($entry->scope)) {
59           return false;
60         }
62         // Move information
63         $this->baseMode= (string)$entry->base;
64         $this->scopeMode= (string)$entry->scope;
65         $this->query= $entry->query;
67         // One is enough
68         break;
69       }
70     }
72     // Generate formular data
73     if (isset($xmlData->element)) {
74       foreach ($xmlData->element as $element) {
76         // Ignore elements without type
77         if (!isset($element->type)) {
78           next;
79         }
81         $tag= (string)$element->tag;
83         // Store element for quick access
84         $this->elements[$tag] = $element;
86         // Preset elementValues with default values if exist
87         if (isset($element->default)) {
88           $this->elementValues[$tag] = (string)$element->default;
89         } else {
90           $this->elementValues[$tag] = "";
91         }
93         // Does this element react on alphabet links?
94         if (isset($element->alphabet) && (string)$element->alphabet == "true") {
95           $this->alphabetElements[]= $tag;
96         }
97       }
98     }
100     // Save definition
101     if (isset($xmlData->definition)) {
102      $this->definition = $xmlData->definition;
103     }
105     // Save search
106     if (isset($xmlData->search)) {
107      $this->search = $xmlData->search;
108     }
110     return true;  
111   }
114   function getTextfield($element)
115   {
116     $tag= (string)$element->tag;
117     $result= "<input class='filter_textfield' id='$tag' name='$tag' type='text' size='30' maxlength='30' value='".$this->elementValues[$tag]."'>";
118     if (isset($element->autocomplete)) {
119       $frequency= "0.5";
120       $characters= "1";
121       if (isset($element->autocomplete->frequency)) {
122         $frequency= (string)$element->autocomplete->frequency;
123       }
124       if (isset($element->autocomplete->characters)) {
125         $characters= (string)$element->autocomplete->characters;
126       }
127       $result.= "<div id='autocomplete$tag' class='autocomplete'></div>".
128                 "<script type='text/javascript'>".
129                 "new Ajax.Autocompleter('$tag', 'autocomplete$tag', 'autocomplete.php', { minChars: $characters, frequency: $frequency });".
130                 "</script>";
131     }
132     return $result;
133   }
136   function getCheckbox($element)
137   {
138     $tag= (string)$element->tag;
139     $checked= "";
140     if ($this->elementValues[$tag] == "true") {
141       $checked= " checked";
142     }
144     $result= "<input class='filter_checkbox' name='$tag' type='checkbox' onClick='document.mainform.submit();' value='true'$checked>";
145     return $result;
146   }
149   function getCombobox($element)
150   {
151     $result= "<select name='".$element->tag."' size='1' onClick='document.mainform.submit();'>";
152     foreach ($element->value as $key=>$value) {
153       $selected= "";
154       if ($this->elementValues[(string)$element->tag] == $value->key) {
155         $selected= " selected";
156       }
157       $result.= "<option value='".$value->key."'$selected>{t}".$value->set."{/t}</option>";
158     }
159     $result.= "</select>";
161     return $result;
162   }
165   function getCurrentBase()
166   {
167     if (isset($this->search->base) && (string)$this->search->scope != "auto") {
168       return false;
169     }
171     return $this->base;
172   }
175   function getCurrentScope()
176   {
177     if (isset($this->search->scope) && (string)$this->search->scope != "auto") {
178       return (string)$this->search->scope;
179     }
181     return $this->scope;
182   }
185   function setBases($bases) {
186     $this->bases= $bases;    
187   }
190   function setObjectStorage($storage) {
191     $this->objectStorage= $storage;    
192   }
195   function setObjectBase($base) {
196     $this->objectBase= $base;    
197   }
200   function setCategory($category) {
201     $this->category= $category;    
202   }
205   function setCurrentBase($base) {
206     $this->base= $base;
207   }
210   function setCurrentScope($scope) {
211     $this->scope= $scope;
212   }
215   function renderBase()
216   {
217     $result= "<select name='currentMainBase' onChange='mainform.submit()' size='1'>";
219     foreach ($this->bases as $key=>$value) {
220       $selected= "";
221       if ($key == $this->base) {
222         $selected= " selected";
223       }
224       $result.= "<option value='".$key."'$selected>".$value."</option>";
225     }
226     $result.= "</select>";
228     return $result;
229   }
232   function renderAlphabet($columns= 10)
233   {
234     // Return pre-rendered alphabet if available
235     if ($this->alphabet) {
236       return ($this->alphabet);
237     }
239     $characters= _("*ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
240     $alphabet= "";
241     $c= 0;
243     /* Fill cells with charaters */
244     for ($i= 0, $l= mb_strlen($characters, 'UTF8'); $i<$l; $i++){
245       if ($c == 0){
246         $alphabet.= "<tr>";
247       }
249       $ch = mb_substr($characters, $i, 1, "UTF8");
250       $alphabet.= "<td><a class=\"alphaselect\" href=\"main.php?plug=".
251         validate($_GET['plug'])."&amp;filter=".$ch."\">&nbsp;".$ch."&nbsp;</a></td>";
253       if ($c++ == $columns){
254         $alphabet.= "</tr>";
255         $c= 0;
256       }
257     }
259     /* Fill remaining cells */
260     while ($c++ <= $columns){
261       $alphabet.= "<td>&nbsp;</td>";
262     }
264     /* Save alphabet */
265     $this->alphabet= "<table width='100%'>$alphabet</table>";
267     return ($this->alphabet);
268   }
271   function renderApply()
272   {
273     return ("<input type='submit' name='apply' value='"._("Apply filter")."'>");
274   }
277   function renderScope()
278   {
279     $checked= $this->scope == "sub"?" checked":"";
280     return "<input type='checkbox' name='SCOPE' value='1' onClick='document.mainform.submit();'$checked>&nbsp;"._("Search in subtrees");
281   }
284   function renderFilter()
285   {
286     $smarty= get_smarty();
287     $smarty->assign("ALPHABET", $this->renderAlphabet());
288     $smarty->assign("APPLY", $this->renderApply());
289     $smarty->assign("SCOPE", $this->renderScope());
290     $smarty->assign("BASE", $this->renderBase());
292     // Load template and replace elementsHtml[]
293     foreach ($this->elements as $tag => $element) {
294       $htmlCode= "";
295       switch ($element->type) {
296         case "textfield":
297           $htmlCode = $this->getTextfield($element);
298           break;
300         case "checkbox":
301           $htmlCode = $this->getCheckbox($element);
302           break;
304         case "combobox":
305           $htmlCode = $this->getCombobox($element);
306           break;
308         default:
309           die ("Unknown element type specified!");
310       }
311       $smarty->assign("$tag", $htmlCode);
312     }
314     // Load template
315     return ("<input type='hidden' name='FILTER_LOADED' value='1'>".$smarty->fetch(get_template_path("filter/$this->templatePath")));
316   }
319   function query()
320   {
321     global $class_mapping;
322     $result= array();
324     // Go thru all queries and merge results
325     foreach ($this->query as $query) {
326       if (!isset($query->backend) || !isset($query->filter) || !isset($query->attribute)) {
327         die("No backend specified in search config.");
328       }
330       // Is backend available?
331       $backend= "filter".(string)$query->backend;
332       if (!isset($class_mapping["$backend"])) {
333         die("Invalid backend specified in search config.");
334       }
336       // Load filter and attributes
337       $filter= $query->filter;
338       $attributes= array();
339       foreach($query->attribute as $attr) {
340         $attributes[]= (string)$attr;
341       }
343       // Generate final filter
344       foreach ($this->elements as $tag => $element) {
345         $e_set= (string)$element->set;
346         $e_unset= (string)$element->unset;
348         if ($this->elementValues[$tag] == "") {
349           $e_unset= preg_replace('/\$/', normalizeLdap($this->elementValues[$tag]), $e_unset);
350           $filter= preg_replace("/\\$$tag/", $e_unset, $filter);
351         } else {
352           $e_set= preg_replace('/\$/', normalizeLdap($this->elementValues[$tag]), $e_set);
353           $filter= preg_replace("/\\$$tag/", $e_set, $filter);
354         }
355       }
357       $result= array_merge($result, call_user_func(array($backend, 'query'), $this->base, $this->scope, $filter, $attributes,
358                                $this->category, $this->objectStorage, $this->objectBase));
359     }
360     
362     return ($result);
363   }
366   function isValid()
367   {
368     foreach ($this->elements as $tag => $element) {
369       if (isset($element->regex)){
370         if (!preg_match('/'.(string)$element->regex.'/', $this->elementValues[$tag])){
371           return false;
372         }
373       }
374     }
375     return true;
376   }
379   function update()
380   {
382     /* React on alphabet links if needed */
383     if (isset($_GET['filter'])){
384       $s= mb_substr(validate($_GET['filter']), 0, 1, "UTF8")."*";
385       if ($s == "**"){
386         $s= "*";
387       }
388       foreach ($this->alphabetElements as $tag) {
389         $this->elementValues[$tag]= $s;
390       }
391     }
393     if (isset($_POST['FILTER_LOADED'])) {
394       // Load post values and adapt filter, base and scope accordingly - but
395       // only if we didn't get a _GET
396       foreach ($this->elements as $tag => $element) {
397         if (isset($_POST[$tag])){
398           $this->elementValues[$tag]= validate($_POST[$tag]);
399         } else {
400           $this->elementValues[$tag]= "";
401         }
402       }
403     }
405     // Save base
406     if (isset($_POST['BASE']) && $this->baseMode == "true") {
407       $base= validate($_POST['BASE']);
408       if (isset($this->bases[$base])) {
409         $this->base= $base;
410       }
411     }
413     // Save scope if needed
414     if ($this->scopeMode == "auto") {
415       $this->scope= isset($_POST['SCOPE'])?"sub":"one";
416     }
417   }
421 ?>