From: Raphaël Barrois Date: Tue, 2 Feb 2010 21:28:32 +0000 (+0100) Subject: Move getIDs() to DirEnumeration X-Git-Tag: xorg/1.0.0~332^2~263 X-Git-Url: http://git.polytechnique.org/?a=commitdiff_plain;h=21b6746289ae4bcd60128f0c849a74af8da7f62b;p=platal.git Move getIDs() to DirEnumeration Signed-off-by: Raphaël Barrois --- diff --git a/include/directory.enums.inc.php b/include/directory.enums.inc.php index 013e0d7..4a61151 100644 --- a/include/directory.enums.inc.php +++ b/include/directory.enums.inc.php @@ -28,16 +28,17 @@ class DirEnum * Each of these consts contains the basename of the class (its full name * being DE_$basename). */ - const BINETS = 'binets'; - const SECTIONS = 'sections'; - const SCHOOLS = 'schools'; - const DEGREES = 'degrees'; - const NATIONALITIES = 'nationalities'; - const COUNTRIES = 'countries'; - const GROUPESX = 'groupesx'; - const SECTORS = 'sectors'; - const NETWORKS = 'networking'; - const ADMINAREAS = 'adminareas'; + const BINETS = 'binets'; + const SECTIONS = 'sections'; + const SCHOOLS = 'schools'; + const DEGREES = 'degrees'; + const STUDIESDOMAINS = 'studiesdomains'; + const NATIONALITIES = 'nationalities'; + const COUNTRIES = 'countries'; + const GROUPESX = 'groupesx'; + const SECTORS = 'sectors'; + const NETWORKS = 'networking'; + const ADMINAREAS = 'adminareas'; static private $enumerations = array(); @@ -63,17 +64,38 @@ class DirEnum $obj = self::$enumerations[$type]; return call_user_func_array(array($obj, 'getOptions'), $args); } + + static public function getIDs() + { + $args = func_get_args(); + $type = array_shift($args); + if (!array_key_exists($type, self::$enumerations)) { + self::init($type); + } + $obj = self::$enumerations[$type]; + return call_user_func_array(array($obj, 'getIDs'), $args); + } } abstract class DirEnumeration { + /** Modes for LIKE searches + */ + const MODE_EXACT = 0x000; + const MODE_PREFIX = 0x001; + const MODE_SUFFIX = 0x002; + const MODE_CONTAINS = 0x003; + /** An internal array of ID => optionTxt */ protected $options; + /** Description of the MySQL storage of the fields + */ protected $idfield = 'id'; protected $valfield = 'text'; protected $from; + protected $join = ''; protected $where = ''; public function __construct() { @@ -85,6 +107,45 @@ abstract class DirEnumeration return $this->options; } + /** Retrieves possible IDs for given text + * @param $text Text to search for IDs + * @param $mode Mode of search (PREFIX, SUFFIX, CONTAINS) + * @return An array of matching IDs ; if empty, input should be considered invalid + */ + public function getIDs($text, $mode) + { + if ($mode == self::MODE_EXACT) { + $options = $this->getOptions(); + return array_keys($options, $text); + } else { + if ($this->where == null) { + $where = 'WHERE '; + } else { + $where = $this->where . ' AND '; + } + return XDB::fetchColumn('SELECT ' . $this->idfield . ' + FROM ' . $this->from . ' + ' . $this->join . ' + ' . $where . $this->valfield . self::makeSqlConcat($text, $mode) . ' + GROUP BY ' . $this->idfield); + } + } + + static protected function makeSqlConcat($text, $mode) + { + if ($mode == self::MODE_EXACT) { + return ' = ' . XDB::format('{?}', $text); + } + if (($mode & self::MODE_CONTAINS) == self::MODE_PREFIX) { + $right = XDB::format('CONCAT({?}, \'%\')', $text); + } else if (($mode & self::MODE_CONTAINS) == self::MODE_SUFFIX) { + $right = XDB::format('CONCAT(\'%\', {?})', $text); + } else { + $right = XDB::format('CONCAT(\'%\', {?}, \'%\')', $text); + } + return ' LIKE ' . $right; + } + /** The function used to load options */ protected function loadOptions() @@ -92,6 +153,7 @@ abstract class DirEnumeration $this->options = XDB::iterator('SELECT ' . $this->valfield . ' AS field, ' . $this->idfield . ' AS id FROM ' . $this->from . ' + ' . $this->join . ' ' . $this->where . ' GROUP BY ' . $this->valfield . ' ORDER BY ' . $this->valfield); @@ -143,13 +205,32 @@ class DE_Degrees extends DirEnumeration return array(); } } + + public function getIDs($text, $mode, $eduid = null) + { + if ($eduid == null) { + return XDB::fetchColumn('SELECT id + FROM profile_education_degree_enum + WHERE degree ' . self::makeSqlConcat($text, $mode)); + } else { + return XDB::fetchColumn('SELECT pede.id + FROM profile_education_degree AS ped + LEFT JOIN profile_education_degree_enum AS pede ON (ped.degreeid = pede.id) + WHERE ped.eduid = {?} AND pede.degree ' . self::makeSqlConcat($text, $mode), $eduid); + } + } +} +class DE_StudiesSector extends DirEnumeration +{ + protected $valfield = 'field'; + protected $from = 'profile_education_field_enum'; } class DE_Nationalities extends DirEnumeration { protected $idfield = 'iso_3166_1_a2'; protected $valfield = 'nationalityFR'; protected $from = 'geoloc_countries AS gc'; - protected $where = 'INNER JOIN profiles AS p ON (gc.iso_3166_1_a2 IN (p.nationality1, p.nationality2, p.nationality3))'; + protected $join = 'INNER JOIN profiles AS p ON (gc.iso_3166_1_a2 IN (p.nationality1, p.nationality2, p.nationality3))'; } class DE_Countries extends DirEnumeration { @@ -188,6 +269,19 @@ class DE_AdminAreas extends DirEnumeration return array(); } } + + public function getIDs($text, $mode, $country = null) + { + if ($country == null) { + return XDB::fetchColumn('SELECT id + FROM geoloc_administrativeareas + WHERE name ' . self::makeSqlConcat($text, $mode)); + } else { + return XDB::fetchColumn('SELECT id + FROM geoloc_administrativeareas + WHERE country = {?} AND name' . self::makeSqlConcat($text, $mode), $country); + } + } } class DE_GroupesX extends DirEnumeration { diff --git a/include/ufbuilder.php b/include/ufbuilder.php index 528759a..26f6e1b 100644 --- a/include/ufbuilder.php +++ b/include/ufbuilder.php @@ -1,6 +1,6 @@ envprefix . $key, $def)); } - public function i($key, $def) { + public function i($key, $def = 0) { return intval(trim(Env::i($this->envprefix . $key, $def))); } - public function v($key, $def) { + public function v($key, $def = null) { return Env::v($this->envprefix . $key, $def); } public function has($key) { - return Env::has($this->envprefix . $key); + return (Env::has($this->envprefix . $key) && strlen($this->s($key, '')) > 0); } } +// }}} +// {{{ class UFB_AdvancedSearch +class UFB_AdvancedSearch extends UserFilterBuilder +{ + public function __construct($envprefix = '') + { + $fields = array( + new UFBF_Name('name', 'Nom'), + new UFBF_Promo('promo1', 'Promotion', 'egal1'), + new UFBF_Promo('promo2', 'Promotion', 'egal2'), + new UFBF_Sex('woman', 'Sexe'), + new UFBF_Registered('subscriber', 'Inscrit'), + new UFBF_Dead('alive', 'En vie'), + + new UFBF_Town('city', 'Ville / Code Postal'), + new UFBF_Country('countryTxt', 'country', 'Pays'), + new UFBF_AdminArea('region', 'Région'), + + new UFBF_JobCompany('entreprise', 'Entreprise'), + new UFBF_JobSector('sector', 'Poste'), + new UFBF_JobDescription('jobdescription', 'Fonction'), + new UFBF_JobCv('cv', 'CV'), + + new UFBF_Nationality('nationaliteTxt', 'nationalite', 'Nationalité'), + new UFBF_Binet('binetTxt', 'binet', 'Binet'), + 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_Comment('free', 'Commentaire'), + ); + parent::__construct($fields, $envprefix); + } +} +// }}} + +// {{{ class UFB_Field abstract class UFB_Field { protected $envfield; @@ -155,7 +198,9 @@ abstract class UFB_Field */ abstract protected function check(UserFilterBuilder &$ufb); } +// }}} +// {{{ class UFBF_Text abstract class UFBF_Text extends UFB_Field { private $forbiddenchars; @@ -186,7 +231,9 @@ abstract class UFBF_Text extends UFB_Field return true; } } +// }}} +// {{{ class UFBF_Range /** Subclass to use for fields which only allow integers within a range */ abstract class UFBF_Range extends UFB_Field @@ -218,7 +265,9 @@ abstract class UFBF_Range extends UFB_Field return true; } } +// }}} +// {{{ class UFBF_Index /** Subclass to use for indexed fields */ abstract class UFBF_Index extends UFB_Field @@ -231,15 +280,20 @@ abstract class UFBF_Index extends UFB_Field return true; } } +// }}} +// {{{ class UFBF_Enum /** Subclass to use for fields whose value must belong to a specific set of values */ abstract class UFBF_Enum extends UFB_Field { - public function __construct($envfield, $formtext = '', $allowedvalues = array()) + protected $allowedvalues; + + public function __construct($envfield, $formtext = '', $allowedvalues = array(), $strict = false) { parent::__construct($envfield, $formtext); $this->allowedvalues = $allowedvalues; + $this->strict = $strict; } protected function check(UserFilterBuilder &$ufb) @@ -251,32 +305,102 @@ abstract class UFBF_Enum extends UFB_Field $this->val = $ufb->v($this->envfield); if (! in_array($this->val, $this->allowedvalues)) { - return $this->raise("La valeur {$this->val} n'est pas valide pour le champ %s."); + if ($this->strict) { + return $this->raise("La valeur {$this->val} n'est pas valide pour le champ %s."); + } else { + $this->empty = true; + } } return true; } } +// }}} -class UFBF_Name extends UFBF_Text +// {{{ class UFBF_Bool +abstract class UFBF_Bool extends UFB_Field { - private $type; + protected function check(UserFilterBuilder &$ufb) + { + if (!$ufb->has($this->envfield)) { + $this->empty = true; + return true; + } + + $this->val = ($ufb->i($this->envfield) != 0); + return true; + } +} +// }}} - public function __construct($envfield, $type, $formtext = '', $forbiddenchars = '', $minlength = 2, $maxlength = 255) +// {{{ class UFBF_Mixed +/** A class for building UFBFs when the user can input either a text or an ID + */ +abstract class UFBF_Mixed extends UFB_Field +{ + /** Name of the DirEnum on which class is based + */ + protected $direnum; + + protected $envfieldindex; + + public function __construct($envfieldtext, $envfieldindex, $formtext = '') { - parent::__construct($envfield, $formtext, $forbiddenchars, $minlength, $maxlength); - $this->type = $type; + parent::__construct($envfieldtext, $formtext); + $this->envfieldindex = $envfieldindex; } - protected function buildUFC(UserFilterBuilder &$ufb) + protected function check(UserFilterBuilder &$ufb) { - if ($ufb->i('exact')) { - return new UFC_Name($this->type, $this->val, UFC_Name::VARIANTS); + if (!$ufb->has($this->envfieldindex) && !$ufb->has($this->envfield)) { + $this->empty = true; + return true; + } + + if ($ufb->has($this->envfieldindex)) { + $index = $ufb->v($this->envfieldindex); + if (is_int($index)) { + $index = intval($index); + } else { + $index = strtoupper($index); + } + $this->val = array($index); } else { - return new UFC_Name($this->type, $this->val, UFC_Name::VARIANTS | UFC_Name::CONTAINS); + $indexes = DirEnum::getIDs($this->direnum, $ufb->s($this->envfield), + $ufb->i('exact') ? DirEnumeration::MODE_EXACT : DirEnumeration::MODE_CONTAINS); + if (count($indexes) == 0) { + return false; + } + $this->val = $indexes; } + return true; } } +// }}} +// {{{ class UFBF_Name +class UFBF_Name extends UFBF_Text +{ + protected function check(UserFilterBuilder &$ufb) + { + if (!parent::check($ufb)) { + return false; + } + + $this->val = preg_split('/[[:space:]]/', $this->val); + if (count($this->val) == 0) { + $this->empty = true; + } + return true; + } + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_NameTokens($this->val, array(), $ufb->i('with_soundex'), $ufb->i('exact')); + } +} +// }}} + +// {{{ class UFBF_Promo class UFBF_Promo extends UFB_Field { private static $validcomps = array('<', '<=', '=', '>=', '>'); @@ -316,5 +440,277 @@ class UFBF_Promo extends UFB_Field return new UFC_Promo($this->comp, UserFilter::DISPLAY, 'X' . $this->val); } } +// }}} + +// {{{ class UFBF_Sex +class UFBF_Sex extends UFBF_Enum +{ + public function __construct($envfield, $formtext = '') + { + parent::__construct($envfield, $formtext, array(1, 2)); + } + + private static function getVal($id) + { + switch($id) { + case 1: + return User::GENDER_MALE; + break; + case 2: + return User::GENDER_FEMALE; + break; + } + } + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Sex(self::getVal($this->val)); + } +} +// }}} + +// {{{ class UFBF_Registered +class UFBF_Registered extends UFBF_Enum +{ + public function __construct($envfield, $formtext = '') + { + parent::__construct($envfield, $formtext, array(1, 2)); + } + + protected function buildUFC(UserFilterBuilder &$ufb) + { + if ($this->val == 1) { + return new UFC_Registered(); + } else if ($this->val == 2) { + return new PFC_Not(UFC_Registered()); + } + } +} +// }}} +// {{{ class UFBF_Dead +class UFBF_Dead extends UFBF_Enum +{ + public function __construct($envfield, $formtext = '') + { + parent::__construct($envfield, $formtext, array(1, 2)); + } + + protected function buildUFC(UserFilterBuilder &$ufb) + { + if ($this->val == 1) { + return new PFC_Not(UFC_Dead()); + } else if ($this->val == 2) { + return new UFC_Dead(); + } + } +} +// }}} + +// {{{ class UFBF_Town +/** Retrieves a town, either from a postal code or a town name + */ +class UFBF_Town extends UFBF_Text +{ + const TYPE_TEXT = 1; + const TYPE_ZIP = 2; + const TYPE_ANY = 3; + + private $type; + public function __construct($envfield, $formtext = '', $type = self::TYPE_ANY) + { + $this->type = $type; + parent::__construct($envfield, $formtext, '', 2, 30); + } + + protected function buildUFC(UserFilterBuilder &$ufb) + { + 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); + } 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); + if ($this->type & self::TYPE_ANY) { + return new PFC_Or($byname, $byzip); + } else if ($this->type & self::TYPE_TEXT) { + return $byname; + } else { + return $byzip; + } + } + } +} +// }}} + +// {{{ class UFBF_Country +class UFBF_Country extends UFBF_Mixed +{ + protected $direnum = DirEnum::COUNTRIES; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_AddressField($this->val, UFC_AddressField::FIELD_COUNTRY, UFC_Address::TYPE_ANY, UFC_Address::FLAG_ANY); + } +} +// }}} + +// {{{ class UFBF_AdminArea +class UFBF_AdminArea extends UFBF_Mixed +{ + protected $direnum = DirEnum::ADMINAREAS; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_AddressField($this->val, UFC_AddressField::FIELD_ADMAREA, UFC_Address::TYPE_ANY, UFC_Address::FLAG_ANY); + } +} +// }}} + +// {{{ class UFBF_JobCompany +class UFBF_JobCompany extends UFBF_Text +{ + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Job_Company(UFC_Job_Company::JOBNAME, $this->val); + } +} +// }}} + +// {{{ class UFBF_JobSector +class UFBF_JobSector extends UFBF_Mixed +{ + protected $direnum = DirEnum::SECTORS; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Job_Sectorization($this->val, UserFilter::JOB_SUBSUBSECTOR); + } +} +// }}} + +// {{{ class UFBF_JobDescription +class UFBF_JobDescription extends UFBF_Text +{ + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Job_Description($this->val, UserFilter::JOB_USERDEFINED); + } +} +// }}} + +// {{{ class UFBF_JobCv +class UFBF_JobCv extends UFBF_Text +{ + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Job_Description($this->val, UserFilter::JOB_CV); + } +} +// }}} + +// {{{ class UFBF_Nationality +class UFBF_Nationality extends UFBF_Mixed +{ + protected $direnum = DirEnum::NATIONALITIES; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Nationality($this->val); + } +} +// }}} + +// {{{ class UFBF_Binet +class UFBF_Binet extends UFBF_Mixed +{ + protected $direnum = DirEnum::BINETS; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Binet($this->val); + } +} +// }}} + +// {{{ class UFBF_Group +class UFBF_Group extends UFBF_Mixed +{ + protected $direnum = DirEnum::GROUPESX; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + if (count($this->val) == 1) { + return new UFC_Group($this->val[0]); + } + + $or = new PFC_Or(); + foreach ($this->val as $grp) { + $or->addChild(new UFC_Group($grp)); + } + return $or; + } +} +// }}} + +// {{{ class UFBF_Section +class UFBF_Section extends UFBF_Index +{ + protected $direnum = DirEnum::SECTIONS; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Section($this->val); + } +} +// }}} + +// {{{ class UFBF_Formation +class UFBF_Formation extends UFBF_Mixed +{ + protected $direnum = DirEnum::SCHOOLS; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Formation($this->val); + } +} +// }}} + +// {{{ class UFBF_Diploma +class UFBF_Diploma extends UFBF_Mixed +{ + protected $direnum = DirEnum::DEGREES; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Diploma($this->val); + } +} +// }}} + +// {{{ class UFBF_StudiesDomain +class UFBF_StudiesDomain extends UFBF_Mixed +{ + protected $direnum = DirEnum::STUDIESDOMAINS; + + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_StudyField($this->val); + } +} +// }}} + +// {{{ class UFBF_Comment +class UFBF_Comment extends UFBF_Text +{ + protected function buildUFC(UserFilterBuilder &$ufb) + { + return new UFC_Comment($this->val); + } +} +// }}} ?>