Dotclear

source: inc/admin/class.dc.filter.php @ 438:5197b0c2826f

Revision 438:5197b0c2826f, 13.0 KB checked in by Dsls <dsls@…>, 14 years ago (diff)
  • Cleaned up and documented filters code
  • added booleanFilter
  • some l10n added (to be completed)
  • filters are now saved in user preferences
  • fixed a bug in categories filter: cat_id "null ?not" selector now works
Line 
1<?php
2# ***** BEGIN LICENSE BLOCK *****
3# This file is part of DotClear "MyPostTypes" plugin.
4# Copyright (c) 2010 Bruno Hondelatte, and contributors.
5# Many, many thanks to Olivier Meunier and the Dotclear Team.
6# All rights reserved.
7#
8# MyPostTypes plugin for DC2 is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12#
13# DotClear is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17#
18# You should have received a copy of the GNU General Public License
19# along with DotClear; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21#
22# ***** END LICENSE BLOCK *****
23
24/**
25@ingroup DC_CORE
26@nosubgrouping
27@brief Dotclear FilterSet class.
28
29Dotclear FilterSet handles filters and columns when displaying items lists.
30*/
31class dcFilterSet {
32
33     protected $filters;           /// <b>array</b> lists of defined filters
34     protected $form_prefix;       /// <b>string</b> displayed form prefix
35     protected $action;            /// <b>string</b> form action page
36     protected $hideform;          /// <b>boolean</b> start form display hidden by default or not
37     protected $columns_form; /// <b>string</b> columns form
38     protected $name;              /// <b>string</b> fieldset name
39     /**
40     Inits dcFilterSet object
41     
42     @param    core      <b>dcCore</b>       Dotclear core reference
43     @param    form_prefix    <b>string</b>       form prefix to use for parameters
44     */
45     public function __construct($name,$action,$form_prefix="f_") {
46          $this->name = $name;
47          $this->form_prefix=$form_prefix;
48          $this->filters = array();
49          $this->action = $action;
50     }
51
52     /**
53     Adds a new filter to list
54     
55     @param    filter         <b>dcFilter</b>          the filter to add
56     */
57     public function addFilter (Filter $filter) {
58          $filter->setFormPrefix($this->form_prefix);
59          $this->filters[$filter->id] = $filter;
60          return $this;
61     }
62     
63     /**
64     Saves user filters to preferences
65     */
66     protected function saveFilters() {
67          $ser = array();
68          $ws = $GLOBALS['core']->auth->user_prefs->addWorkspace('filters');
69          foreach($this->filters as $filter) {
70               $ser[$filter->id]=$filter->serialize();
71          }
72          $ws->put($this->name,serialize($ser),'string');
73     }
74     
75     /**
76     Loads user filters from preferences
77     */
78     protected function loadFilters() {
79          $ws = $GLOBALS['core']->auth->user_prefs->addWorkspace('filters');
80         
81          $settings = !is_null($ws->{$this->name}) ? unserialize($ws->{$this->name}) : array();
82          foreach($settings as $k => $v) {
83               $this->filters[$k]->unserialize($v);
84          }
85     }
86     
87     /**
88     Updates filters values according to form_data
89     To be called before any call to display() or getForm()
90     
91     @param    form_data <b>array</b>   form values (usually $_GET or $_POST)
92     */
93     public function setValues ($form_data) {
94          $this->hideform = true;
95          if (isset($form_data['clear_filters'])) {
96               $this->saveFilters();
97               return;
98          }
99          if (!isset($form_data['apply'])) {
100               $this->loadFilters();
101          }
102          foreach ($this->filters as $filter) {
103               $filter->setValues ($form_data);
104               if ($filter->isEnabled()) {
105                    $this->hideform=false;
106               }
107          }
108          if (isset($form_data['apply'])) {
109               if (trim($form_data['apply']) == '+'
110                    && isset($form_data['add_filter']) 
111                    && isset($this->filters[$form_data['add_filter']])) {
112                    $this->filters[$form_data['add_filter']]->add();
113                    $this->hideform=false;
114               }
115          }
116          $this->saveFilters();
117     }
118     
119     /**
120     Defines additional form in layout (right column)
121     
122     @param    html <b>string</b>       the code to add
123     */
124     public function setColumnsForm($html)
125     {
126          $this->columns_form = $html;
127     }
128     
129     /**
130     Returns form fields as hidden fields
131     
132     @return   <b>string</b>  the corresponding html code
133     */
134     public function getFormFieldsAsHidden() {
135          $ret='';
136          foreach ($this->filters as $filter) {
137               $ret.= $filter->getFormFieldAsHidden();
138          }
139          return $ret;
140     }
141
142     /**
143     Retrieves filterset generated form
144     
145     @param    method    <b>string</b>       form method to use (default: "get")
146     */
147     public function getForm($method="get") {
148          $ret = '';
149         
150          if ($this->hideform) {
151               $formclass = ' class="hidden"';
152          } else {
153               $formclass='';
154          }
155          $ret .= '<p><img alt="" src="images/minus.png" /> <a href="#" id="toggle-filters">'.__('Toggle filters and display options').'</a></p>';
156          $ret .=
157               '<div class="two-cols">'.
158               '<form id="filters" action="'.$this->action.'" method="'.$method.'" id="filters-form"'.$formclass.'>'.
159               '<div class="col70">'.
160               '<h3>'.__('Entries filters').'</h3>';
161               
162          $count=0;
163          $form_combo=array();
164          $form_combo['-']='';
165          if (count($this->filters)) {
166               $ret .= '<ul>';
167               foreach ($this->filters as $filter) {
168                    if ($filter->isEnabled()) {
169                         $ret .= $filter->getFormLine();
170                    }
171                    $form_combo[$filter->desc]=$filter->id;
172                    $count++;
173               }
174               $ret .= '</ul>';
175          }
176          $ret .= 
177               '<p class="clear"><input class="delete" type="submit" value="'.__('Delete all filters').'" name="clear_filters"></p>'.
178               '<h3 class="margintop">'.__('Add a filter').'</h3>'.
179               '<p id="available_filters">'.
180               form::combo("add_filter",$form_combo).
181               '<input type="submit" value=" + " title="'.__('Add this filter').'" name="apply">'.
182               '</p>'.
183               '</div>'.
184               '<div class="col30">'.
185               $this->columns_form.
186               '</div>'.
187               '<p class="clear margintop"><input type="submit" value="'.__('Apply filters and display options').'" name="apply"></p>'.
188
189               '</form></div>';
190          return $ret;
191     }
192     
193     /**
194     Displays required fieldset http header
195     To be called in page header, of course.
196     */
197     public function header() {
198          return dcPage::jsLoad('js/filters.js');
199     }
200     
201     
202     /**
203     Displays the fieldset
204     */
205     public function display() {
206          echo $this->getForm();
207     }
208
209     /**
210     Applies fieldset and return resulting parameters for request
211     
212     @param    method    <b>string</b>       form method to use (default: "get")
213     @param    method    <b>string</b>       form method to use (default: "get")
214     
215     */
216     public function applyFilters($params) {
217          $filtered = false;
218          foreach ($this->filters as $filter) {
219               if ($filter->isEnabled()) {
220                    $filter->applyFilter($params);
221                    $filtered = true;
222               }
223          }
224          return $filtered;
225     }
226     
227}
228
229
230/**
231@ingroup DC_CORE
232@nosubgrouping
233@brief abstract filter class.
234
235Dotclear Filter handles administration filters for each list
236A filter fills in a parameter array, as defined in dcBlog class
237*/
238abstract class Filter {
239     public $id;                        ///< <b>string</b> field id (local to fieldset)
240     public $desc;                 ///< <b>string</b> field description
241     protected $request_param;     ///< <b>string</b> resulting parameter array key
242     protected $enabled;           ///< <b>string</b> true if filter is enabled
243     protected $values;            ///< <b>array</b> possible filter values
244     public $field_id;             ///< <b>string</b> field id (global to the page)
245     
246     /**
247     Inits Filter object
248     
249     @param    id        <b>string</b>  field id
250     @param    form_prefix    <b>string</b>       form prefix to use for parameters
251     */
252     public function __construct ($id,$desc,$request_param) {
253          $this->id = $id;
254          $this->desc = $desc;
255          $this->request_param = $request_param;
256          $this->enabled=false;
257          $this->values = array();
258          $this->field_id = $this->id;
259     }
260     
261     /**
262     Get a field id
263     
264     @param    pos       <b>integer</b> position of field, in case of multiple field (0 if only 1 field set, default value)
265     @return   <b>string</b> The field ID
266     */
267     protected function getFieldId($pos=0) {
268          if ($pos == 0) {
269               return $this->field_id;
270          } else {
271               return $this->field_id.'_'.$pos;
272          }
273     }
274     
275     /**
276     Tells whether the filter is enabled or not
277     
278     @return   <b>boolean</b> true if enabled, false otherwise
279     */
280     public function isEnabled() {
281          return $this->enabled;
282     }
283     
284     /**
285     Adds the current filter to the list
286     */
287     public function add() {
288          // By default here, only 1 value allowed. Simply enable the filter
289          $this->enabled = true;
290     }
291     
292     /**
293     Defines form prefix for filter
294     
295     @param    prefix         <b>string</b>  the form prefix
296     */
297     public function setFormPrefix($prefix) {
298          $this->field_id = $prefix.$this->id;
299     }
300     
301     
302     /**
303     Returns HTML code for form field
304     
305     @param    pos       <b>integer</b> position of the field to display (in case of multiple values)
306     @return <b>string</b> the html code
307     */
308     public function getFormFields($pos=0) {
309          return '';
310     }
311     
312     /**
313     Returns filter values il a serialized way (array)
314     
315     @return        <b>array</b>   serialized data
316     */
317     public function serialize() {
318          return array(
319               'values' => $this->values,
320               'enabled' => $this->enabled
321          );
322     }
323     
324     /**
325     Defines filter values from serialized data (array)
326     To be used in conjunction with serialize method
327     
328     @param    $data     <b>array</b>   serialized data to retrieve
329     */
330     public function unserialize ($data) {
331          $this->values = $data['values'];
332          $this->enabled = $data['enabled'];
333     }
334     
335     /**
336     Set filter values from form_data (usually $_GET) 
337     @param    $form_data     <b>array</b>   form data
338     */
339     public function setValues($form_data) {
340          $count=0;
341          while (isset($form_data[$this->getFieldId($count)])) {
342               if (!isset($form_data['del_'.$this->getFieldId($count)])) {
343                    $this->values[$count] = $form_data[$this->getFieldId($count)];
344               } elseif (isset($this->values[$count])) {
345                    unset($this->values[$count]);
346               }
347               $count++;
348
349          }
350          $this->values = array_values($this->values);
351          $this->enabled = (count($this->values)!=0);
352     }
353     
354          /**
355     Returns form fields as hidden fields
356     
357     @return   <b>string</b>  the corresponding html code
358     */   
359     public function getFormFieldAsHidden () {
360          $ret='';
361          for ($cur=0; $cur < count($this->values); $cur++) {
362               $ret .= form::hidden($this->getFieldId($cur), $this->values[$cur]);
363          }
364     }
365     /**
366     Returns HTML code for the hole filter lines
367     
368     @return <b>string</b> the html code
369     */
370     
371     public function getFormLine() {
372          $ret="";
373          for ($cur=0; $cur < count($this->values); $cur++) {
374               $ret .= '<li id="'.$this->getFieldId($cur).'" class="line" title="'.$this->desc.'">'.
375                    $this->getFormFields($cur).
376                    '<input id="del_'.$this->getFieldId($cur).'" class="delete" '.
377                    'type="submit" title="Delete the following filter : " value=" - " name="del_'.$this->getFieldId($cur).'"/>'.
378                    '</li>';
379          }
380          return $ret;
381     }
382     
383     /**
384     Convert filter values into a $param filter, used for the upcoming SQL request
385     
386     @param <b>ArrayObject</b> the parameters array to enrich
387     */
388     public function applyFilter($params) {
389     }
390     
391}
392
393/**
394@ingroup DC_CORE
395@nosubgrouping
396@brief abstract filter class.
397
398Handle combo filter on admin side. Can be single or multi-valued
399*/
400class comboFilter extends Filter {
401     protected $options;
402     protected $default;
403     protected $no_value;
404     protected $verb;
405     protected $extra;
406     
407     public function __construct($id,$desc,$request_param,$options,$extra=array()) {
408          parent::__construct($id,$desc,$request_param);
409          $this->options = $options;
410          $this->extra = $extra;
411          $this->desc = $desc;
412          $this->verb = "is";
413          $this->values=array();
414     }
415     
416     public function add() {
417          parent::add();
418          if (isset($this->extra['singleval']) && (count($this->values) > 0))
419               return;
420          $this->values[]=current($this->options);
421     }
422     
423     public function getType() {
424          return "combo";
425     }
426
427     public function serialize() {
428          $data = parent::serialize();
429          $data['verb'] = $this->verb;
430          return $data;
431     }
432     
433     public function unserialize ($data) {
434          parent::unserialize($data);
435          $this->verb = $data['verb'];
436     }
437     
438     public function setValues($form_data) {
439          parent::setValues($form_data);
440          if (isset($form_data[$this->field_id."_v"])) {
441               $this->verb = ($form_data[$this->field_id."_v"] == 'is') ? 'is' : 'isnot';
442          }
443     }
444
445     public function getFormFieldAsHidden () {
446          return parent::getFormFieldAsHidden().form::hidden($this->field_id."_v",$this->verb);
447     }
448
449     public function getFormFields($pos=0) {
450         
451          if ($pos == 0) {
452               $desc = $this->desc.' : ';
453               $labelclass="filter-title";
454          } else {
455               $desc = __('or');
456               $labelclass = 'or';
457          };
458          return '<span class="'.$labelclass.'">'.$desc.'</span>'.
459               (($pos == 0) 
460                    ?form::combo($this->field_id.'_v',
461                         array(__('is')=>'is',__('is not')=>'isnot'),$this->verb,'','',
462                         false,'title="'.sprintf(__('%s is or is not'),$this->desc).'"') 
463                    :'').
464               form::combo($this->getFieldId($pos),$this->options,$this->values[$pos],
465                    '','',false,'title="'.__('Choose an option').'"');
466     }
467     
468     public function applyFilter($params) {
469          $attr = $this->request_param;
470          if ($this->verb != "is") {
471               $params[$attr."_not"] = true;
472          }
473          if (isset($this->extra['singleval']))
474               $params[$attr]=$this->values[0];
475          else
476               $params[$attr]=$this->values;
477     }
478}
479
480/**
481@ingroup DC_CORE
482@nosubgrouping
483@brief abstract filter class.
484
485Handle boolean filter on admin side.
486*/
487class booleanFilter extends Filter {
488     protected $options;
489     
490     public function __construct($id,$desc,$request_param,$options,$extra=array()) {
491          parent::__construct($id,$desc,$request_param);
492          $this->options = $options;
493          $this->values=array();
494     }
495     
496     
497     public function getType() {
498          return "boolean";
499     }
500     public function add() {
501          parent::add();
502          $this->values[]=$options[0];
503     }
504
505     public function getFormFields($pos=0) {
506          return '<span class="'.$labelclass.'">'.$this->desc.'</span>'.
507               form::combo($this->getFieldId($pos),$this->options,$this->values[$pos],
508                    '','',false,'title="'.__('Choose an option').'"');
509     }
510     
511     public function applyFilter($params) {
512          $params[$this->request_param]=$this->values[0];
513     }
514}
515
516?>
Note: See TracBrowser for help on using the repository browser.

Sites map