X-Git-Url: http://git.polytechnique.org/?a=blobdiff_plain;f=include%2Fdirectory.enums.inc.php;h=9b31f246366a91cdc4fcb88e0ee1b642873c2656;hb=2998edf118b3d6243171dd3294247ad1324ac343;hp=4a61151aefaa5c8eb06c5fe0c4f68b8a70a16328;hpb=21b6746289ae4bcd60128f0c849a74af8da7f62b;p=platal.git diff --git a/include/directory.enums.inc.php b/include/directory.enums.inc.php index 4a61151..9b31f24 100644 --- a/include/directory.enums.inc.php +++ b/include/directory.enums.inc.php @@ -19,6 +19,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ***************************************************************************/ +// {{{ class DirEnum /** This class stores all data for the different kinds of fields. * It is only a dispatcher for the various DirEnum_XXX classes. */ @@ -28,17 +29,26 @@ class DirEnum * Each of these consts contains the basename of the class (its full name * being DE_$basename). */ + const NAMETYPES = 'nametypes'; + const BINETS = 'binets'; + const GROUPESX = 'groupesx'; const SECTIONS = 'sections'; - const SCHOOLS = 'schools'; - const DEGREES = 'degrees'; - const STUDIESDOMAINS = 'studiesdomains'; + + const EDUSCHOOLS = 'educationschools'; + const EDUDEGREES = 'educationdegrees'; + const EDUFIELDS = 'educationfields'; + const NATIONALITIES = 'nationalities'; const COUNTRIES = 'countries'; - const GROUPESX = 'groupesx'; + const ADMINAREAS = 'adminareas'; + const LOCALITIES = 'localities'; + + const COMPANIES = 'companies'; const SECTORS = 'sectors'; + const JOBDESCRIPTION = 'jobdescription'; + const NETWORKS = 'networking'; - const ADMINAREAS = 'adminareas'; static private $enumerations = array(); @@ -50,9 +60,7 @@ class DirEnum /** Retrieves all options for a given type * @param $type Type of enum for which options are requested - * @return XorgDbIterator over the results - * TODO : add support for optional parameters transmitted to enumerations - * TODO : Find a way to get either an array, or the adequate PlIterator + * @return Array of the results */ static public function getOptions() { @@ -62,9 +70,57 @@ class DirEnum self::init($type); } $obj = self::$enumerations[$type]; - return call_user_func_array(array($obj, 'getOptions'), $args); + if ($obj->capabilities & DirEnumeration::HAS_OPTIONS) { + return call_user_func_array(array($obj, 'getOptions'), $args); + } else { + return array(); + } } + /** Retrieves all options for a given type + * @param $type Type of enum for which options are requested + * @return PlIterator over the results + */ + static public function getOptionsIter() + { + $args = func_get_args(); + $type = array_shift($args); + if (!array_key_exists($type, self::$enumerations)) { + self::init($type); + } + $obj = self::$enumerations[$type]; + if ($obj->capabilities & DirEnumeration::HAS_OPTIONS) { + return call_user_func_array(array($obj, 'getOptionsIter'), $args); + } else { + return PlIteratorUtils::fromArray(array()); + } + } + + /** Retrieves all options with number of profiles for autocompletion + * @param $type Type of enum for which options are requested + * @param $text Text to autocomplete + * @return PlIterator over the results + */ + static public function getAutoComplete() + { + $args = func_get_args(); + $type = array_shift($args); + if (!array_key_exists($type, self::$enumerations)) { + self::init($type); + } + $obj = self::$enumerations[$type]; + if ($obj->capabilities & DirEnumeration::HAS_AUTOCOMP) { + return call_user_func_array(array($obj, 'getAutoComplete'), $args); + } else { + return PlIteratorUtils::fromArray(array()); + } + } + + /** Retrieves a list of IDs for a given type + * @param $type Type of enum for which IDs are requested + * @param $text Text to search in enum valuees + * @param $mode Mode of search for those IDs (prefix/suffix/infix) + */ static public function getIDs() { $args = func_get_args(); @@ -73,40 +129,66 @@ class DirEnum self::init($type); } $obj = self::$enumerations[$type]; - return call_user_func_array(array($obj, 'getIDs'), $args); + if ($obj->capabilities & DirEnumeration::HAS_OPTIONS) { + return call_user_func_array(array($obj, 'getIDs'), $args); + } else { + return array(); + } } } +// }}} +// {{{ class DirEnumeration abstract class DirEnumeration { - /** Modes for LIKE searches - */ - const MODE_EXACT = 0x000; - const MODE_PREFIX = 0x001; - const MODE_SUFFIX = 0x002; - const MODE_CONTAINS = 0x003; + const AUTOCOMPLETE_LIMIT = 11; + + const HAS_OPTIONS = 0x001; + const HAS_AUTOCOMP = 0x002; + + public $capabilities = 0x003; // self::HAS_OPTIONS | self::HAS_AUTOCOMP; /** An internal array of ID => optionTxt */ - protected $options; + protected $options = null; /** Description of the MySQL storage of the fields */ protected $idfield = 'id'; protected $valfield = 'text'; + protected $valfield2 = null; protected $from; protected $join = ''; protected $where = ''; - public function __construct() { - $this->loadOptions(); + /** Fields for autocompletion + */ + protected $ac_join = ''; // Additional joins + protected $ac_where = null; // Additional where + protected $ac_beginwith = true; // Whether to search for 'x%' or for '%x%' + protected $ac_unique; // Which field is to be taken as unique + protected $ac_distinct = true; // Whether we want to keep only distinct valfield value + protected $ac_withid = true; // Do we want to fetch id too ? + + protected function _fetchOptions() + { + if (is_null($this->options)) { + $this->loadOptions(); + } } public function getOptions() { + $this->_fetchOptions(); return $this->options; } + public function getOptionsIter() + { + return PlIteratorUtils::fromArray(self::expandArray($this->getOptions()), 1, true); + } + + // {{{ function getIDs /** Retrieves possible IDs for given text * @param $text Text to search for IDs * @param $mode Mode of search (PREFIX, SUFFIX, CONTAINS) @@ -114,7 +196,7 @@ abstract class DirEnumeration */ public function getIDs($text, $mode) { - if ($mode == self::MODE_EXACT) { + if ($mode == XDB::WILDCARD_EXACT) { $options = $this->getOptions(); return array_keys($options, $text); } else { @@ -123,181 +205,392 @@ abstract class DirEnumeration } else { $where = $this->where . ' AND '; } + $conds = array(); + $conds[] = $this->valfield . XDB::formatWildcards($mode, $text); + if ($this->valfield2 != null) { + $conds[] = $this->valfield2 . XDB::formatWildcards($mode, $text); + } + $where .= '(' . implode(' OR ', $conds) . ')'; + return XDB::fetchColumn('SELECT ' . $this->idfield . ' FROM ' . $this->from . ' ' . $this->join . ' - ' . $where . $this->valfield . self::makeSqlConcat($text, $mode) . ' + ' . $where . ' GROUP BY ' . $this->idfield); } } + // }}} - static protected function makeSqlConcat($text, $mode) + private function mkTests($field, $text) { - if ($mode == self::MODE_EXACT) { - return ' = ' . XDB::format('{?}', $text); + $tests = array(); + $tests[] = $field . XDB::formatWildcards(XDB::WILDCARD_PREFIX, $text); + if (!$this->ac_beginwith) { + $tests[] = $field . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, ' ' . $text); + $tests[] = $field . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, '-' . $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); + return $tests; + } + + static protected function expandArray(array $tab, $keyname = 'id', $valname = 'field') + { + $res = array(); + foreach ($tab as $key => $val) { + $res[$key] = array( + $keyname => $key, + $valname => $val, + ); + } + return $res; + } + + // {{{ function getAutoComplete + public function getAutoComplete($text) + { + $text = str_replace(array('%', '_'), '', $text); + + if (is_null($this->ac_where) || $this->ac_where == '') { + $where = ''; } else { - $right = XDB::format('CONCAT(\'%\', {?}, \'%\')', $text); + $where = $this->ac_where . ' AND '; } - return ' LIKE ' . $right; + + $tests = $this->mkTests($this->valfield, $text); + if (!is_null($this->valfield2)) { + $tests = array_merge($tests, $this->mkTests($this->valfield2, $text)); + } + + $where .= '(' . implode(' OR ', $tests) . ')'; + + return XDB::iterator('SELECT ' . $this->valfield . ' AS field' + . ($this->ac_distinct ? (', COUNT(DISTINCT ' . $this->ac_unique . ') AS nb') : '') + . ($this->ac_withid ? (', ' . $this->idfield . ' AS id') : '') . ' + FROM ' . $this->from . ' + ' . $this->ac_join . ' + WHERE ' . $where . ' + GROUP BY ' . $this->valfield . ' + ORDER BY ' . ($this->ac_distinct ? 'nb DESC' : $this->valfield) . ' + LIMIT ' . self::AUTOCOMPLETE_LIMIT); } + // }}} + // {{{ function loadOptions /** The function used to load options */ protected function loadOptions() { - $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); + $this->options = XDB::fetchAllAssoc('id', 'SELECT ' . $this->valfield . ' AS field, + ' . $this->idfield . ' AS id + FROM ' . $this->from . ' + ' . $this->join . ' + ' . $this->where . ' + GROUP BY ' . $this->valfield . ' + ORDER BY ' . $this->valfield); } + // }}} } +// }}} -class DE_Binets extends DirEnumeration -{ - protected $from = 'binets_def'; -} -class DE_Sections extends DirEnumeration -{ - protected $from = 'sections'; -} -class DE_Schools extends DirEnumeration -{ - protected $valfield = 'name'; - protected $from = 'profile_education_enum'; -} -class DE_Degrees extends DirEnumeration +// {{{ class DE_WithSuboption +/** A class for DirEnum with possibility to select only suboptions for a given parameter (country, school, ...) + */ +abstract class DE_WithSuboption extends DirEnumeration { - protected $suboptions = array(); + protected $optfield; + + protected $suboptions = null; protected function loadOptions() { - $res = XDB::query('SELECT ped.eduid, ped.degreeid, pede.degree - FROM profile_education_enum AS pee - LEFT JOIN profile_education_degree AS ped ON (pee.id = ped.eduid) - LEFT JOIN profile_education_degree_enum AS pede ON (ped.degreeid = pede.id) - ORDER BY pede.degree'); - foreach($res->fetchAllRow() as $row) { - list($eduid, $degreeid, $name) = $row; - $this->options[$degreeid] = array('id' => $degreeid, 'field' => $name); - if (!array_key_exists($eduid, $this->suboptions)) { - $this->suboptions[$eduid] = array(); + $opts = XDB::fetchAllAssoc('id', 'SELECT ' . $this->valfield . ' AS field, + ' . $this->optfield . ' AS subid, + ' . $this->idfield . ' AS id + FROM ' . $this->from . ' + ' . $this->join . ' + ' . $this->where . ' + GROUP BY ' . $this->valfield . ' + ORDER BY ' . $this->valfield); + $this->options = array(); + $this->suboptions = array(); + foreach ($opts as $id => $opt) { + $this->options[$id] = $opt['field']; + if (!array_key_exists($opt['subid'], $this->suboptions)) { + $this->suboptions[$opt['subid']] = array(); } - $this->suboptions[$eduid][] = array('id' => $degreeid, 'field' => $name); + $this->suboptions[$opt['subid']][$id] = $opt['field']; } } - public function getOptions($eduid = null) + public function getOptions($subid = null) { - if ($eduid == null) { - return PlIteratorUtils::fromArray($this->options, 1, true); + $this->_fetchOptions(); + if ($subid == null) { + return $this->options; + } else if (array_key_exists($subid, $this->suboptions)) { + return $this->suboptions[$subid]; + } else { + return false; } - if (array_key_exists($eduid, $this->suboptions)) { - return PlIteratorUtils::fromArray($this->suboptions[$eduid], 1, true); + } + + public function getOptionsIter($subid = null) + { + return PlIteratorUtils::fromArray(self::expandArray($this->getOptions($subid)), 1, true); + } + + public function getIDs($text, $mode, $subid = null) + { + if ($mode == XDB::WILDCARD_EXACT) { + $options = $this->getOptions($subid); + return array_keys($options, $text); } else { - return array(); + if ($this->where == null) { + $where = 'WHERE '; + } else { + $where = $this->where . ' AND '; + } + if ($subid != null && array_key_exists($subid, $this->suboptions)) { + $where .= XDB::format($this->optfield . ' = {?} AND ', $subid); + } + + $conds = array(); + $conds[] = $this->valfield . XDB::formatWildcards($mode, $text); + if ($this->valfield2 != null) { + $conds[] = $this->valfield2 . XDB::formatWildcards($mode, $text); + } + $where .= '(' . implode(' OR ', $conds) . ')'; + + return XDB::fetchColumn('SELECT ' . $this->idfield . ' + FROM ' . $this->from . ' + ' . $this->join . ' + ' . $where . ' + GROUP BY ' . $this->idfield); } } - public function getIDs($text, $mode, $eduid = null) + public function getAutoComplete($text, $subid = null) { - if ($eduid == null) { - return XDB::fetchColumn('SELECT id - FROM profile_education_degree_enum - WHERE degree ' . self::makeSqlConcat($text, $mode)); + $text = str_replace(array('%', '_'), '', $text); + + if (is_null($this->ac_where) || $this->ac_where == '') { + $where = ''; } 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); + $where = $this->ac_where . ' AND '; } + + if ($subid != null && array_key_exists($subid, $this->suboptions)) { + $where .= XDB::format($this->optfield . ' = {?} AND ', $subid); + } + + $tests = $this->mkTests($this->valfield, $text); + if (!is_null($this->valfield2)) { + $tests = array_merge($tests, $this->mkTests($this->valfield2, $text)); + } + + $where .= '(' . implode(' OR ', $tests) . ')'; + + return XDB::iterator('SELECT ' . $this->valfield . ' AS field' + . ($this->ac_distinct ? (', COUNT(DISTINCT ' . $this->ac_unique . ') AS nb') : '') + . ($this->ac_withid ? (', ' . $this->idfield . ' AS id') : '') . ' + FROM ' . $this->from . ' + ' . $this->ac_join . ' + WHERE ' . $where . ' + GROUP BY ' . $this->valfield . ' + ORDER BY ' . ($this->ac_distinct ? 'nb DESC' : $this->valfield) . ' + LIMIT ' . self::AUTOCOMPLETE_LIMIT); } } -class DE_StudiesSector extends DirEnumeration +// }}} + +// {{{ class DE_NameTypes +// returns 'system' names ('lastname', 'lastname_marital', ...) +class DE_NameTypes extends DirEnumeration { - protected $valfield = 'field'; - protected $from = 'profile_education_field_enum'; + public $capabilities = self::HAS_OPTIONS; + + protected $from = 'profile_name_enum'; + protected $valfield = 'type'; } +// }}} + +/** GROUPS + */ +// {{{ class DE_Binets +class DE_Binets extends DirEnumeration +{ + protected $from = 'binets_def'; + + protected $ac_join = 'INNER JOIN binets_ins ON (binets_def.id = binets_ins.binet_id)'; + protected $ac_unique = 'binets_ins.user_id'; +} +// }}} + +// {{{ class DE_Sections +class DE_Sections extends DirEnumeration +{ + protected $from = 'sections'; + + protected $ac_join = 'INNER JOIN profiles ON (profiles.section = sections.id)'; + protected $ac_unique = 'profiles.pid'; +} +// }}} + +// {{{ class DE_GroupesX +class DE_GroupesX extends DirEnumeration +{ + protected $idfield = 'groups.id'; + protected $valfield = 'groups.nom'; + protected $valfield2 = 'groups.diminutif'; + protected $from = 'groups'; + protected $where = 'WHERE (cat = \'GroupesX\' OR cat = \'Institutions\') AND pub = \'public\''; + + protected $ac_join = "INNER JOIN group_members ON (groups.id = memb.asso_id + AND (groups.cat = 'GroupesX' OR groups.cat = 'Institutions') + AND groups.pub = 'public')"; + protected $ac_unique = 'group_members.uid'; +} +// }}} + +/** EDUCATION + */ +// {{{ class DE_EducationSchools +class DE_EducationSchools extends DirEnumeration +{ + protected $valfield = 'profile_education_enum.name'; + protected $valfield2 = 'profile_education_enum.abbreviation'; + protected $from = 'profile_education_enum'; + + protected $ac_join = 'INNER JOIN profile_education ON (profile_education.eduid = profile_education_enum.id)'; + protected $ac_unique = 'profile_education.uid'; +} +// }}} + +// {{{ class DE_EducationDegrees +class DE_EducationDegrees extends DirEnumeration +{ + public $capabilities = self::HAS_OPTIONS; + + protected $idfield = 'profile_education_degree.degreeid'; + protected $optfield = 'profile_education_degree.eduid'; + protected $valfield = 'profile_education_degree_enum.degree'; + protected $from = 'profile_education_degree_enum'; + protected $join = 'INNER JOIN profile_education_degree ON (profile_education_degree.degreeid = profile_education_degree_enum.id)'; + +} +// }}} + +// {{{ class DE_EducationFields +class DE_EducationFields extends DirEnumeration +{ + protected $valfield = 'profile_education_field_enum.field'; + protected $from = 'profile_education_field_enum'; + + protected $ac_join = 'INNER JOIN profile_education ON (profile_education.fieldid = profile_education_field_enum.id)'; + protected $ac_unique = 'profile_education.uid'; +} +// }}} + +/** GEOLOC + */ +// {{{ class DE_Nationalities class DE_Nationalities extends DirEnumeration { - protected $idfield = 'iso_3166_1_a2'; - protected $valfield = 'nationalityFR'; - protected $from = 'geoloc_countries AS gc'; - protected $join = 'INNER JOIN profiles AS p ON (gc.iso_3166_1_a2 IN (p.nationality1, p.nationality2, p.nationality3))'; + protected $idfield = 'geoloc_countries.iso_3166_1_a2'; + protected $valfield = 'geoloc_countries.nationalityFR'; + protected $valfield2 = 'geoloc_countries.nationality'; + protected $from = 'geoloc_countries'; + protected $join = 'INNER JOIN profiles ON (geoloc_countries.iso_3166_1_a2 IN (profiles.nationality1, profiles.nationality2, profiles.nationality3))'; + + protected $ac_join = 'INNER JOIN profiles ON (geoloc_countries.iso_3166_1_a2 IN (profiles.nationality1, profiles.nationality2, profiles.nationality3))'; + protected $ac_unique = 'profiles.pid'; } +// }}} + +// {{{ class DE_Countries class DE_Countries extends DirEnumeration { - protected $idfield = 'iso_3166_1_a2'; - protected $valfield = 'countryFR'; - protected $from = 'geoloc_countries'; + protected $idfield = 'geoloc_countries.iso_3166_1_a2'; + protected $valfield = 'geoloc_countries.countryFR'; + protected $valfield2 = 'geoloc_countries.country'; + protected $from = 'geoloc_countries'; + + protected $ac_join = 'INNER JOIN profile_addresses ON (geoloc_countries.iso_3166_1_a2 = profile_addresses.countryFR'; + protected $ac_unique = 'profile_addresses.pid'; } -class DE_AdminAreas extends DirEnumeration +// }}} + +// {{{ class DE_AdminAreas +class DE_AdminAreas extends DE_WithSuboption { - protected $suboptions = array(); + protected $idfield = 'geoloc_administrativeareas.id'; + protected $optfield = 'geoloc_administrativeareas.country'; + protected $valfield = 'geoloc_administrativeareas.name'; + protected $from = 'geoloc_administrativeareas'; - protected function loadOptions() - { - $res = XDB::query('SELECT id, name AS field, country - FROM geoloc_administrativeareas - GROUP BY name - ORDER BY name'); - foreach($res->fetchAllRow() as $row) { - list($id, $field, $country) = $row; - $this->options[] = array('id' => $id, 'field' => $field); - if (!array_key_exists($country, $this->suboptions)) { - $this->suboptions[$country] = array(); - } - $this->suboptions[$country][] = array('id' => $id, 'field' => $field); - } - } + protected $ac_join = 'INNER JOIN profile_addresses ON (profile_addresses.administrativeAreaId = geoloc_administrativeareas.id)'; + protected $ac_unique = 'profile_addresses.pid'; +} +// }}} - public function getOptions($country = null) - { - if ($country == null) { - return PlIteratorUtils::fromArray($this->options, 1, true); - } - if (array_key_exists($country, $this->suboptions)) { - return PlIteratorUtils::fromArray($this->suboptions[$country], 1, true); - } else { - return array(); - } - } +// {{{ class DE_Localities +class DE_Localities extends DirEnumeration +{ + protected $valfield = 'geoloc_localities.name'; + protected $from = 'geoloc_localities'; - 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); - } - } + protected $ac_join = 'profile_addresses ON (profile_addresses.localityID = geoloc_localities.id)'; + protected $ac_unique = 'profile_addresses.pid'; } -class DE_GroupesX extends DirEnumeration +// }}} + +/** JOBS + */ +// {{{ class DE_Companies +class DE_Companies extends DirEnumeration { - protected $valfield = 'nom'; - protected $from = '#groupex#.asso'; - protected $where = 'WHERE (cat = \'GroupesX\' OR cat = \'Institutions\') AND pub = \'public\''; + protected $valfield = 'profile_job_enum.name'; + protected $valfield2 = 'profile_job_enum.acronym'; + protected $from = 'profile_job_enum'; + + protected $ac_join = 'INNER JOIN profile_job ON (profile_job.jobid = profile_job_enum.id)'; + protected $ac_unique = 'profile_job.uid'; } +// }}} + +// {{{ class DE_Sectors class DE_Sectors extends DirEnumeration { - protected $valfield = 'name'; - protected $from = 'profile_job_sector_enum'; + protected $valfield = 'profile_job_sector_enum.name'; + protected $from = 'profile_job_sector_enum'; + + protected $ac_join = 'INNER JOIN profile_job ON (profile_job_sector_enum.id = profile_job.sectorid)'; + protected $ac_unique = 'profile_job.uid'; } +// }}} + +// {{{ class DE_JobDescription +class DE_JobDescription +{ + protected $valfield = 'profile_job.description'; + protected $from = 'profile_job'; + protected $idfield = 'profile_job.pid'; + + protected $ac_unique = 'profile_job.pid'; +} +// }}} + +/** NETWORKING + */ +// {{{ class DE_Networking class DE_Networking extends DirEnumeration { - protected $idfield = 'network_type'; - protected $valfield = 'name'; + protected $idfield = 'profile_networking_enum.network_type'; + protected $valfield = 'profile_networking_enum.name'; protected $from = 'profile_networking_enum'; + + + protected $ac_join = 'INNER JOIN profile_networking ON (profile_networking.network_type = profile_networking_enum.network_type'; + protected $ac_unique = 'profile_networking.uid'; } +// }}} ?>