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