Dotclear

source: inc/admin/class.dc.filter.php @ 1524:913f5a36bbb0

Revision 1524:913f5a36bbb0, 26.1 KB checked in by Dsls, 12 years ago (diff)

columns selection is now functional in admin lists

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

Sites map