Code

607b95a69489d0154c8a1da08a22ba9e06b85d32
[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 $category= "";
10   var $objectStorage= array();
11   var $objectBase= "";
12   var $base= "";
13   var $bases= array();
14   var $scope= "";
15   var $query;
16   var $baseMode= false;
17   var $scopeMode= "auto";
18   var $alphabet= null;
21   function filter($filename)
22   {
23     if (!$this->load($filename)) {
24       die("Cannot parse $filename!");
25     }
26   }
29   function load($filename)
30   {
31     $contents = file_get_contents($filename);
32     $this->xmlData= xml::xml2array($contents, 1);
34     if (!isset($this->xmlData['filter'])) {
35       return false;
36     }
38     $this->xmlData= $this->xmlData["filter"];
40     // Load filter
41     if (isset($this->xmlData['search'])) {
42       if (!isset($this->xmlData['search']['query'][0])){
43         $this->xmlData['search']['query']= array($this->xmlData['search']['query']);
44       }
46       // Move information
47       $entry= $this->xmlData['search'];
48       $this->baseMode= $entry['base'];
49       $this->scopeMode= $entry['scope'];
50       $this->query= $entry['query'];
51     } else {
52       return false;
53     }
55     // Generate formular data
56     if (isset($this->xmlData['element'])) {
57       if (!isset($this->xmlData['element'][0])){
58         $this->xmlData['element']= array($this->xmlData['element']);
59       }
60       foreach ($this->xmlData['element'] as $element) {
62         // Ignore elements without type
63         if (!isset($element['type']) || !isset($element['tag'])) {
64           next;
65         }
67         $tag= $element['tag'];
69         // Fix arrays
70         if (isset($element['value']) && !isset($element['value'][0])) {
71           $element['value']= array($element['value']);
72         }
74         // Store element for quick access
75         $this->elements[$tag] = $element;
77         // Preset elementValues with default values if exist
78         if (isset($element['default']) && !is_array($element['default'])) {
79           $this->elementValues[$tag] = $element['default'];
80         } else {
81           $this->elementValues[$tag] = "";
82         }
84         // Does this element react on alphabet links?
85         if (isset($element['alphabet']) && $element['alphabet'] == "true") {
86           $this->alphabetElements[]= $tag;
87         }
88       }
89     }
91     return true;  
92   }
95   function getTextfield($element)
96   {
97     $tag= $element['tag'];
98     $result= "<input class='filter_textfield' id='$tag' name='$tag' type='text' size='30' maxlength='30' value='".$this->elementValues[$tag]."'>";
99     if (isset($element['autocomplete'])) {
100       $frequency= "0.5";
101       $characters= "1";
102       if (isset($element['autocomplete']['frequency'])) {
103         $frequency= $element['autocomplete']['frequency'];
104       }
105       if (isset($element['autocomplete']['characters'])) {
106         $characters= $element['autocomplete']['characters'];
107       }
108       $result.= "<div id='autocomplete$tag' class='autocomplete'></div>".
109                 "<script type='text/javascript'>".
110                 "new Ajax.Autocompleter('$tag', 'autocomplete$tag', 'autocomplete.php', { minChars: $characters, frequency: $frequency });".
111                 "</script>";
112     }
113     return $result;
114   }
117   function getCheckbox($element)
118   {
119     $tag= $element['tag'];
120     $checked= "";
121     if ($this->elementValues[$tag] == "true") {
122       $checked= " checked";
123     }
125     $result= "<input class='filter_checkbox' name='$tag' type='checkbox' onClick='document.mainform.submit();' value='true'$checked>";
126     return $result;
127   }
130   function getCombobox($element)
131   {
132     $result= "<select name='".$element['tag']."' size='1' onClick='document.mainform.submit();'>";
133     foreach ($element['value'] as $value) {
134       $selected= "";
135       if ($this->elementValues[$element['tag']] == $value['key']) {
136         $selected= " selected";
137       }
138       $result.= "<option value='".$value['key']."'$selected>{t}".$value['set']."{/t}</option>";
139     }
140     $result.= "</select>";
142     return $result;
143   }
146   function getCurrentBase()
147   {
148     if (isset($this->search->base) && (string)$this->search->scope != "auto") {
149       return false;
150     }
152     return $this->base;
153   }
156   function getCurrentScope()
157   {
158     if (isset($this->search->scope) && (string)$this->search->scope != "auto") {
159       return (string)$this->search->scope;
160     }
162     return $this->scope;
163   }
166   function setBases($bases) {
167     $this->bases= $bases;    
168   }
171   function setObjectStorage($storage) {
172     $this->objectStorage= $storage;    
173   }
176   function setObjectBase($base) {
177     $this->objectBase= $base;    
178   }
181   function setCategory($category) {
182     $this->category= $category;    
183   }
186   function setCurrentBase($base) {
187     $this->base= $base;
188   }
191   function setCurrentScope($scope) {
192     $this->scope= $scope;
193   }
196   function renderBase()
197   {
198     $result= "<select name='currentMainBase' onChange='mainform.submit()' size='1'>";
200     foreach ($this->bases as $key=>$value) {
201       $selected= "";
202       if ($key == $this->base) {
203         $selected= " selected";
204       }
205       $result.= "<option value='".$key."'$selected>".$value."</option>";
206     }
207     $result.= "</select>";
209     return $result;
210   }
213   function renderAlphabet($columns= 10)
214   {
215     // Return pre-rendered alphabet if available
216     if ($this->alphabet) {
217       return ($this->alphabet);
218     }
220     $characters= _("*ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
221     $alphabet= "";
222     $c= 0;
224     /* Fill cells with charaters */
225     for ($i= 0, $l= mb_strlen($characters, 'UTF8'); $i<$l; $i++){
226       if ($c == 0){
227         $alphabet.= "<tr>";
228       }
230       $ch = mb_substr($characters, $i, 1, "UTF8");
231       $alphabet.= "<td><a class=\"alphaselect\" href=\"main.php?plug=".
232         validate($_GET['plug'])."&amp;filter=".$ch."\">&nbsp;".$ch."&nbsp;</a></td>";
234       if ($c++ == $columns){
235         $alphabet.= "</tr>";
236         $c= 0;
237       }
238     }
240     /* Fill remaining cells */
241     while ($c++ <= $columns){
242       $alphabet.= "<td>&nbsp;</td>";
243     }
245     /* Save alphabet */
246     $this->alphabet= "<table width='100%'>$alphabet</table>";
248     return ($this->alphabet);
249   }
252   function renderApply()
253   {
254     return ("<input type='submit' name='apply' value='"._("Apply filter")."'>");
255   }
258   function renderScope()
259   {
260     $checked= $this->scope == "sub"?" checked":"";
261     return "<input type='checkbox' name='SCOPE' value='1' onClick='document.mainform.submit();'$checked>&nbsp;"._("Search in subtrees");
262   }
265   function renderFilter()
266   {
267     $smarty= get_smarty();
268     $smarty->assign("ALPHABET", $this->renderAlphabet());
269     $smarty->assign("APPLY", $this->renderApply());
270     $smarty->assign("SCOPE", $this->renderScope());
271     $smarty->assign("BASE", $this->renderBase());
273     // Load template and replace elementsHtml[]
274     foreach ($this->elements as $tag => $element) {
275       $htmlCode= "";
276       switch ($element['type']) {
277         case "textfield":
278           $htmlCode = $this->getTextfield($element);
279           break;
281         case "checkbox":
282           $htmlCode = $this->getCheckbox($element);
283           break;
285         case "combobox":
286           $htmlCode = $this->getCombobox($element);
287           break;
289         default:
290           die ("Unknown element type specified!");
291       }
292       $smarty->assign("$tag", $htmlCode);
293     }
295     // Load template
296     return ("<input type='hidden' name='FILTER_LOADED' value='1'>".$smarty->fetch(get_template_path("filter/".$this->xmlData['definition']['template'])));
297   }
300   function query()
301   {
302     global $class_mapping;
303     $result= array();
305     // Go thru all queries and merge results
306     foreach ($this->query as $query) {
307       if (!isset($query['backend']) || !isset($query['filter']) || !isset($query['attribute'])) {
308         die("No backend specified in search config.");
309       }
311       // Is backend available?
312       $backend= "filter".$query['backend'];
313       if (!isset($class_mapping["$backend"])) {
314         die("Invalid backend specified in search config.");
315       }
317       // Load filter and attributes
318       $filter= $query['filter'];
319       $attributes= $query['attribute'];
321       // Generate final filter
322       foreach ($this->elements as $tag => $element) {
323         if (!isset($element['set']) || !isset($element['unset'])) {
324           next;
325         }
326         $e_set= is_array($element['set'])?"":$element['set'];
327         $e_unset= is_array($element['unset'])?"":$element['unset'];
329         if ($this->elementValues[$tag] == "") {
330           $e_unset= preg_replace('/\$/', normalizeLdap($this->elementValues[$tag]), $e_unset);
331           $filter= preg_replace("/\\$$tag/", $e_unset, $filter);
332         } else {
333           $e_set= preg_replace('/\$/', normalizeLdap($this->elementValues[$tag]), $e_set);
334           $filter= preg_replace("/\\$$tag/", $e_set, $filter);
335         }
336       }
338       $result= array_merge($result, call_user_func(array($backend, 'query'), $this->base, $this->scope, $filter, $attributes,
339                                $this->category, $this->objectStorage, $this->objectBase));
340     }
341     
343     return ($result);
344   }
347   function isValid()
348   {
349     foreach ($this->elements as $tag => $element) {
350       if (isset($element->regex)){
351         if (!preg_match('/'.(string)$element->regex.'/', $this->elementValues[$tag])){
352           return false;
353         }
354       }
355     }
356     return true;
357   }
360   function update()
361   {
363     /* React on alphabet links if needed */
364     if (isset($_GET['filter'])){
365       $s= mb_substr(validate($_GET['filter']), 0, 1, "UTF8")."*";
366       if ($s == "**"){
367         $s= "*";
368       }
369       foreach ($this->alphabetElements as $tag) {
370         $this->elementValues[$tag]= $s;
371       }
372     }
374     if (isset($_POST['FILTER_LOADED'])) {
375       // Load post values and adapt filter, base and scope accordingly - but
376       // only if we didn't get a _GET
377       foreach ($this->elements as $tag => $element) {
378         if (isset($_POST[$tag])){
379           $this->elementValues[$tag]= validate($_POST[$tag]);
380         } else {
381           $this->elementValues[$tag]= "";
382         }
383       }
384     }
386     // Save base
387     if (isset($_POST['BASE']) && $this->baseMode == "true") {
388       $base= validate($_POST['BASE']);
389       if (isset($this->bases[$base])) {
390         $this->base= $base;
391       }
392     }
394     // Save scope if needed
395     if ($this->scopeMode == "auto") {
396       $this->scope= isset($_POST['SCOPE'])?"sub":"one";
397     }
398   }
402 ?>