Fix bug in DirEnum for DE with "suboptions" (degree for a given school, ...)
[platal.git] / include / directory.enums.inc.php
CommitLineData
e39e72a6
RB
1<?php
2/***************************************************************************
3 * Copyright (C) 2003-2010 Polytechnique.org *
4 * http://opensource.polytechnique.org/ *
5 * *
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. *
10 * *
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. *
15 * *
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 *
18 * Foundation, Inc., *
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
20 ***************************************************************************/
21
98925aab 22// {{{ class DirEnum
e39e72a6
RB
23/** This class stores all data for the different kinds of fields.
24 * It is only a dispatcher for the various DirEnum_XXX classes.
25 */
26class DirEnum
27{
28 /** Name of availables Enumerations
29 * Each of these consts contains the basename of the class (its full name
30 * being DE_$basename).
31 */
5c32cc1a
RB
32 const NAMETYPES = 'nametypes';
33
21b67462 34 const BINETS = 'binets';
5ab3ef57 35 const GROUPESX = 'groupesx';
21b67462 36 const SECTIONS = 'sections';
5ab3ef57 37
fb3b6547
RB
38 const EDUSCHOOLS = 'educationschools';
39 const EDUDEGREES = 'educationdegrees';
40 const EDUFIELDS = 'educationfields';
5ab3ef57 41
21b67462
RB
42 const NATIONALITIES = 'nationalities';
43 const COUNTRIES = 'countries';
5ab3ef57
RB
44 const ADMINAREAS = 'adminareas';
45 const LOCALITIES = 'localities';
46
47 const COMPANIES = 'companies';
21b67462 48 const SECTORS = 'sectors';
5ab3ef57
RB
49 const JOBDESCRIPTION = 'jobdescription';
50
21b67462 51 const NETWORKS = 'networking';
e39e72a6
RB
52
53 static private $enumerations = array();
54
55 static private function init($type)
56 {
57 $cls = "DE_" . ucfirst($type);
58 self::$enumerations[$type] = new $cls();
59 }
60
61 /** Retrieves all options for a given type
62 * @param $type Type of enum for which options are requested
63 * @return XorgDbIterator over the results
e39e72a6
RB
64 */
65 static public function getOptions()
66 {
67 $args = func_get_args();
68 $type = array_shift($args);
69 if (!array_key_exists($type, self::$enumerations)) {
70 self::init($type);
71 }
72 $obj = self::$enumerations[$type];
73 return call_user_func_array(array($obj, 'getOptions'), $args);
74 }
21b67462 75
a137e407
RB
76 /** Retrieves all options for a given type
77 * @param $type Type of enum for which options are requested
78 * @return Array of the results the results
79 */
80 static public function getOptionsArray()
81 {
82 $args = func_get_args();
83 $type = array_shift($args);
84 if (!array_key_exists($type, self::$enumerations)) {
85 self::init($type);
86 }
87 $obj = self::$enumerations[$type];
88 return call_user_func_array(array($obj, 'getOptionsArray'), $args);
89 }
90
30b9ca46
RB
91 /** Retrieves all options with number of profiles for autocompletion
92 * @param $type Type of enum for which options are requested
93 * @param $text Text to autocomplete
94 * @return XorgDbIterator over the results
95 */
96 static public function getAutoComplete()
97 {
98 $args = func_get_args();
99 $type = array_shift($args);
100 if (!array_key_exists($type, self::$enumerations)) {
101 self::init($type);
102 }
103 $obj = self::$enumerations[$type];
104 return call_user_func_array(array($obj, 'getAutoComplete'), $args);
105 }
106
98925aab
RB
107 /** Retrieves a list of IDs for a given type
108 * @param $type Type of enum for which IDs are requested
109 * @param $text Text to search in enum valuees
110 * @param $mode Mode of search for those IDs (prefix/suffix/infix)
111 */
21b67462
RB
112 static public function getIDs()
113 {
114 $args = func_get_args();
115 $type = array_shift($args);
116 if (!array_key_exists($type, self::$enumerations)) {
117 self::init($type);
118 }
119 $obj = self::$enumerations[$type];
120 return call_user_func_array(array($obj, 'getIDs'), $args);
121 }
e39e72a6 122}
98925aab 123// }}}
e39e72a6 124
98925aab 125// {{{ class DirEnumeration
e39e72a6
RB
126abstract class DirEnumeration
127{
128 /** An internal array of ID => optionTxt
129 */
9ed7f5bc 130 protected $options = null;
e39e72a6 131
21b67462
RB
132 /** Description of the MySQL storage of the fields
133 */
e39e72a6
RB
134 protected $idfield = 'id';
135 protected $valfield = 'text';
30b9ca46 136 protected $valfield2 = null;
e39e72a6 137 protected $from;
21b67462 138 protected $join = '';
e39e72a6
RB
139 protected $where = '';
140
30b9ca46
RB
141 /** Fields for autocompletion
142 */
143 protected $ac_join = ''; // Additional joins
144 protected $ac_where = null; // Additional where
145 protected $ac_beginwith = true; // Whether to search for 'x%' or for '%x%'
146 protected $ac_unique; // Which field is to be taken as unique
147 protected $ac_distinct = true; // Whether we want to keep only distinct valfield value
148 protected $ac_withid = true; // Do we want to fetch id too ?
149
9ed7f5bc
RB
150 protected function _fetchOptions()
151 {
152 if (is_null($this->options)) {
153 $this->loadOptions();
154 }
e39e72a6
RB
155 }
156
157 public function getOptions()
158 {
9ed7f5bc 159 $this->_fetchOptions();
e39e72a6
RB
160 return $this->options;
161 }
162
a137e407
RB
163 public function getOptionsArray()
164 {
165 $this->_fetchOptions();
166 $options = array();
167 while ($row = $this->options->next()) {
168 $options[$row['id']] = $row['field'];
169 }
170 return $options;
171 }
172
30b9ca46 173 // {{{ function getIDs
21b67462
RB
174 /** Retrieves possible IDs for given text
175 * @param $text Text to search for IDs
176 * @param $mode Mode of search (PREFIX, SUFFIX, CONTAINS)
177 * @return An array of matching IDs ; if empty, input should be considered invalid
178 */
179 public function getIDs($text, $mode)
180 {
658b4c83 181 if ($mode == XDB::WILDCARD_EXACT) {
21b67462
RB
182 $options = $this->getOptions();
183 return array_keys($options, $text);
184 } else {
185 if ($this->where == null) {
186 $where = 'WHERE ';
187 } else {
188 $where = $this->where . ' AND ';
189 }
30b9ca46 190 $conds = array();
658b4c83 191 $conds[] = $this->valfield . XDB::formatWildcards($mode, $text);
30b9ca46 192 if ($this->valfield2 != null) {
658b4c83 193 $conds[] = $this->valfield2 . XDB::formatWildcards($mode, $text);
30b9ca46
RB
194 }
195 $where .= '(' . implode(' OR ', $conds) . ')';
196
21b67462
RB
197 return XDB::fetchColumn('SELECT ' . $this->idfield . '
198 FROM ' . $this->from . '
199 ' . $this->join . '
30b9ca46 200 ' . $where . '
21b67462
RB
201 GROUP BY ' . $this->idfield);
202 }
203 }
30b9ca46 204 // }}}
21b67462 205
30b9ca46
RB
206 private function mkTests($field, $text)
207 {
208 $tests = array();
658b4c83 209 $tests[] = $field . XDB::formatWildcards(XDB::WILDCARD_PREFIX, $text);
30b9ca46 210 if (!$this->ac_beginwith) {
658b4c83
RB
211 $tests[] = $field . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, ' ' . $text);
212 $tests[] = $field . XDB::formatWildcards(XDB::WILDCARD_CONTAINS, '-' . $text);
30b9ca46
RB
213 }
214 return $tests;
215 }
216
217 // {{{ function getAutoComplete
218 public function getAutoComplete($text)
219 {
220 $text = str_replace(array('%', '_'), '', $text);
221
222 if (is_null($this->ac_where) || $this->ac_where == '') {
223 $where = '';
224 } else {
225 $where = $this->ac_where . ' AND ';
226 }
227
228 $tests = $this->mkTests($this->valfield, $text);
229 if (!is_null($this->valfield2)) {
230 $tests = array_merge($tests, $this->mkTests($this->valfield2, $text));
231 }
232
233 $where .= '(' . implode(' OR ', $tests) . ')';
234
235 return XDB::iterator('SELECT ' . $this->valfield . ' AS field'
236 . ($this->ac_distinct ? (', COUNT(DISTINCT ' . $this->ac_unique . ') AS nb') : '')
237 . ($this->ac_withid ? (', ' . $this->idfield . ' AS id') : '') . '
238 FROM ' . $this->from . '
239 ' . $this->ac_join . '
240 WHERE ' . $where . '
241 GROUP BY ' . $this->valfield . '
242 ORDER BY ' . ($this->ac_distinct ? 'nb DESC' : $this->valfield) . '
243 LIMIT 11');
244 }
245 // }}}
246
30b9ca46 247 // {{{ function loadOptions
e39e72a6
RB
248 /** The function used to load options
249 */
250 protected function loadOptions()
251 {
252 $this->options = XDB::iterator('SELECT ' . $this->valfield . ' AS field,
253 ' . $this->idfield . ' AS id
254 FROM ' . $this->from . '
21b67462 255 ' . $this->join . '
e39e72a6
RB
256 ' . $this->where . '
257 GROUP BY ' . $this->valfield . '
258 ORDER BY ' . $this->valfield);
259 }
30b9ca46 260 // }}}
e39e72a6 261}
98925aab 262// }}}
e39e72a6 263
5c32cc1a
RB
264// {{{ class DE_NameTypes
265// returns 'system' names ('lastname', 'lastname_marital', ...)
266class DE_NameTypes extends DirEnumeration
267{
268 protected $from = 'profile_name_enum';
269 protected $valfield = 'type';
270}
271// }}}
272
5ab3ef57
RB
273/** GROUPS
274 */
98925aab 275// {{{ class DE_Binets
e39e72a6
RB
276class DE_Binets extends DirEnumeration
277{
278 protected $from = 'binets_def';
30b9ca46
RB
279
280 protected $ac_join = 'INNER JOIN binets_ins ON (binets_def.id = binets_ins.binet_id)';
281 protected $ac_unique = 'binets_ins.user_id';
e39e72a6 282}
98925aab
RB
283// }}}
284
285// {{{ class DE_Sections
e39e72a6
RB
286class DE_Sections extends DirEnumeration
287{
288 protected $from = 'sections';
30b9ca46
RB
289
290 protected $ac_join = 'INNER JOIN profiles ON (profiles.section = sections.id)';
291 protected $ac_unique = 'profiles.pid';
e39e72a6 292}
98925aab
RB
293// }}}
294
5ab3ef57
RB
295// {{{ class DE_GroupesX
296class DE_GroupesX extends DirEnumeration
297{
298 protected $idfield = 'asso.id';
299 protected $valfield = 'asso.nom';
300 protected $valfield2 = 'asso.diminutif';
eb41eda9 301 protected $from = 'groups AS asso';
5ab3ef57
RB
302 protected $where = 'WHERE (cat = \'GroupesX\' OR cat = \'Institutions\') AND pub = \'public\'';
303
eb41eda9 304 protected $ac_join = "INNER JOIN group_members AS memb ON (asso.id = memb.asso_id
5ab3ef57
RB
305 AND (asso.cat = 'GroupesX' OR asso.cat = 'Institutions')
306 AND asso.pub = 'public')";
307 protected $ac_unique = 'memb.uid';
308}
309// }}}
310
311/** EDUCATION
312 */
fb3b6547
RB
313// {{{ class DE_EducationSchools
314class DE_EducationSchools extends DirEnumeration
e39e72a6 315{
30b9ca46
RB
316 protected $valfield = 'name';
317 protected $valfield2 = 'abbreviation';
318 protected $from = 'profile_education_enum';
319
320 protected $ac_join = 'INNER JOIN profile_education ON (profile_education.eduid = profile_education_enum.id)';
321 protected $ac_unique = 'profile_education.uid';
e39e72a6 322}
98925aab
RB
323// }}}
324
fb3b6547
RB
325// {{{ class DE_EducationDegrees
326class DE_EducationDegrees extends DirEnumeration
e39e72a6 327{
30b9ca46
RB
328 protected $from = 'profile_education_degree_enum';
329 protected $valfield = 'degree';
330
e39e72a6
RB
331 protected $suboptions = array();
332
333 protected function loadOptions()
334 {
335 $res = XDB::query('SELECT ped.eduid, ped.degreeid, pede.degree
336 FROM profile_education_enum AS pee
337 LEFT JOIN profile_education_degree AS ped ON (pee.id = ped.eduid)
338 LEFT JOIN profile_education_degree_enum AS pede ON (ped.degreeid = pede.id)
339 ORDER BY pede.degree');
e5fb8f87 340 $options = array();
e39e72a6
RB
341 foreach($res->fetchAllRow() as $row) {
342 list($eduid, $degreeid, $name) = $row;
e5fb8f87 343 $options[$degreeid] = array('id' => $degreeid, 'field' => $name);
e39e72a6
RB
344 if (!array_key_exists($eduid, $this->suboptions)) {
345 $this->suboptions[$eduid] = array();
346 }
347 $this->suboptions[$eduid][] = array('id' => $degreeid, 'field' => $name);
348 }
e5fb8f87 349 $this->options = PlIteratorUtils::fromArray($options, 1, true);
e39e72a6
RB
350 }
351
352 public function getOptions($eduid = null)
353 {
9ed7f5bc 354 $this->_fetchOptions();
e39e72a6 355 if ($eduid == null) {
e5fb8f87 356 return $this->options;
e39e72a6
RB
357 }
358 if (array_key_exists($eduid, $this->suboptions)) {
359 return PlIteratorUtils::fromArray($this->suboptions[$eduid], 1, true);
360 } else {
361 return array();
362 }
363 }
21b67462 364
e5fb8f87
RB
365 public function getOptionsArray($eduid = null)
366 {
367 $it = $this->getOptions($eduid);
368 $options = array();
369 while ($row = $it->next()) {
370 $options[$row['id']] = $row['field'];
371 }
372 return $options;
373 }
374
21b67462
RB
375 public function getIDs($text, $mode, $eduid = null)
376 {
377 if ($eduid == null) {
378 return XDB::fetchColumn('SELECT id
379 FROM profile_education_degree_enum
658b4c83 380 WHERE degree ' . XDB::formatWildcards($mode, $text));
21b67462
RB
381 } else {
382 return XDB::fetchColumn('SELECT pede.id
383 FROM profile_education_degree AS ped
384 LEFT JOIN profile_education_degree_enum AS pede ON (ped.degreeid = pede.id)
658b4c83 385 WHERE ped.eduid = {?} AND pede.degree ' . XDB::formatWildcards($mode, $text), $eduid);
21b67462
RB
386 }
387 }
388}
98925aab
RB
389// }}}
390
fb3b6547
RB
391// {{{ class DE_EducationFields
392class DE_EducationFields extends DirEnumeration
21b67462
RB
393{
394 protected $valfield = 'field';
30b9ca46
RB
395 protected $from = 'profile_education_field_enum';
396
397 protected $ac_join = 'INNER JOIN profile_education ON (profile_education.fieldid = profile_education_field_enum.id)';
398 protected $ac_unique = 'profile_education.uid';
e39e72a6 399}
98925aab
RB
400// }}}
401
5ab3ef57
RB
402/** GEOLOC
403 */
98925aab 404// {{{ class DE_Nationalities
e39e72a6
RB
405class DE_Nationalities extends DirEnumeration
406{
30b9ca46
RB
407 protected $idfield = 'iso_3166_1_a2';
408 protected $valfield = 'nationalityFR';
409 protected $valfield2 = 'nationality';
410 protected $from = 'geoloc_countries AS gc';
411 protected $join = 'INNER JOIN profiles AS p ON (gc.iso_3166_1_a2 IN (p.nationality1, p.nationality2, p.nationality3))';
412
413 protected $ac_join = 'INNER JOIN profiles AS p ON (gc.iso_3166_1_a2 IN (p.nationality1, p.nationality2, p.nationality3))';
414 protected $ac_unique = 'profiles.pid';
e39e72a6 415}
98925aab
RB
416// }}}
417
418// {{{ class DE_Countries
e39e72a6
RB
419class DE_Countries extends DirEnumeration
420{
30b9ca46
RB
421 protected $idfield = 'iso_3166_1_a2';
422 protected $valfield = 'countryFR';
423 protected $valfield2 = 'country';
424 protected $from = 'geoloc_countries';
425
426 protected $ac_join = 'INNER JOIN profile_addresses ON (geoloc_countries.iso_3166_1_a2 = profile_addresses.countryFR';
427 protected $ac_unique = 'profile_addresses.pid';
e39e72a6 428}
98925aab
RB
429// }}}
430
431// {{{ class DE_AdminAreas
e39e72a6
RB
432class DE_AdminAreas extends DirEnumeration
433{
434 protected $suboptions = array();
435
436 protected function loadOptions()
437 {
438 $res = XDB::query('SELECT id, name AS field, country
439 FROM geoloc_administrativeareas
440 GROUP BY name
441 ORDER BY name');
e5fb8f87 442 $options = array();
e39e72a6
RB
443 foreach($res->fetchAllRow() as $row) {
444 list($id, $field, $country) = $row;
e5fb8f87 445 $options[$id] = array('id' => $id, 'field' => $field);
e39e72a6
RB
446 if (!array_key_exists($country, $this->suboptions)) {
447 $this->suboptions[$country] = array();
448 }
449 $this->suboptions[$country][] = array('id' => $id, 'field' => $field);
450 }
e5fb8f87 451 $this->options = PlIteratorUtils::fromArray($options, 1, true);
e39e72a6
RB
452 }
453
454 public function getOptions($country = null)
455 {
9ed7f5bc
RB
456 $this->_fetchOptions();
457
e39e72a6 458 if ($country == null) {
e5fb8f87 459 return $this->options;
e39e72a6
RB
460 }
461 if (array_key_exists($country, $this->suboptions)) {
462 return PlIteratorUtils::fromArray($this->suboptions[$country], 1, true);
463 } else {
464 return array();
465 }
466 }
21b67462 467
e5fb8f87
RB
468 public function getOptionsArray($country = null)
469 {
470 $it = $this->getOptions($eduid);
471 $options = array();
472 while ($row = $it->next()) {
473 $options[$row['id']] = $row['field'];
474 }
475 return $options;
476 }
477
21b67462
RB
478 public function getIDs($text, $mode, $country = null)
479 {
480 if ($country == null) {
481 return XDB::fetchColumn('SELECT id
482 FROM geoloc_administrativeareas
658b4c83 483 WHERE name ' . XDB::formatWildcards($mode, $text));
21b67462
RB
484 } else {
485 return XDB::fetchColumn('SELECT id
486 FROM geoloc_administrativeareas
658b4c83 487 WHERE country = {?} AND name' . XDB::formatWildcards($mode, $text), $country);
21b67462
RB
488 }
489 }
e39e72a6 490}
98925aab
RB
491// }}}
492
5ab3ef57
RB
493// {{{ class DE_Localities
494class DE_Localities extends DirEnumeration
e39e72a6 495{
5ab3ef57
RB
496 protected $valfield = 'gl.name';
497 protected $from = 'geoloc_localities AS gl';
30b9ca46 498
5ab3ef57
RB
499 protected $ac_join = 'profile_addresses AS pa ON (pa.localityID = gl.id)';
500 protected $ac_unique = 'pa.pid';
501}
502// }}}
503
504/** JOBS
505 */
506// {{{ class DE_Companies
507class DE_Companies extends DirEnumeration
508{
509 protected $valfield = 'pje.name';
510 protected $valfield2 = 'pje.acronym';
511 protected $from = 'profile_job_enum AS pje';
512
513 protected $ac_join = 'INNER JOIN profile_job AS pj ON (pj.jobid = pje.id)';
514 protected $ac_unique = 'pj.uid';
e39e72a6 515}
98925aab
RB
516// }}}
517
518// {{{ class DE_Sectors
e39e72a6
RB
519class DE_Sectors extends DirEnumeration
520{
30b9ca46
RB
521 protected $valfield = 'name';
522 protected $from = 'profile_job_sector_enum';
523
524 protected $ac_join = 'INNER JOIN profile_job ON (profile_job_sector_enum.id = profile_job.sectorid)';
525 protected $ac_unique = 'profile_job.uid';
e39e72a6 526}
98925aab
RB
527// }}}
528
5ab3ef57
RB
529// {{{ class DE_JobDescription
530class DE_JobDescription
531{
532 protected $valfield = 'pj.description';
533 protected $from = 'profile_job AS pj';
534 protected $idfield = 'pj.pid';
535
536 protected $ac_unique = 'pj.pid';
537}
538// }}}
539
540/** NETWORKING
541 */
98925aab 542// {{{ class DE_Networking
e39e72a6
RB
543class DE_Networking extends DirEnumeration
544{
30b9ca46
RB
545 protected $idfield = 'profile_networking_enum.network_type';
546 protected $valfield = 'profile_networking_enum.name';
e39e72a6 547 protected $from = 'profile_networking_enum';
30b9ca46
RB
548
549
550 protected $ac_join = 'INNER JOIN profile_networking ON (profile_networking.network_type = profile_networking_enum.network_type';
551 protected $ac_unique = 'profile_networking.uid';
e39e72a6 552}
98925aab 553// }}}
e39e72a6 554?>