Fix UserFilter::DN_SORT -> Profile::DN_SORT.
[platal.git] / include / ufbuilder.inc.php
index 26f6e1b..ee8f3fd 100644 (file)
@@ -28,6 +28,7 @@ class UserFilterBuilder
     private $fields;
     private $valid = true;
     private $ufc = null;
+    private $orders = array();
 
     /** Constructor
      * @param $fields An array of UFB_Field objects
@@ -61,16 +62,32 @@ class UserFilterBuilder
         $this->ufc->addChild($cond);
     }
 
+    public function addOrder(PlFilterOrder &$order)
+    {
+        $this->order[] = $order;
+    }
+
     public function isValid()
     {
         $this->buildUFC();
         return $this->valid;
     }
 
+    public function isEmpty()
+    {
+        $this->buildUFC();
+        foreach ($this->fields as $field) {
+            if (! $field->isEmpty()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     /** Returns the built UFC
      * @return The UFC, or PFC_False() if an error happened
      */
-    public function &getUFC()
+    public function getUFC()
     {
         $this->buildUFC();
         if ($this->valid) {
@@ -80,6 +97,14 @@ class UserFilterBuilder
         }
     }
 
+    /** Returns adequate orders
+     */
+    public function getOrders()
+    {
+        $this->buildUFC();
+        return $this->orders;
+    }
+
     /** Wrappers around Env::i/s/..., to add envprefix
      */
     public function s($key, $def = '') {
@@ -97,6 +122,23 @@ class UserFilterBuilder
     public function has($key) {
         return (Env::has($this->envprefix . $key) && strlen($this->s($key, '')) > 0);
     }
+
+    public function isOn($key) {
+        return (Env::has($this->envprefix . $key) && $this->s($key) == 'on');
+    }
+}
+// }}}
+
+// {{{ class UFB_QuickSearch
+class UFB_QuickSearch extends UserFilterBuilder
+{
+    public function __construct($envprefix = '')
+    {
+        $fields = array(
+            new UFBF_Quick('quick', 'Recherche rapide'),
+        );
+        parent::__construct($fields, $envprefix);
+    }
 }
 // }}}
 
@@ -127,11 +169,29 @@ class UFB_AdvancedSearch extends UserFilterBuilder
             new UFBF_Group('groupexTxt', 'groupex', 'Groupe X'),
             new UFBF_Section('sectionTxt', 'section', 'Section'),
 
-            new UFBF_Formation('schoolTxt', 'school', "École d'application"),
-            new UFBF_Diploma('diplomaTxt', 'diploma', 'Diplôme'),
-            new UFBF_StudiesDomain('fieldTxt', 'field', "Domaine d'études"),
+            new UFBF_EducationSchool('schoolTxt', 'school', "École d'application"),
+            new UFBF_EducationDegree('diplomaTxt', 'diploma', 'Diplôme'),
+            new UFBF_EducationField('fieldTxt', 'field', "Domaine d'études"),
 
             new UFBF_Comment('free', 'Commentaire'),
+            new UFBF_Phone('phone_number', 'Téléphone'),
+            new UFBF_Networking('networking_address', 'networking_type', 'Networking et sites webs'),
+        );
+        parent::__construct($fields, $envprefix);
+    }
+}
+// }}}
+
+// {{{ class UFB_MentorSearch
+class UFB_MentorSearch extends UserFilterBuilder
+{
+    public function __construct($envprefix = '')
+    {
+        $fields = array(
+            new UFBF_MentorCountry('pays_sel'),
+            new UFBF_MentorSectorization('sector', '', UFC_Mentor_Sectorization::SECTOR),
+            new UFBF_MentorSectorization('subSector', '', UFC_Mentor_Sectorization::SUBSECTOR),
+            new UFBF_MentorExpertise('expertise'),
         );
         parent::__construct($fields, $envprefix);
     }
@@ -186,6 +246,11 @@ abstract class UFB_Field
         return true;
     }
 
+    public function isEmpty()
+    {
+        return $this->empty;
+    }
+
     /** Create the UFC associated to the field; won't be called
      * if the field is "empty"
      * @param &$ufb UFB to which fields must be added
@@ -203,14 +268,12 @@ abstract class UFB_Field
 // {{{ class UFBF_Text
 abstract class UFBF_Text extends UFB_Field
 {
-    private $forbiddenchars;
     private $minlength;
     private $maxlength;
 
-    public function __construct($envfield, $formtext = '', $forbiddenchars = '', $minlength = 2, $maxlength = 255)
+    public function __construct($envfield, $formtext = '', $minlength = 2, $maxlength = 255)
     {
         parent::__construct($envfield, $formtext);
-        $this->forbiddenchars = $forbiddenchars;
         $this->minlength      = $minlength;
         $this->maxlength      = $maxlength;
     }
@@ -227,7 +290,10 @@ abstract class UFBF_Text extends UFB_Field
             return $this->raise("Le champ %s est trop court (minimum {$this->minlength}).");
         } else if (strlen($this->val) > $this->maxlength) {
             return $this->raise("Le champ %s est trop long (maximum {$this->maxlength}).");
+        } else if (preg_match(":[\]\[<>{}~/§_`|%$^=+]|\*\*:u", $this->val)) {
+            return $this->raise('Le champ %s contient un caractère interdit rendant la recherche impossible.');
         }
+
         return true;
     }
 }
@@ -277,6 +343,7 @@ abstract class UFBF_Index extends UFB_Field
         if (!$ufb->has($this->envfield)) {
             $this->empty = true;
         }
+        $this->val = $ufb->i($this->envfield);
         return true;
     }
 }
@@ -366,7 +433,7 @@ abstract class UFBF_Mixed extends UFB_Field
             $this->val = array($index);
         } else {
             $indexes = DirEnum::getIDs($this->direnum, $ufb->s($this->envfield), 
-                $ufb->i('exact') ? DirEnumeration::MODE_EXACT : DirEnumeration::MODE_CONTAINS);
+                $ufb->i('exact') ? XDB::WILDCARD_EXACT : XDB::WILDCARD_CONTAINS);
             if (count($indexes) == 0) {
                 return false;
             }
@@ -377,6 +444,109 @@ abstract class UFBF_Mixed extends UFB_Field
 }
 // }}}
 
+// {{{ class UFBF_Quick
+class UFBF_Quick extends UFB_Field
+{
+    protected function check(UserFilterBuilder &$ufb)
+    {
+        if (!$ufb->has($this->envfield)) {
+            $this->empty = true;
+            return true;
+        }
+
+        $this->val = str_replace('*', '%', replace_accent($ufb->s($this->envfield)));
+
+        return true;
+    }
+
+    protected function buildUFC(UserFilterBuilder &$ufb)
+    {
+
+        $r = $s = $this->val;
+
+        /** Admin: Email, IP
+         */
+        if (S::admin() && strpos($s, '@') !== false) {
+            return new UFC_Email($s);
+        } else if (S::admin() && preg_match('/[0-9]+\.([0-9]+|%)\.([0-9]+|%)\.([0-9]+|%)/', $s)) {
+            $this->conds->addChild(new UFC_Ip($s));
+            return;
+        }
+
+        $conds = new PFC_And();
+
+        /** Name
+         */
+        $s = preg_replace('!\d+!', ' ', $s);
+        $strings = preg_split("![^a-zA-Z%]+!",$s, -1, PREG_SPLIT_NO_EMPTY);
+        if (count($strings) > 5) {
+            Platal::page()->trigWarning("Tu as indiqué trop d'éléments dans ta recherche, seuls les 5 premiers seront pris en compte");
+            $strings = array_slice($strings, 0, 5);
+        }
+
+        if (count($strings)) {
+            if (S::logged()) {
+                $flags = array();
+            } else {
+                $flags = array('public');
+            }
+            if ($ufb->i('soundex')) {
+                $soundex = true;
+                $st = array();
+                foreach ($strings as $string) {
+                    $st[] = soundex_fr($string);
+                }
+            } else {
+                $soundex = false;
+                $st = $strings;
+            }
+            if ($ufb->i('exact')) {
+                $exact = true;
+            } else {
+                $exact = false;
+            }
+            $conds->addChild(new UFC_NameTokens($st, $flags, $soundex, $exact));
+
+            $ufb->addOrder(new UFO_Score());
+        }
+
+        /** Promo ranges
+         */
+        $s = preg_replace('! *- *!', '-', $r);
+        $s = preg_replace('!([<>]) *!', ' \1', $s);
+        $s = preg_replace('![^0-9\-><]!', ' ', $s);
+        $s = preg_replace('![<>\-] !', '', $s);
+        $ranges = preg_split('! +!', $s, -1, PREG_SPLIT_NO_EMPTY);
+        foreach ($ranges as $r) {
+            if (preg_match('!^\d{4}$!', $r)) {
+                $conds->addChild(new UFC_Promo('=', UserFilter::DISPLAY, 'X' . $r));
+            } elseif (preg_match('!^(\d{4})-(\d{4})$!', $r, $matches)) {
+                $p1=min(intval($matches[1]), intval($matches[2]));
+                $p2=max(intval($matches[1]), intval($matches[2]));
+                $conds->addChild(new PFC_And(
+                    new UFC_Promo('>=', UserFilter::DISPLAY, 'X' . $p1),
+                    new UFC_Promo('<=', UserFilter::DISPLAY, 'X' . $p2)
+                ));
+            } elseif (preg_match('!^<(\d{4})!', $r, $matches)) {
+                $conds->addChild(new UFC_Promo('<=', UserFilter::DISPLAY, 'X' . $matches[1]));
+            } elseif (preg_match('!^>(\d{4})!', $r, $matches)) {
+                $conds->addChild(new UFC_Promo('>=', UserFilter::DISPLAY, 'X' . $matches[1]));
+            }
+        }
+
+        /** Phone number
+         */
+        $t = preg_replace('!(\d{4}-\d{4}|>\d{4}|<\d{4})!', '', $s);
+        $t = preg_replace('![<>\- ]!', '', $t);
+        if (strlen($t) > 4) {
+            $conds->addChild(new UFC_Phone($t));
+        }
+
+        return $conds;
+    }
+}
+// }}}
+
 // {{{ class UFBF_Name
 class UFBF_Name extends UFBF_Text
 {
@@ -517,23 +687,32 @@ class UFBF_Town extends UFBF_Text
     const TYPE_ANY  = 3;
 
     private $type;
-    public function __construct($envfield, $formtext = '', $type = self::TYPE_ANY)
+    private $onlycurrentfield;
+
+    public function __construct($envfield, $formtext = '', $type = self::TYPE_ANY, $onlycurrentfield = 'only_current')
     {
         $this->type = $type;
-        parent::__construct($envfield, $formtext, '', 2, 30);
+        $this->onlycurrentfield = $onlycurrentfield;
+        parent::__construct($envfield, $formtext, 2, 30);
     }
 
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
+        if ($ufb->isOn($this->onlycurrentfield)) {
+            $flags = UFC_Address::FLAG_CURRENT;
+        } else {
+            $flags = UFC_Address::FLAG_ANY;
+        }
+
         if (preg_match('/[0-9]/', $this->val)) {
             if ($this->type & self::TYPE_ZIP) {
-                return new UFC_AddressField(UFC_Address::TYPE_ANY, UFC_Address::FLAG_ANY, null, null, null, null, $this->val);
+                return new UFC_AddressField($this->val, UFC_AddressField::FIELD_ZIPCODE, UFC_Address::TYPE_ANY, $flags);
             } else {
                 return new PFC_False();
             }
         } else {
-            $byname = new UFC_AddressText(null, UFC_Address::CONTAINS, UFC_Address::TYPE_ANY, UFC_Address::FLAG_ANY, null, $this->val);
-            $byzip  = new UFC_AddressField(UFC_Address::TYPE_ANY, UFC_Address::FLAG_ANY, null, null, null, null, $this->val);
+            $byname = new UFC_AddressText(null, UFC_Address::CONTAINS, UFC_Address::TYPE_ANY, $flags, null, $this->val);
+            $byzip  = new UFC_AddressField($this->val, UFC_AddressField::FIELD_ZIPCODE, UFC_Address::TYPE_ANY, $flags);
             if ($this->type & self::TYPE_ANY) {
                 return new PFC_Or($byname, $byzip);
             } else if ($this->type & self::TYPE_TEXT) {
@@ -550,10 +729,23 @@ class UFBF_Town extends UFBF_Text
 class UFBF_Country extends UFBF_Mixed
 {
     protected $direnum = DirEnum::COUNTRIES;
+    protected $onlycurrentfield;
+
+    public function __construct($envfieldtext, $envfieldindex, $formtext = '', $onlycurrentfield = 'only_current')
+    {
+        parent::__construct($envfieldtext, $envfieldindex, $formtext);
+        $this->onlycurrentfield = $onlycurrentfield;
+    }
 
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
-        return new UFC_AddressField($this->val, UFC_AddressField::FIELD_COUNTRY, UFC_Address::TYPE_ANY, UFC_Address::FLAG_ANY);
+        if ($ufb->isOn($this->onlycurrentfield)) {
+            $flags = UFC_Address::FLAG_CURRENT;
+        } else {
+            $flags = UFC_Address::FLAG_ANY;
+        }
+
+        return new UFC_AddressField($this->val, UFC_AddressField::FIELD_COUNTRY, UFC_Address::TYPE_ANY, $flags);
     }
 }
 // }}}
@@ -562,10 +754,24 @@ class UFBF_Country extends UFBF_Mixed
 class UFBF_AdminArea extends UFBF_Mixed
 {
     protected $direnum = DirEnum::ADMINAREAS;
+    protected $onlycurrentfield;
+
+    public function __construct($envfieldtext, $envfieldindex, $formtext = '', $onlycurrentfield = 'only_current')
+    {
+        parent::__construct($envfieldtext, $envfieldindex, $formtext);
+        $this->onlycurrentfield = $onlycurrentfield;
+    }
+
 
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
-        return new UFC_AddressField($this->val, UFC_AddressField::FIELD_ADMAREA, UFC_Address::TYPE_ANY, UFC_Address::FLAG_ANY);
+        if ($ufb->isOn($this->onlycurrentfield)) {
+            $flags = UFC_Address::FLAG_CURRENT;
+        } else {
+            $flags = UFC_Address::FLAG_ANY;
+        }
+
+        return new UFC_AddressField($this->val, UFC_AddressField::FIELD_ADMAREA, UFC_Address::TYPE_ANY, $flags);
     }
 }
 // }}}
@@ -573,6 +779,26 @@ class UFBF_AdminArea extends UFBF_Mixed
 // {{{ class UFBF_JobCompany
 class UFBF_JobCompany extends UFBF_Text
 {
+    private $onlymentorfield;
+
+    public function __construct($envfield, $formtext = '', $onlymentorfield = 'only_referent')
+    {
+        parent::__construct($envfield, $formtext);
+        $this->onlymentorfield = $onlymentorfield;
+    }
+
+    public function check(UserFilterBuilder &$ufb) {
+        if (parent::check($ufb)) {
+            # No company check for mentors
+           if ($ufb->isOn($this->onlymentorfield)) {
+                $this->empty = true;
+           }
+           return true;
+        } else {
+            return false;
+        }
+    }
+
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
         return new UFC_Job_Company(UFC_Job_Company::JOBNAME, $this->val);
@@ -584,10 +810,21 @@ class UFBF_JobCompany extends UFBF_Text
 class UFBF_JobSector extends UFBF_Mixed
 {
     protected $direnum = DirEnum::SECTORS;
+    private $onlymentorfield;
+
+    public function __construct($envfieldtext, $envfieldindex, $formtext = '', $onlymentorfield = 'only_referent')
+    {
+        parent::__construct($envfieldtext, $envfieldindex, $formtext);
+        $this->onlymentorfield = $onlymentorfield;
+    }
 
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
-        return new UFC_Job_Sectorization($this->val, UserFilter::JOB_SUBSUBSECTOR);
+        if ($ufb->isOn($this->onlymentorfield)) {
+            return new UFC_Mentor_Sectorization($this->val, UserFilter::JOB_SUBSECTOR);
+        } else {
+            return new UFC_Job_Sectorization($this->val, UserFilter::JOB_SUBSUBSECTOR);
+        }
     }
 }
 // }}}
@@ -595,9 +832,21 @@ class UFBF_JobSector extends UFBF_Mixed
 // {{{ class UFBF_JobDescription
 class UFBF_JobDescription extends UFBF_Text
 {
+    private $onlymentorfield;
+
+    public function __construct($envfield, $formtext = '', $onlymentorfield = 'only_referent')
+    {
+        parent::__construct($envfield, $formtext);
+        $this->onlymentorfield = $onlymentorfield;
+    }
+
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
-        return new UFC_Job_Description($this->val, UserFilter::JOB_USERDEFINED);
+        if ($ufb->isOn($this->onlymentorfield)) {
+            return new UFC_Mentor_Expertise($this->val);
+        } else {
+            return new UFC_Job_Description($this->val, UserFilter::JOB_USERDEFINED);
+        }
     }
 }
 // }}}
@@ -605,9 +854,21 @@ class UFBF_JobDescription extends UFBF_Text
 // {{{ class UFBF_JobCv
 class UFBF_JobCv extends UFBF_Text
 {
+    private $onlymentorfield;
+
+    public function __construct($envfield, $formtext = '', $onlymentorfield = 'only_referent')
+    {
+        parent::__construct($envfield, $formtext);
+        $this->onlymentorfield = $onlymentorfield;
+    }
+
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
-        return new UFC_Job_Description($this->val, UserFilter::JOB_CV);
+        if ($ufb->isOn($this->onlymentorfield)) {
+            return new UFC_Mentor_Expertise($this->val);
+        } else {
+            return new UFC_Job_Description($this->val, UserFilter::JOB_CV);
+        }
     }
 }
 // }}}
@@ -668,38 +929,38 @@ class UFBF_Section extends UFBF_Index
 }
 // }}}
 
-// {{{ class UFBF_Formation
-class UFBF_Formation extends UFBF_Mixed
+// {{{ class UFBF_EducationSchool
+class UFBF_EducationSchool extends UFBF_Mixed
 {
-    protected $direnum = DirEnum::SCHOOLS;
+    protected $direnum = DirEnum::EDUSCHOOLS;
 
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
-        return new UFC_Formation($this->val);
+        return new UFC_EducationSchool($this->val);
     }
 }
 // }}}
 
-// {{{ class UFBF_Diploma
-class UFBF_Diploma extends UFBF_Mixed
+// {{{ class UFBF_EducationDegree
+class UFBF_EducationDegree extends UFBF_Mixed
 {
-    protected $direnum = DirEnum::DEGREES;
+    protected $direnum = DirEnum::EDUDEGREES;
 
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
-        return new UFC_Diploma($this->val);
+        return new UFC_EducationDegree($this->val);
     }
 }
 // }}}
 
-// {{{ class UFBF_StudiesDomain
-class UFBF_StudiesDomain extends UFBF_Mixed
+// {{{ class UFBF_EducationField
+class UFBF_EducationField extends UFBF_Mixed
 {
-    protected $direnum = DirEnum::STUDIESDOMAINS;
+    protected $direnum = DirEnum::EDUFIELDS;
 
     protected function buildUFC(UserFilterBuilder &$ufb)
     {
-        return new UFC_StudyField($this->val);
+        return new UFC_EducationField($this->val);
     }
 }
 // }}}
@@ -713,4 +974,81 @@ class UFBF_Comment extends UFBF_Text
     }
 }
 // }}}
+
+// {{{ class UFBF_Phone
+class UFBF_Phone extends UFBF_Text
+{
+    protected function buildUFC(UserFilterBuilder &$ufb)
+    {
+        return new UFC_Phone($this->val);
+    }
+}
+// }}}
+
+// {{{ class UFBF_Networking
+class UFBF_Networking extends UFBF_Text
+{
+    private $networktypefield;
+    private $nwtype;
+
+    public function __construct($envfield, $networktypefield, $formtext = '')
+    {
+        parent::__construct($envfield, $formtext);
+        $this->networktypefield  = $networktypefield;
+    }
+
+    public function check(UserFilterBuilder &$ufb)
+    {
+        if (parent::check($ufb)) {
+            $this->nwtype = $ufb->i($this->networktypefield);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public function buildUFC(UserFilterBuilder &$ufb)
+    {
+        return new UFC_Networking($this->nwtype, $this->val);
+    }
+}
+// }}}
+
+// {{{ class UFBF_MentorCountry
+class UFBF_MentorCountry extends UFBF_Index
+{
+    protected function buildUFC(UserFilterBuilder &$ufb)
+    {
+        return new UFC_Mentor_Country($this->val);
+    }
+}
+// }}}
+
+// {{{ class UFBF_MentorSectorization
+class UFBF_MentorSectorization extends UFBF_Index
+{
+    protected $type;
+
+    public function __construct($envfield, $formtext = '', $type = UFC_Mentor_Sectorization::SECTOR)
+    {
+        parent::__construct($envfield, $formtext);
+        $this->type = $type;
+    }
+
+    protected function buildUFC(UserFilterBuilder &$ufb)
+    {
+        return new UFC_Mentor_Sectorization($this->val, $this->type);
+    }
+}
+// }}}
+
+// {{{ class UFBF_MentorExpertise
+class UFBF_MentorExpertise extends UFBF_Text
+{
+    protected function buildUFC(UserFilterBuilder &$ufb)
+    {
+        return new UFC_Mentor_Expertise($this->val);
+    }
+}
+// }}}
 ?>