Dotclear

source: inc/admin/class.dc.filter.php @ 1498:6d67bea812f3

Revision 1498:6d67bea812f3, 26.0 KB checked in by Dsls, 12 years ago (diff)

formfilters improvement, added applied filters features

Line 
1<?php
2# -- BEGIN LICENSE BLOCK ---------------------------------------
3#
4# This file is part of Dotclear 2.
5#
6# Copyright (c) 2003-2013 Olivier Meunier & Association Dotclear
7# Licensed under the GPL version 2.0 license.
8# See LICENSE file or
9# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
10#
11# -- END LICENSE BLOCK -----------------------------------------
12
13if (!defined('DC_RC_PATH')) { return; }
14
15
16/**
17* dcFilterSet -- filter handling object
18*
19* @uses     dcForm
20*
21*/
22class dcFilterSet extends dcForm {
23     /** @var array list of variable filters */
24     protected $filters;
25     /** @var array list of static filters */
26     protected $static_filters;
27     /** @var array list of all filters (union of the 2 previous props) */
28     protected $all_filters;
29     /** @var string prefix to be used for all fields */
30     protected $form_prefix;
31     /** @var string action to perform upon form submission */
32     protected $action;
33     /** @var boolean start form display hidden by default or not */
34     protected $hide_filterset;
35     /** @var string filterset name */
36     protected $name;
37     /** @var dcCore dotclear core object */
38     protected $core;
39     /** @var boolean true if content is filtered */
40     protected $filtered;
41
42    /**
43     * __init__ - class static initialiser (called at the very bottom of this
44     *                   page)
45     *
46     * @param mixed $env the twig environment.
47     *
48     * @access public
49     * @static
50     *
51     */
52     public static function __init__($env) {
53          // filterset widgets are defined in a separate file
54          $env->getExtension('dc_form')->addTemplate(
55               '@forms/formfilter_layout.html.twig'
56          );
57
58          $env->addFunction(
59               new Twig_SimpleFunction(
60                    'filterset',
61                    'dcFilterSet::renderFilterSet',
62                    array(
63                         'is_safe' => array('html'),
64                         'needs_context' => true,
65                         'needs_environment' => true
66          )));
67     }
68
69    /**
70     * __construct -- constructor
71     *
72     * @param dcCore  $core       dotclear core instance.
73     * @param string  $name       filterset name.
74     * @param string  $action     form action.
75     * @param string $form_prefix form prefix.
76     *
77     * @access public
78     *
79     * @return mixed Value.
80     */
81     public function __construct($core,$name,$action,$form_prefix="f_"){
82          $this->form_prefix=$form_prefix;
83          $this->filters = new ArrayObject();
84          $this->static_filters = new ArrayObject();
85          $this->all_filters = new ArrayObject();
86          $this->action = $action;
87          $this->filtered = false;
88          parent::__construct($core,$name,$action,'POST');
89          //$this->id = "filters";
90     }
91
92
93    /**
94     * renderFilterSet -- binding to twig function "filterset"
95     *                             renders a filterset given its name & context
96     * @param mixed $env        Twig environment (passed by Twig template).
97     * @param mixed $context    Context (passed by Twig template).
98     * @param mixed $name       filterset name.
99     * @param array $attributes filterset attributes.
100     *
101     * @access public
102     * @static
103     *
104     * @return mixed Value.
105     */
106     public static function renderFilterSet($env,$context,$name,
107                                                     $attributes=array())  {
108          $context['filtersetname']=$name;
109          echo $env->getExtension('dc_form')->renderWidget(
110               'filterset',
111               $context
112          );
113     }
114
115
116    /**
117     * setup - sets up the form filter from http context
118     *
119     * @access public
120     *
121     * @return mixed Value.
122     */
123     public function setup() {
124          $form_combo = array();
125          $form_combo['-'] = '';
126          foreach ($this->all_filters as $filter) {
127               $filter->init();
128          }
129          foreach ($this->filters as $filter) {
130               $form_combo[$filter->id]=$filter->name;
131          }
132          $p = $this->form_prefix;
133          $this
134               ->addField (
135                    new dcFieldCombo ($p.'add_filter','',$form_combo,
136                         array()))
137               ->addField (
138                    new  dcFieldSubmit($p.'add',__('Add this filter'),
139                         array()))
140               ->addField (
141                    new dcFieldSubmit($p.'clear_filters',__('Delete all filters'),
142                         array()))
143               ->addField (
144                    new dcFieldSubmit($p.'apply',
145                         __('Apply filters and display options'),
146                         array()))
147               ->addField (
148                    new dcFieldSubmit($p.'reset',__('Reset'),
149                         array()))
150          ;
151          $this->setupFields();
152          /*  Since we have specific handling for actions
153              (for instance "del_*" fields), we do not take advantage of
154              submitfields features, actions are performed manually here.
155
156               Use cases :
157               (1) $_POST not empty for formfilter fields :
158                    * filters are set from $_POST
159                    * applied filters values are set from $_GET
160                    * keep filters div shown
161               (2) $_POST empty :
162                    * both filters fields & applied values are set from $_GET
163                    * hide filter div
164          */
165          $action = false;
166          //$allowed_actions = array('clear_filters','add','del_.*','apply','reset');
167          $allowed_actions = '#^(clear_filters|add|del_.*|apply|reset)$#';
168
169          // Fetch each $_POST parameter to see whether filters are concerned.
170          // Only 1 action at a time is allowed.
171          foreach ($_POST as $k => $v) {
172               if (strpos($k,$this->form_prefix)===0) {
173                    $tmp = substr($k,strlen($this->form_prefix));
174                    $count = preg_match($allowed_actions,$tmp,$match);
175                    if ($count==1) {
176                         $action = $match[1];
177                         break;
178                    }
179               }
180          }
181          $this->hide_filterset = true;
182          if ($action !== false) {
183               // Use case (1)
184               if ($action != 'clear_filters' && $action != 'reset')  {
185                    // initialize fields from $_POST
186                    $this->setupEditFilters($this->all_filters,$_POST);
187                    if ($action == 'add'){
188                         // Add a new filter
189                         $fname = $p.'add_filter';
190                         if (isset($_POST[$fname])
191                              && isset($this->filters[$_POST[$fname]])) {
192                              $this->filters[$_POST[$fname]]->add();
193                         }
194                         $this->hide_filterset = false;
195                    } elseif (strpos($action,'del_') === 0) {
196                         // Remove a filter
197                         $count = preg_match('#del_(.+)_([0-9]+)#',$action,$match);
198                         if (($count == 1) && isset($this->filters[$match[1]])) {
199                              $this->filters[$match[1]]->remove($match[2]);
200                         }
201                         $this->hide_filterset = false;
202                    } elseif ($action=="apply") {
203                         // Apply all filters
204                         // ==> store filter to preferences and redirect to
205                         //     page with filter as $_GET attributes
206                         $data = $this->saveFilters();
207                         $query = http_build_query($data,'','&');
208                         if ($query != '') {
209                              $query = (strpos($this->action,'?') === false ? '?' : '&').$query;
210                         }
211                         http::redirect($this->action.$query);
212                         exit;
213                    }
214               }
215               // Form as been submitted with POST method, retrieve
216               // applied filter values from "query" field
217               if (isset($_POST[$p."query"])) {
218                    parse_str($_POST[$p."query"],$out);
219                    $this->setupAppliedValues($this->all_filters,$out);
220                    if ($action == 'reset') {
221                         // RESET action => set fields from query field
222                         $this->setupEditFilters($this->all_filters,$out);
223                    } elseif ($action == 'clear_filters') {
224                         $this->setupEditFilters($this->static_filters,$out);
225                         foreach ($this->filters as $f) {
226                              $f->cleanup();
227                         }
228                    }
229               }
230          } else {
231               // Use case (2) : GET method; set both filters and applied values
232               // from GET args or from settings if no GET args.
233               $load_from_settings = true;
234               foreach($_GET as $k=>$v) {
235                    if (strpos($k,$this->form_prefix)===0) {
236                         $load_from_settings=false;
237                         break;
238                    }
239               }
240               $get = $_GET;
241               if ($load_from_settings) {
242                    $get = array_merge($this->loadFilters(),$get);
243               }
244               $this->setupEditFilters($this->all_filters,$get);
245
246               $this->setupAppliedValues($this->all_filters,$get);
247          }
248          foreach ($this->static_filters as $f) {
249               if (!$f->isEnabled()) {
250                    $f->add();
251               }
252          }
253          $queryParams = $this->getAppliedFilterValues();
254          $this->addField(
255               new dcFieldHidden($this->form_prefix.'query',
256                    http_build_query($queryParams)));
257          // form context is set through a global twig variable
258          $this->core->tpl->addGlobal(
259               'filterset_'.$this->name,
260               $this->getContext());
261     }
262
263     public function getURLParams() {
264          return $this->getAppliedFilterValues()->getArrayCopy();
265     }
266
267    /**
268     * saveFilters - save user defined filters into preferences
269     *
270     * @access protected
271     */
272     protected function saveFilters() {
273          $ser = array();
274          $ws = $GLOBALS['core']->auth->user_prefs->addWorkspace('filters');
275          $data= $this->serialize();
276          $ws->put($this->name,serialize($data->getArrayCopy()),'string');
277          return $data;
278     }
279
280    /**
281     * loadFilters - load user filters from preferences
282     *
283     * @access protected
284     *
285     * @return mixed Value.
286     */
287     protected function loadFilters() {
288          $ws = $GLOBALS['core']->auth->user_prefs->addWorkspace('filters');
289          $data = (!is_null($ws->{$this->name}))
290               ? unserialize($ws->{$this->name})
291               : array();
292          if (is_array($data))
293               return $data;
294          else
295               return array();
296     }
297
298    /**
299     * setupEditFilters - Updates filters fields according to form_data
300     *                        To be called before any call to display() or getForm()
301     *
302     * @param array $filters   list of filters to update
303     * @param array $form_data form values (usually $_GET or $_POST)
304     *
305     * @access protected
306     *
307     * @return mixed Value.
308     */
309     protected function setupEditFilters ($filters,$form_data) {
310          foreach ($filters as $filter) {
311               $filter->setupFields ($form_data);
312          }
313     }
314
315    /**
316     * setupAppliedValues - Updates filters applied values according to
317     *                             form_data
318     *
319     * @param array $filters   list of filters to update
320     * @param array $form_data form values (usually $_GET or $_POST)
321     *
322     * @access protected
323     *
324     * @return mixed Value.
325     */
326     protected function setupAppliedValues ($filters,$form_data) {
327          foreach ($filters as $filter) {
328               $filter->setupAppliedValue ($form_data);
329          }
330     }
331
332    /**
333     * serialize - retrieves filter applied values in a serialized form
334     *
335     * @access protected
336     *
337     * @return ArrayObject serialized data.
338     */
339     protected function serialize() {
340          $arr = new ArrayObject();
341          foreach ($this->filters as $f) {
342               if ($f->isEnabled()) {
343                    $f->serialize($arr);
344               }
345          }
346          foreach ($this->static_filters as $f) {
347               $f->serialize($arr);
348          }
349          return $arr;
350     }
351
352    /**
353     * addFilter - registers a new filter in filterset
354     *
355     * @param mixed \dcFilter the filter.
356     *
357     * @access public
358     *
359     * @return dcFilterSet the filterset (enabling to chain addFilter).
360     */
361     public function addFilter (dcFilter $filter) {
362          $filter->setFormPrefix($this->form_prefix);
363          $filter->setFilterSet($this);
364          $this->all_filters[$filter->id] = $filter;
365          if ($filter->isStatic()) {
366               $this->static_filters[$filter->id] = $filter;
367          } else {
368               $this->filters[$filter->id] = $filter;
369          }
370          return $this;
371     }
372
373    /**
374     * getContext - retrieves current filterset context
375     *                   (to be given to twig template)
376     *
377     * @access public
378     *
379     * @return array the context
380     */
381     public function getContext() {
382          $fcontext = new ArrayObject();
383          $sfcontext = new ArrayObject();
384          $afcontext = new ArrayObject();
385          foreach ($this->filters as $f) {
386               if($f->isEnabled()) {
387                    $f->appendFilterContext($fcontext);
388               }
389          }
390          foreach ($this->static_filters as $f) {
391               $f->appendFilterContext($sfcontext);
392          }
393          foreach ($this->filters as $f) {
394               if ($f->isApplied()) {
395                    $afcontext[] = $f->getAppliedFilterText();
396               }
397          }
398          return array(
399               'active_filters' => $fcontext,
400               'static_filters' => $sfcontext,
401               'applied_filters' => $afcontext,
402               'hide_filters'  => $this->hide_filterset,
403               'prefix'        => $this->form_prefix);
404     }
405
406    /**
407     * getAppliedFilterValues - retrieves the list of applied filter values
408     *
409     * @access protected
410     *
411     * @return ArrayObject the list of applied values
412     */
413     protected function getAppliedFilterValues() {
414          $arr = new ArrayObject();
415          foreach ($this->all_filters as $f) {
416               if ($f->isApplied())
417                    $f->updateAppliedValues($arr);
418          }
419          return $arr;
420     }
421
422    /**
423     * applyFilters -- applies filterset
424     *
425     * @param mixed $params the parameters to update.
426     *
427     * @access public
428     *
429     * @return mixed true if at least 1 filter has been applied, false otherwise
430     */
431     public function applyFilters($params) {
432          foreach ($this->all_filters as $filter) {
433               if ($filter->isApplied()) {
434                    $filter->applyFilter($params);
435                    $this->filtered = true;
436               }
437          }
438          return $this->filtered;
439     }
440
441    /**
442     * buildFieldName -- builds a field name given a verb, an id and a position
443     *                        takes the form prefix into consideration
444     * @param mixed $verb     the verb to use (ex  : "del")
445     * @param mixed $field_id the field id
446     * @param mixed $pos      the field position
447     *
448     * @access public
449     *
450     * @return mixed the field name
451     */
452     public function buildFieldName($verb,$field_id,$pos) {
453          return $this->form_prefix.$verb.'_'.$field_id.'_'.$pos;
454     }
455
456}
457
458
459/**
460* dcFilter -- base filter class
461*
462*  A filter can be edited while being applied with other values
463*  that enables to keep the list of applied filters (to display a list of items)
464*  while modifing the filter itself.
465*  Therefore it contains :
466*   * a Field that tracks the currently edited filter
467*   * an applied values that tracks the currently applied filter
468*
469*/
470abstract class dcFilter  {
471     /** @var dcFilterSet filterset parent */
472     public $filterset;
473     /** @var string filter id */
474     public $id;
475     /** @var string filter name */
476     public $name;
477     /** @var string filter description */
478     public $desc;
479     /** @var string filter id (including form prefix) */
480     public $filter_id;
481     /** @var string resulting parameter array key */
482     protected $request_param;
483     /** @var dcField edited field */
484     protected $field;
485     /** @var array currently applied values */
486     protected $avalues;
487     /** @var boolean true if field is static */
488     protected $static;
489     /** @var array generic field options */
490     protected $options;
491     /** @var boolean true if field can have multiple values */
492     protected $multiple;
493
494    /**
495     * __construct -- filter constructor
496     *
497     * @param mixed $id            filter id.
498     * @param mixed $name          filter name.
499     * @param mixed $desc          filter description.
500     * @param mixed $request_param request parameter (see dcBlog::getPosts for
501     *                             instance).
502     * @param array $options       filter options.
503     *
504     * @access public
505     *
506     * @return mixed Value.
507     */
508     public function __construct ($id,$name,$desc,$request_param,$options=array()) {
509          $this->id                     = $id;
510          $this->name              =$name;
511          $this->desc              = $desc;
512          $this->request_param     = $request_param;
513          $this->avalues           = array();
514          $this->filter_id         = $this->id;
515          $this->static            = false;
516          $this->multiple          = false;
517          $this->options           = $options;
518          if (isset($options['static']) && $options['static']) {
519               $this->static       = true;
520          }
521          if (isset($options['multiple']) && $options['multiple']) {
522               $this->multiple          = true;
523          }
524     }
525
526
527    /**
528     * parseData - Extract values from data (data being an array, such as $_GET
529     *                   or $_POST) ; does not update any field, only return parsed
530     *                   data
531     *
532     * @param mixed $data input data.
533     *
534     * @access protected
535     *
536     * @return array an array containing parsed data.
537     */
538     protected function parseData($data) {
539          $arr = $this->field->parseValues($data);
540          return array('values' => $arr);
541     }
542
543    /**
544     * isStatic -- returns whether the filter is static or not
545     *
546     * @access public
547     *
548     * @return boolean true if the filter is static.
549     */
550     public function isStatic() {
551          return $this->static;
552     }
553
554    /**
555     * setupFields -- sets up filter fielt from $_GET or $_POST
556     *
557     * @param mixed $data input data (either $_GET or $_POST).
558     *
559     * @access public
560     *
561     * @return mixed Value.
562     */
563     public function setupFields($data) {
564          $this->field->setup($data);
565     }
566
567
568    /**
569     * init -- initializes filter (called after setup)
570     *
571     * @access public
572     *
573     * @return mixed Value.
574     */
575     public function init() {
576     }
577
578    /**
579     * cleanup - resets filter field to its default value
580     *
581     * @access public
582     *
583     * @return mixed Value.
584     */
585     public function cleanup() {
586          $this->field->setValues(array());
587     }
588
589    /**
590     * setupAppliedValue -- defines field applied values from data
591     *
592     * @param mixed $data data to retrieve values from ($_GET or $_POST).
593     *
594     * @access public
595     *
596     * @return mixed Value.
597     */
598     public function setupAppliedValue($data) {
599          $this->avalues = $this->parseData($data);
600     }
601
602     public function updateAppliedValues($arr) {
603          $arr[$this->filter_id] = $this->avalues['values'];
604     }
605
606    /**
607     * setFilterSet -- sets filterSet for filter
608     *
609     * @param mixed \dcFilterset Description.
610     *
611     * @access public
612     *
613     */
614     public function setFilterSet(dcFilterset $fs) {
615          $this->filterset = $fs;
616     }
617
618    /**
619     * setFormPrefix -- sets filter form prefix
620     *
621     * @param string $prefix the form prefix.
622     *
623     * @access public
624     *
625     * @return mixed Value.
626     */
627     public function setFormPrefix($prefix) {
628          $this->filter_id = $prefix.$this->id;
629     }
630
631    /**
632     * isEnabled -- Tells whether the filter is enabled or not (ie field has
633     *                   at least 1 value defined)
634     *
635     * @access public
636     *
637     * @return mixed true if the filter is enabled.
638     */
639     public function isEnabled() {
640          return count($this->field) != 0;
641     }
642
643     protected abstract function addValue($value=NULL);
644     protected abstract function getAppliedFilterText();
645     
646    /**
647     * add -- adds a value for the filter
648     *
649     * @access public
650     *
651     * @return mixed Value.
652     */
653     public function add() {
654          if (count($this->field) > 1 && !$this->multiple)
655               return;
656          $this->addValue();
657     }
658
659    /**
660     * remove -- Removes a value from filter
661     *
662     * @param mixed $pos value position.
663     *
664     * @access public
665     *
666     * @return mixed Value.
667     */
668     public function remove($pos) {
669          $values = $this->field->getValues();
670          if (isset($values[$pos])) {
671               $this->field->delValue($pos);
672          }
673
674     }
675
676     abstract protected function appendContextLine($ctx,$pos);
677
678    /**
679     * appendFilterContext -- appends current filter context to the given
680     *                        context.
681     *    A filter context consists in a list of array elements, one for
682     *    each field line displayed.
683     *    If a field has multiple values, there will be as many lines as values
684      *
685     *  The twig template then iterates through the array to display
686     *  each and every line
687     * @param mixed $ctx the context to enrich
688     *
689     * @access public
690     *
691     * @return mixed Value.
692     */
693     public function appendFilterContext($ctx) {
694          foreach ($this->field->getValues() as $cur => $f) {
695               /*
696               * each line of context has the following properties :
697               *  * lineclass : <tr> class to use
698               *  * 'del_id' : delete input field name to delete current value
699               *  * other field-type specific values that are set from
700               *         appendContextLine method
701                */
702               $line = new ArrayObject();
703               $line['lineclass'] = $this->id;
704               $line['del_id'] = $this->filterset->buildFieldName('del',$this->id,$cur);
705               // Create the delete field for this line
706               $del = new dcFieldSubmit(
707                    $this->filterset->buildFieldName('del',$this->id,$cur),
708                    '-',
709                    array(
710                         'attr' => array(
711                              'title' => __('Delete the following filter')))
712               );
713               $this->filterset->addField($del);
714               $this->appendContextLine($line,$cur);
715               $ctx[]=$line;
716          }
717     }
718
719    /**
720     * serialize - serializes field value into given array
721     *
722     * @param mixed $arr the context to update.
723     *
724     * @access public
725     *
726     * @return mixed Value.
727     */
728     public function serialize($arr) {
729          if (count($this->fields) == 1) {
730               $arr[$this->filter_id]=$this->field->getValue();
731          } else {
732               $arr[$this->filter_id]=$this->field->getValues();
733          }
734     }
735
736    /**
737     * isApplied -- returns true when the filter is applied
738     *    (ie. has at least 1 applied value)
739     * @access public
740     *
741     * @return mixed Value.
742     */
743     public function isApplied(){
744          return (count($this->avalues['values']) != 0);
745     }
746
747    /**
748     * applyFilter -- Converts filter values into a $param filter, used for the
749     *                    upcoming SQL request
750     *
751     * @param mixed $params Description.
752     *
753     * @access public
754     *
755     * @return mixed Value.
756     */
757     public function applyFilter($params) {
758          return false;
759     }
760
761    /**
762     * header -- tbd
763     *
764     * @access public
765     *
766     * @return mixed Value.
767     */
768     public function header() {
769          return '';
770     }
771
772    /**
773     * getFields -- returns filter field(s)
774     *
775     * @access public
776     *
777     * @return dcField the filter field.
778     */
779     public function getFields() {
780          return $this->field;
781     }
782}
783
784/**
785* dcFilterText - basic single field text filter
786*
787* @uses     dcFilter
788*
789*/
790class dcFilterText extends dcFilter {
791
792    /**
793     * @see dcFilter::init()
794     */
795     public function init() {
796          $this->field = new dcFieldText(
797               $this->filter_id,
798               NULL);
799          $this->filterset->addField($this->field);
800          $this->multiple = false;
801     }
802
803
804    /**
805     * @see dcFilter::appendContextLine()
806     */
807     public function appendContextLine($line,$pos) {
808          /*
809          Extra data provided by this filter :
810          * ffield : field name
811          * display_inline : true if the field is static
812          * fwidget : name of the widget (filter_text)
813          * desc : filter description
814           */
815          $line['ffield'] = $this->field->getName();
816          if ($this->static) {
817               $line['display_inline'] = true;
818          }
819
820          if ($pos == 0) {
821               $line['fwidget']='filter_text';
822               $line['desc']=$this->desc;
823          };
824     }
825
826    /**
827     * @see dcFilter::addValue()
828     */
829    protected function addValue($value=NULL) {
830          if ($value === NULL) {
831               $value = '';
832          }
833          $this->field->addValue($value);
834     }
835
836    /**
837     * @see dcFilter::applyFilter()
838     */
839     public function applyFilter($params) {
840          $params[$this->request_param]=$this->avalues['values'][0];
841     }
842     
843     public function getAppliedFilterText() {
844          if ($this->isApplied()) {
845               return sprintf(__('%s contains : "%s"'),$this->desc,$this->avalues['values'][0]);
846          }
847     }
848}
849
850/**
851* dcFilterCombo -- combo filter
852*
853* Enables to filter through a list of values, can be used to check
854* if a value is in a list of items
855*
856* @uses     dcFilter
857*
858*/
859class dcFilterCombo extends dcFilter {
860     /** @var combo the list of possible values in combo */
861     protected $combo;
862     
863    /**
864     * @see dcFilter::__construct()
865     */
866     public function __construct($id,$name,$desc,$request_param,$combo,
867                                        $options=array()) {
868          parent::__construct($id,$name,$desc,$request_param,$options);
869          $this->combo = $combo;
870     }
871
872    /**
873     * @see dcFilter::init()
874     */
875     public function init() {
876          echo $this->name.":".($this->multiple?"MULTIPLE":"SIMPLE");
877          $this->field = new dcFieldCombo(
878               $this->filter_id,
879               NULL,
880               $this->combo,array(
881                    'multiple' => $this->multiple));
882          $this->filterset->addField($this->field);
883     }
884
885    /**
886     * @see dcFilter::addValue()
887     */
888     protected function addValue($value=NULL) {
889          if ($value === NULL) {
890               $value = current(array_keys($this->combo));
891          }
892          $this->field->addValue($value);
893     }
894
895    /**
896     * @see dcFilter::init()
897     */
898     public function appendContextLine($line,$pos) {
899          /*
900          Extra data provided by this filter :
901          * ffield : field name
902          * display_inline : true if the field is static
903          * fwidget : name of the widget (filter_combo or filter_combo_cont)
904          * foffset : field value offset
905          * desc : filter description
906          Only the 1st item contains description.
907           */
908          if ($this->static) {
909               $line['display_inline'] = true;
910          }
911          $line['ffield'] = $this->field->getName();
912          $line['foffset'] = $pos;
913          if ($pos == 0) {
914               $line['fwidget']='filter_combo';
915               $line['desc']=$this->desc;
916          } else {
917               $line['fwidget']='filter_combo_cont';
918          };
919     }
920
921    /**
922     * @see dcFilter::applyFilter()
923     */
924     public function applyFilter($params) {
925          $attr = $this->request_param;
926          if ($this->multiple)
927               $params[$attr]=$this->avalues['values'];
928          else
929               $params[$attr]=$this->avalues['values'][0];
930     }
931     public function getAppliedFilterText() {
932          if ($this->isApplied()) {
933               if (count($this->avalues['values'])) {
934                    return sprintf(__("%s is %s"),$this->desc,join(__(' OR '), $this->avalues['values']));
935               } else {
936                    return sprintf(__('%s is %s'),$this->desc,$this->avalues['values'][0]);
937               }
938          }
939     }
940}
941
942/**
943* dcFilterRichCombo -- rich combo filter
944*
945* Same as dcFilterCombo, with the possibility to exclude a list of values
946*
947* @uses     dcFilter
948*
949*/
950class dcFilterRichCombo extends dcFilterCombo {
951     /** @var verb verb field ('is' or 'is not') */
952     protected $verb;
953
954    /**
955     * @see dcFilter::init()
956     */
957     public function init() {
958          parent::init();
959          $this->verb = new dcFieldCombo(
960               $this->filter_id.'_v', 
961               'is',
962               array(
963                    'is'=>__('is'),
964                    'isnot'=>__('is not'))
965          );
966          $this->filterset->addField($this->verb);
967     }
968
969    /**
970     * @see dcFilter::parseData()
971     */
972     protected function parseData($data) {
973          $val = parent::parseData($data);
974          $v = $this->verb->parseValues($data);
975          if (isset($v[0]) && $v[0] === 'isnot')
976               $val['verb'] = 'isnot';
977          else
978               $val['verb'] ='is';
979          return $val;
980     }
981
982    /**
983     * @see dcFilter::setupFields()
984     */
985     public function setupFields($data) {
986          parent::setupFields($data);
987          $this->verb->setup($data);
988     }
989
990    /**
991     * @see dcFilter::updateAppliedValues()
992     */
993     public function updateAppliedValues($arr) {
994          parent::updateAppliedValues($arr);
995          $arr[$this->verb->getName()] = $this->verb->getValue();
996     }
997
998    /**
999     * @see dcFilter::appendContextLine()
1000     */
1001     public function appendContextLine($line,$pos) {
1002          parent::appendContextLine($line,$pos);
1003          if ($pos == 0) {
1004               $line['fverb'] = $this->verb->getName();
1005               $line['fwidget']='filter_richcombo';
1006          }
1007     }
1008
1009    /**
1010     * @see dcFilter::serialize()
1011     */
1012     public function serialize($arr) {
1013          parent::serialize($arr);
1014          $arr[$this->filter_id.'_v']=$this->verb->getValue();
1015     }
1016
1017    /**
1018     * @see dcFilter::applyFilter()
1019     */
1020     public function applyFilter($params) {
1021          parent::applyFilter($params);
1022          $attr = $this->request_param;
1023          if ($this->avalues['verb'] != "is") {
1024               $params[$attr."_not"] = true;
1025          }
1026     }
1027     public function getAppliedFilterText() {
1028          if ($this->isApplied()) {
1029               if ($this->avalues['verb'] == "is") {
1030                    $txt = __("%s is %s");
1031                    $or = __(' or ');
1032               } else {
1033                    $txt = __("%s is not %s");
1034                    $or = __(' nor ');
1035               }
1036               $texts = array();
1037               foreach ($this->avalues['values'] as $v) {
1038                    $texts[] = $this->field->getTextForValue($v);
1039               }
1040               if (count($texts)>=1) {
1041                    return sprintf($txt,$this->desc,join($or, $texts));
1042               } else {
1043                    return sprintf($txt,$this->desc,$texts);
1044               }
1045          }
1046     }
1047
1048}
1049
1050// Static initializer
1051dcFilterSet::__init__($GLOBALS['core']->tpl);
1052?>
Note: See TracBrowser for help on using the repository browser.

Sites map