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