c9b38e28bfd18a5dfcaba5008abb933fa39e6a20
2 /***************************************************************************
3 * Copyright (C) 2003-2010 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the Free Software *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
22 require_once 'directory.enums.inc.php';
24 // {{{ class UserFilterBuilder
25 class UserFilterBuilder
29 private $valid = true
;
33 * @param $fields An array of UFB_Field objects
34 * @param $envprefix Prefix to use for parts of the query
36 public function __construct($fields, $envprefix = '')
38 $this->fields
= $fields;
39 $this->envprefix
= $envprefix;
42 /** Builds the UFC; returns as soon as a field says it is invalid
44 private function buildUFC()
46 if ($this->ufc
!= null
) {
49 $this->ufc
= new PFC_And();
51 foreach ($this->fields
as $field) {
52 $this->valid
= $field->apply(&$this);
59 public function addCond(PlFilterCondition
&$cond)
61 $this->ufc
->addChild($cond);
64 public function isValid()
70 /** Returns the built UFC
71 * @return The UFC, or PFC_False() if an error happened
73 public function &getUFC()
79 return new PFC_False();
83 /** Wrappers around Env::i/s/..., to add envprefix
85 public function s($key, $def = '') {
86 return trim(Env
::s($this->envprefix
. $key, $def));
89 public function i($key, $def = 0) {
90 return intval(trim(Env
::i($this->envprefix
. $key, $def)));
93 public function v($key, $def = null
) {
94 return Env
::v($this->envprefix
. $key, $def);
97 public function has($key) {
98 return (Env
::has($this->envprefix
. $key) && strlen($this->s($key, '')) > 0);
101 public function isOn($key) {
102 return (Env
::has($this->envprefix
. $key) && $this->s($key) == 'on');
107 // {{{ class UFB_AdvancedSearch
108 class UFB_AdvancedSearch
extends UserFilterBuilder
110 public function __construct($envprefix = '')
113 new UFBF_Name('name', 'Nom'),
114 new UFBF_Promo('promo1', 'Promotion', 'egal1'),
115 new UFBF_Promo('promo2', 'Promotion', 'egal2'),
116 new UFBF_Sex('woman', 'Sexe'),
117 new UFBF_Registered('subscriber', 'Inscrit'),
118 new UFBF_Dead('alive', 'En vie'),
120 new UFBF_Town('city', 'Ville / Code Postal'),
121 new UFBF_Country('countryTxt', 'country', 'Pays'),
122 new UFBF_AdminArea('region', 'Région'),
124 new UFBF_JobCompany('entreprise', 'Entreprise'),
125 new UFBF_JobSector('sector', 'Poste'),
126 new UFBF_JobDescription('jobdescription', 'Fonction'),
127 new UFBF_JobCv('cv', 'CV'),
129 new UFBF_Nationality('nationaliteTxt', 'nationalite', 'Nationalité'),
130 new UFBF_Binet('binetTxt', 'binet', 'Binet'),
131 new UFBF_Group('groupexTxt', 'groupex', 'Groupe X'),
132 new UFBF_Section('sectionTxt', 'section', 'Section'),
134 new UFBF_Formation('schoolTxt', 'school', "École d'application"),
135 new UFBF_Diploma('diplomaTxt', 'diploma', 'Diplôme'),
136 new UFBF_StudiesDomain('fieldTxt', 'field', "Domaine d'études"),
138 new UFBF_Comment('free', 'Commentaire'),
139 new UFBF_Phone('phone_number', 'Téléphone'),
140 new UFBF_Networking('networking_address', 'networking_type', 'Networking et sites webs'),
142 parent
::__construct($fields, $envprefix);
147 // {{{ class UFB_Field
148 abstract class UFB_Field
153 protected $empty = false
;
154 protected $val = null
;
157 * @param $envfield Name of the field in the environment
158 * @param $formtext User-friendly name of that field
160 public function __construct($envfield, $formtext = '')
162 $this->envfield
= $envfield;
163 if ($formtext != '') {
164 $this->formtext
= $formtext;
166 $formtext = ucfirst($envfield);
170 /** Prints the given error message to the user, and returns false
171 * in order to be used as return $this->raise('ERROR');
173 * All %s in the $msg will be replaced with the formtext.
175 protected function raise($msg)
177 Platal
::page()->trigError(str_replace('%s', $this->formtext
, $msg));
181 public function apply(UserFilterBuilder
&$ufb) {
182 if (!$this->check($ufb)) {
187 $ufc = $this->buildUFC($ufb);
195 /** Create the UFC associated to the field; won't be called
196 * if the field is "empty"
197 * @param &$ufb UFB to which fields must be added
200 abstract protected function buildUFC(UserFilterBuilder
&$ufb);
202 /** This function is intended to run consistency checks on the value
203 * @return boolean Whether the input is valid
205 abstract protected function check(UserFilterBuilder
&$ufb);
209 // {{{ class UFBF_Text
210 abstract class UFBF_Text
extends UFB_Field
212 private $forbiddenchars;
216 public function __construct($envfield, $formtext = '', $forbiddenchars = '', $minlength = 2, $maxlength = 255)
218 parent
::__construct($envfield, $formtext);
219 $this->forbiddenchars
= $forbiddenchars;
220 $this->minlength
= $minlength;
221 $this->maxlength
= $maxlength;
224 protected function check(UserFilterBuilder
&$ufb)
226 if (!$ufb->has($this->envfield
)) {
231 $this->val
= $ufb->s($this->envfield
);
232 if (strlen($this->val
) < $this->minlength
) {
233 return $this->raise("Le champ %s est trop court (minimum {$this->minlength}).");
234 } else if (strlen($this->val
) > $this->maxlength
) {
235 return $this->raise("Le champ %s est trop long (maximum {$this->maxlength}).");
242 // {{{ class UFBF_Range
243 /** Subclass to use for fields which only allow integers within a range
245 abstract class UFBF_Range
extends UFB_Field
251 public function __construct($envfield, $formtext = '', $min = 0, $max = 65535)
253 parent
::__construct($envfield, $formtext);
258 protected function check(UserFilterBuilder
&$ufb)
260 if (!$ufb->has($this->envfield
)) {
265 $this->val
= $ufb->i($this->envfield
);
266 if ($this->val
< $this->min
) {
267 return $this->raise("Le champs %s est inférieur au minimum ({$this->min}).");
268 } else if ($this->val
> $this->max
) {
269 return $this->raise("Le champ %s est supérieur au maximum ({$this->max}).");
276 // {{{ class UFBF_Index
277 /** Subclass to use for indexed fields
279 abstract class UFBF_Index
extends UFB_Field
281 protected function check(UserFilterBuilder
&$ufb)
283 if (!$ufb->has($this->envfield
)) {
291 // {{{ class UFBF_Enum
292 /** Subclass to use for fields whose value must belong to a specific set of values
294 abstract class UFBF_Enum
extends UFB_Field
296 protected $allowedvalues;
298 public function __construct($envfield, $formtext = '', $allowedvalues = array(), $strict = false
)
300 parent
::__construct($envfield, $formtext);
301 $this->allowedvalues
= $allowedvalues;
302 $this->strict
= $strict;
305 protected function check(UserFilterBuilder
&$ufb)
307 if (!$ufb->has($this->envfield
)) {
312 $this->val
= $ufb->v($this->envfield
);
313 if (! in_array($this->val
, $this->allowedvalues
)) {
315 return $this->raise("La valeur {$this->val} n'est pas valide pour le champ %s.");
325 // {{{ class UFBF_Bool
326 abstract class UFBF_Bool
extends UFB_Field
328 protected function check(UserFilterBuilder
&$ufb)
330 if (!$ufb->has($this->envfield
)) {
335 $this->val
= ($ufb->i($this->envfield
) != 0);
341 // {{{ class UFBF_Mixed
342 /** A class for building UFBFs when the user can input either a text or an ID
344 abstract class UFBF_Mixed
extends UFB_Field
346 /** Name of the DirEnum on which class is based
350 protected $envfieldindex;
352 public function __construct($envfieldtext, $envfieldindex, $formtext = '')
354 parent
::__construct($envfieldtext, $formtext);
355 $this->envfieldindex
= $envfieldindex;
358 protected function check(UserFilterBuilder
&$ufb)
360 if (!$ufb->has($this->envfieldindex
) && !$ufb->has($this->envfield
)) {
365 if ($ufb->has($this->envfieldindex
)) {
366 $index = $ufb->v($this->envfieldindex
);
367 if (is_int($index)) {
368 $index = intval($index);
370 $index = strtoupper($index);
372 $this->val
= array($index);
374 $indexes = DirEnum
::getIDs($this->direnum
, $ufb->s($this->envfield
),
375 $ufb->i('exact') ? DirEnumeration
::MODE_EXACT
: DirEnumeration
::MODE_CONTAINS
);
376 if (count($indexes) == 0) {
379 $this->val
= $indexes;
386 // {{{ class UFBF_Name
387 class UFBF_Name
extends UFBF_Text
389 protected function check(UserFilterBuilder
&$ufb)
391 if (!parent
::check($ufb)) {
395 $this->val
= preg_split('/[[:space:]]/', $this->val
);
396 if (count($this->val
) == 0) {
402 protected function buildUFC(UserFilterBuilder
&$ufb)
404 return new UFC_NameTokens($this->val
, array(), $ufb->i('with_soundex'), $ufb->i('exact'));
409 // {{{ class UFBF_Promo
410 class UFBF_Promo
extends UFB_Field
412 private static $validcomps = array('<', '<=', '=', '>=', '>');
414 private $envfieldcomp;
416 public function __construct($envfield, $fromtext = '', $envfieldcomp)
418 parent
::__construct($envfield, $fromtext);
419 $this->envfieldcomp
= $envfieldcomp;
422 protected function check(UserFilterBuilder
&$ufb)
424 if (!$ufb->has($this->envfield
) ||
!$ufb->has($this->envfieldcomp
)) {
429 $this->val
= $ubf->i($this->envfield
);
430 $this->comp
= $ubf->v($this->envfieldcomp
);
432 if (!in_array($this->comp
, self
::$validcomps)) {
433 return $this->raise("Le critère {$this->comp} n'est pas valide pour le champ %s");
436 if (preg_match('/^[0-9]{2}$/', $this->val
)) {
439 if ($this->val
< 1900 ||
$this->val
> 9999) {
440 return $this->raise("Le champ %s doit être une année à 4 chiffres.");
445 protected function buildUFC(UserFilterBuilder
&$ufb) {
446 return new UFC_Promo($this->comp
, UserFilter
::DISPLAY
, 'X' . $this->val
);
451 // {{{ class UFBF_Sex
452 class UFBF_Sex
extends UFBF_Enum
454 public function __construct($envfield, $formtext = '')
456 parent
::__construct($envfield, $formtext, array(1, 2));
459 private static function getVal($id)
463 return User
::GENDER_MALE
;
466 return User
::GENDER_FEMALE
;
471 protected function buildUFC(UserFilterBuilder
&$ufb)
473 return new UFC_Sex(self
::getVal($this->val
));
478 // {{{ class UFBF_Registered
479 class UFBF_Registered
extends UFBF_Enum
481 public function __construct($envfield, $formtext = '')
483 parent
::__construct($envfield, $formtext, array(1, 2));
486 protected function buildUFC(UserFilterBuilder
&$ufb)
488 if ($this->val
== 1) {
489 return new UFC_Registered();
490 } else if ($this->val
== 2) {
491 return new PFC_Not(UFC_Registered());
497 // {{{ class UFBF_Dead
498 class UFBF_Dead
extends UFBF_Enum
500 public function __construct($envfield, $formtext = '')
502 parent
::__construct($envfield, $formtext, array(1, 2));
505 protected function buildUFC(UserFilterBuilder
&$ufb)
507 if ($this->val
== 1) {
508 return new PFC_Not(UFC_Dead());
509 } else if ($this->val
== 2) {
510 return new UFC_Dead();
516 // {{{ class UFBF_Town
517 /** Retrieves a town, either from a postal code or a town name
519 class UFBF_Town
extends UFBF_Text
526 private $onlycurrentfield;
528 public function __construct($envfield, $formtext = '', $type = self
::TYPE_ANY
, $onlycurrentfield = 'only_current')
531 $this->onlycurrentfield
= $onlycurrentfield;
532 parent
::__construct($envfield, $formtext, '', 2, 30);
535 protected function buildUFC(UserFilterBuilder
&$ufb)
537 if ($ufb->isOn($this->onlycurrentfield
)) {
538 $flags = UFC_Address
::FLAG_CURRENT
;
540 $flags = UFC_Address
::FLAG_ANY
;
543 if (preg_match('/[0-9]/', $this->val
)) {
544 if ($this->type
& self
::TYPE_ZIP
) {
545 return new UFC_AddressField($this->val
, UFC_AddressField
::FIELD_ZIPCODE
, UFC_Address
::TYPE_ANY
, $flags);
547 return new PFC_False();
550 $byname = new UFC_AddressText(null
, UFC_Address
::CONTAINS
, UFC_Address
::TYPE_ANY
, $flags, null
, $this->val
);
551 $byzip = new UFC_AddressField($this->val
, UFC_AddressField
::FIELD_ZIPCODE
, UFC_Address
::TYPE_ANY
, $flags);
552 if ($this->type
& self
::TYPE_ANY
) {
553 return new PFC_Or($byname, $byzip);
554 } else if ($this->type
& self
::TYPE_TEXT
) {
564 // {{{ class UFBF_Country
565 class UFBF_Country
extends UFBF_Mixed
567 protected $direnum = DirEnum
::COUNTRIES
;
568 protected $onlycurrentfield;
570 public function __construct($envfieldtext, $envfieldindex, $formtext = '', $onlycurrentfield = 'only_current')
572 parent
::__construct($envfieldtext, $envfieldindex, $formtext);
573 $this->onlycurrentfield
= $onlycurrentfield;
576 protected function buildUFC(UserFilterBuilder
&$ufb)
578 if ($ufb->isOn($this->onlycurrentfield
)) {
579 $flags = UFC_Address
::FLAG_CURRENT
;
581 $flags = UFC_Address
::FLAG_ANY
;
584 return new UFC_AddressField($this->val
, UFC_AddressField
::FIELD_COUNTRY
, UFC_Address
::TYPE_ANY
, $flags);
589 // {{{ class UFBF_AdminArea
590 class UFBF_AdminArea
extends UFBF_Mixed
592 protected $direnum = DirEnum
::ADMINAREAS
;
593 protected $onlycurrentfield;
595 public function __construct($envfieldtext, $envfieldindex, $formtext = '', $onlycurrentfield = 'only_current')
597 parent
::__construct($envfieldtext, $envfieldindex, $formtext);
598 $this->onlycurrentfield
= $onlycurrentfield;
602 protected function buildUFC(UserFilterBuilder
&$ufb)
604 if ($ufb->isOn($this->onlycurrentfield
)) {
605 $flags = UFC_Address
::FLAG_CURRENT
;
607 $flags = UFC_Address
::FLAG_ANY
;
610 return new UFC_AddressField($this->val
, UFC_AddressField
::FIELD_ADMAREA
, UFC_Address
::TYPE_ANY
, $flags);
615 // {{{ class UFBF_JobCompany
616 class UFBF_JobCompany
extends UFBF_Text
618 private $onlymentorfield;
620 public function __construct($envfield, $formtext = '', $onlymentorfield = 'only_referent')
622 parent
::__construct($envfield, $formtext);
623 $this->onlymentorfield
= $onlymentorfield;
626 public function check(UserFilterBuilder
&$ufb) {
627 if (parent
::check($ufb)) {
628 # No company check for mentors
629 if ($ufb->isOn($this->onlymentorfield
)) {
638 protected function buildUFC(UserFilterBuilder
&$ufb)
640 return new UFC_Job_Company(UFC_Job_Company
::JOBNAME
, $this->val
);
645 // {{{ class UFBF_JobSector
646 class UFBF_JobSector
extends UFBF_Mixed
648 protected $direnum = DirEnum
::SECTORS
;
649 private $onlymentorfield;
651 public function __construct($envfieldtext, $envfieldindex, $formtext = '', $onlymentorfield = 'only_referent')
653 parent
::__construct($envfieldtext, $envfieldindex, $formtext);
654 $this->onlymentorfield
= $onlymentorfield;
657 protected function buildUFC(UserFilterBuilder
&$ufb)
659 if ($ufb->isOn($this->onlymentorfield
)) {
660 return new UFC_Mentor_Sectorization($this->val
, UserFilter
::JOB_SUBSECTOR
);
662 return new UFC_Job_Sectorization($this->val
, UserFilter
::JOB_SUBSUBSECTOR
);
668 // {{{ class UFBF_JobDescription
669 class UFBF_JobDescription
extends UFBF_Text
671 private $onlymentorfield;
673 public function __construct($envfield, $formtext = '', $onlymentorfield = 'only_referent')
675 parent
::__construct($envfield, $formtext);
676 $this->onlymentorfield
= $onlymentorfield;
679 protected function buildUFC(UserFilterBuilder
&$ufb)
681 if ($ufb->isOn($this->onlymentorfield
)) {
682 return new UFC_Mentor_Expertise($this->val
);
684 return new UFC_Job_Description($this->val
, UserFilter
::JOB_USERDEFINED
);
690 // {{{ class UFBF_JobCv
691 class UFBF_JobCv
extends UFBF_Text
693 private $onlymentorfield;
695 public function __construct($envfield, $formtext = '', $onlymentorfield = 'only_referent')
697 parent
::__construct($envfield, $formtext);
698 $this->onlymentorfield
= $onlymentorfield;
701 protected function buildUFC(UserFilterBuilder
&$ufb)
703 if ($ufb->isOn($this->onlymentorfield
)) {
704 return new UFC_Mentor_Expertise($this->val
);
706 return new UFC_Job_Description($this->val
, UserFilter
::JOB_CV
);
712 // {{{ class UFBF_Nationality
713 class UFBF_Nationality
extends UFBF_Mixed
715 protected $direnum = DirEnum
::NATIONALITIES
;
717 protected function buildUFC(UserFilterBuilder
&$ufb)
719 return new UFC_Nationality($this->val
);
724 // {{{ class UFBF_Binet
725 class UFBF_Binet
extends UFBF_Mixed
727 protected $direnum = DirEnum
::BINETS
;
729 protected function buildUFC(UserFilterBuilder
&$ufb)
731 return new UFC_Binet($this->val
);
736 // {{{ class UFBF_Group
737 class UFBF_Group
extends UFBF_Mixed
739 protected $direnum = DirEnum
::GROUPESX
;
741 protected function buildUFC(UserFilterBuilder
&$ufb)
743 if (count($this->val
) == 1) {
744 return new UFC_Group($this->val
[0]);
748 foreach ($this->val
as $grp) {
749 $or->addChild(new UFC_Group($grp));
756 // {{{ class UFBF_Section
757 class UFBF_Section
extends UFBF_Index
759 protected $direnum = DirEnum
::SECTIONS
;
761 protected function buildUFC(UserFilterBuilder
&$ufb)
763 return new UFC_Section($this->val
);
768 // {{{ class UFBF_Formation
769 class UFBF_Formation
extends UFBF_Mixed
771 protected $direnum = DirEnum
::SCHOOLS
;
773 protected function buildUFC(UserFilterBuilder
&$ufb)
775 return new UFC_Formation($this->val
);
780 // {{{ class UFBF_Diploma
781 class UFBF_Diploma
extends UFBF_Mixed
783 protected $direnum = DirEnum
::DEGREES
;
785 protected function buildUFC(UserFilterBuilder
&$ufb)
787 return new UFC_Diploma($this->val
);
792 // {{{ class UFBF_StudiesDomain
793 class UFBF_StudiesDomain
extends UFBF_Mixed
795 protected $direnum = DirEnum
::STUDIESDOMAINS
;
797 protected function buildUFC(UserFilterBuilder
&$ufb)
799 return new UFC_StudyField($this->val
);
804 // {{{ class UFBF_Comment
805 class UFBF_Comment
extends UFBF_Text
807 protected function buildUFC(UserFilterBuilder
&$ufb)
809 return new UFC_Comment($this->val
);
814 // {{{ class UFBF_Phone
815 class UFBF_Phone
extends UFBF_Text
817 protected function buildUFC(UserFilterBuilder
&$ufb)
819 return new UFC_Phone($this->val
);
824 // {{{ class UFBF_Networking
825 class UFBF_Networking
extends UFBF_Text
827 private $networktypefield;
830 public function __construct($envfield, $networktypefield, $formtext = '')
832 parent
::__construct($envfield, $formtext);
833 $this->networktypefield
= $networktypefield;
836 public function check(UserFilterBuilder
&$ufb)
838 if (parent
::check($ufb)) {
839 $this->nwtype
= $ufb->i($this->networktypefield
);
846 public function buildUFC(UserFilterBuilder
&$ufb)
848 return new UFC_Networking($this->nwtype
, $this->val
);