0337d704 |
1 | <?php |
2 | /*************************************************************************** |
5ddeb07c |
3 | * Copyright (C) 2003-2007 Polytechnique.org * |
0337d704 |
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 | |
22 | require_once("xorg.misc.inc.php"); |
23 | |
24 | // {{{ Global variables used for the search Queries |
25 | |
35fa92e8 |
26 | @$globals->search->result_fields = ' |
94f6c381 |
27 | u.user_id, u.promo, u.matricule, u.matricule_ax, |
28 | if(u.nom_usage=\'\', u.nom, u.nom_usage) AS NomSortKey, |
29 | u.nom_usage,u.date, |
30 | u.deces!=0 AS dcd,u.deces, |
31 | u.perms IN (\'admin\',\'user\', \'disabled\') AS inscrit, |
32 | u.perms != \'pending\' AS wasinscrit, |
33 | FIND_IN_SET(\'femme\', u.flags) AS sexe, |
34 | a.alias AS forlife, |
35 | ad0.text AS app0text, ad0.url AS app0url, ai0.type AS app0type, |
36 | ad1.text AS app1text, ad1.url AS app1url, ai1.type AS app1type, |
37 | es.label AS secteur, ef.fonction_fr AS fonction, |
38 | IF(n.nat=\'\',n.pays,n.nat) AS nat, n.a2 AS iso3166, |
39 | COUNT(em.email) > 0 AS actif,'; |
0337d704 |
40 | // hide private information if not logged |
787bb3d7 |
41 | if (S::logged()) |
94f6c381 |
42 | $globals->search->result_fields .=' |
43 | q.profile_web AS web, |
44 | q.profile_mobile AS mobile, |
45 | q.profile_freetext AS freetext, |
46 | adr.city, gp.pays AS countrytxt, gr.name AS region, |
47 | e.entreprise,'; |
0337d704 |
48 | else |
94f6c381 |
49 | $globals->search->result_fields .=" |
50 | IF(q.profile_web_pub='public', q.profile_web, '') AS web, |
51 | IF(q.profile_mobile_pub='public', q.profile_mobile, '') AS mobile, |
52 | IF(q.profile_freetext_pub='public', q.profile_freetext, '') AS freetext, |
53 | IF(adr.pub='public', adr.city, '') AS city, |
54 | IF(adr.pub='public', gp.pays, '') AS countrytxt, |
55 | IF(adr.pub='public', gr.name, '') AS region, |
56 | IF(e.pub='public', e.entreprise, '') AS entreprise,"; |
35fa92e8 |
57 | @$globals->search->result_where_statement = ' |
94f6c381 |
58 | LEFT JOIN applis_ins AS ai0 ON (u.user_id = ai0.uid AND ai0.ordre = 0) |
59 | LEFT JOIN applis_def AS ad0 ON (ad0.id = ai0.aid) |
60 | LEFT JOIN applis_ins AS ai1 ON (u.user_id = ai1.uid AND ai1.ordre = 1) |
61 | LEFT JOIN applis_def AS ad1 ON (ad1.id = ai1.aid) |
62 | LEFT JOIN entreprises AS e ON (e.entrid = 0 AND e.uid = u.user_id) |
63 | LEFT JOIN emploi_secteur AS es ON (e.secteur = es.id) |
64 | LEFT JOIN fonctions_def AS ef ON (e.fonction = ef.id) |
65 | LEFT JOIN geoloc_pays AS n ON (u.nationalite = n.a2) |
66 | LEFT JOIN adresses AS adr ON (u.user_id = adr.uid AND FIND_IN_SET(\'active\',adr.statut)) |
67 | LEFT JOIN geoloc_pays AS gp ON (adr.country = gp.a2) |
68 | LEFT JOIN geoloc_region AS gr ON (adr.country = gr.a2 AND adr.region = gr.region) |
69 | LEFT JOIN emails AS em ON (em.uid = u.user_id AND em.flags = \'active\')'; |
0337d704 |
70 | |
71 | // }}} |
0337d704 |
72 | // {{{ class ThrowError |
73 | |
74 | /** handle errors for end-users queries |
75 | * assign the error message and runs the templates |
76 | * |
77 | * @author Jean-Sebastien Bedo |
78 | */ |
79 | class ThrowError |
80 | { |
a2aa8436 |
81 | public static $throwHook = array('ThrowError', 'defaultHandler'); |
82 | |
0337d704 |
83 | /** constuctor |
84 | * @param $explain string the error (in natural language) |
85 | */ |
92432704 |
86 | public function __construct($explain) |
0337d704 |
87 | { |
a2aa8436 |
88 | call_user_func(ThrowError::$throwHook, $explain); |
89 | } |
90 | |
91 | /** defaut error handler |
92 | */ |
93 | private static function defaultHandler($explain) |
94 | { |
bc67c37c |
95 | global $page, $globals; |
96 | $page->changeTpl('search/index.tpl'); |
97 | $page->assign('xorg_title','Polytechnique.org - Annuaire'); |
98 | $page->assign('baseurl', $globals->baseurl); |
c9110c6c |
99 | $page->trig('Erreur : '.$explain); |
100 | $page->run(); |
0337d704 |
101 | } |
102 | } |
103 | |
104 | // }}} |
105 | // {{{ class SField [Base class] |
106 | |
a7de4ef7 |
107 | /** classe de base représentant un champ de recherche |
108 | * (correspond à un champ du formulaire mais peut être à plusieurs champs de la bdd) |
109 | * interface étendue pour chaque type de champ particulier |
0337d704 |
110 | */ |
111 | class SField |
112 | { |
113 | // {{{ properties |
94f6c381 |
114 | |
0337d704 |
115 | /** le nom du champ dans le formulaire HTML */ |
116 | var $fieldFormName; |
a7de4ef7 |
117 | /** champs de la bdd correspondant à ce champ sous forme d'un tableau */ |
0337d704 |
118 | var $fieldDbName; |
a7de4ef7 |
119 | /** champ résultat dans la requête MySQL correspondant à ce champ |
120 | * (alias utilisé pour la clause ORDER BY) */ |
0337d704 |
121 | var $fieldResultName; |
a7de4ef7 |
122 | /** valeur du champ instanciée par l'utilisateur */ |
0337d704 |
123 | var $value; |
124 | |
125 | // }}} |
126 | // {{{ constructor |
127 | |
128 | /** constructeur |
a7de4ef7 |
129 | * (récupère la requête de l'utilisateur pour ce champ) */ |
0337d704 |
130 | function SField($_fieldFormName, $_fieldDbName='', $_fieldResultName='') |
131 | { |
132 | $this->fieldFormName = $_fieldFormName; |
133 | $this->fieldDbName = $_fieldDbName; |
134 | $this->fieldResultName = $_fieldResultName; |
135 | $this->get_request(); |
136 | } |
137 | |
138 | // }}} |
139 | // {{{ function get_request() |
140 | |
787bb3d7 |
141 | /** récupérer la requête de l'utilisateur |
a7de4ef7 |
142 | * on met une chaîne vide si le champ n'a pas été complété */ |
0337d704 |
143 | function get_request() |
144 | { |
5e2307dc |
145 | $this->value = trim(Env::v($this->fieldFormName)); |
0337d704 |
146 | } |
147 | |
148 | // }}} |
149 | // {{{ function get_where_statement() |
94f6c381 |
150 | |
a7de4ef7 |
151 | /** récupérer la clause correspondant au champ dans la clause WHERE de la requête |
787bb3d7 |
152 | * on parcourt l'ensemble des champs de la bdd de $fieldDbName et on associe |
a7de4ef7 |
153 | * à chacun d'entre eux une clause spécifique |
154 | * la clause totale et la disjonction de ces clauses spécifiques */ |
0337d704 |
155 | function get_where_statement() |
156 | { |
157 | if ($this->value=='') { |
158 | return false; |
159 | } |
160 | $res = implode(' OR ', array_filter(array_map(array($this, 'get_single_where_statement'), $this->fieldDbName))); |
161 | return empty($res) ? '' : "($res)"; |
162 | } |
163 | |
164 | // }}} |
165 | // {{{ function get_order_statement() |
94f6c381 |
166 | |
a7de4ef7 |
167 | /** récupérer la clause correspondant au champ dans la clause ORDER BY de la requête |
168 | * utilisé par exemple pour placer d'abord le nom égal à la requête avant les approximations */ |
0337d704 |
169 | function get_order_statement() |
170 | { |
171 | return false; |
172 | } |
173 | |
174 | // }}} |
175 | // {{{ function get_select_statement() |
176 | |
177 | function get_select_statement() |
178 | { |
179 | return false; |
180 | } |
181 | |
182 | // }}} |
183 | // {{{ function get_url() |
184 | |
a7de4ef7 |
185 | /** récupérer le bout d'URL correspondant aux paramètres permettant d'imiter une requête d'un |
186 | * utilisateur assignant la valeur $this->value à ce champ */ |
0337d704 |
187 | function get_url() |
188 | { |
189 | if (empty($this->value)) { |
190 | return false; |
191 | } else { |
192 | return $this->fieldFormName.'='.urlencode($this->value); |
193 | } |
194 | } |
195 | |
196 | // }}} |
197 | } |
198 | |
199 | // }}} |
200 | // {{{ class QuickSearch [Google Like] |
201 | |
202 | class QuickSearch extends SField |
203 | { |
204 | // {{{ properties |
94f6c381 |
205 | |
0337d704 |
206 | /** stores tokens */ |
207 | var $strings; |
208 | /** stores numerical ranges */ |
209 | var $ranges; |
bbf610b8 |
210 | /** stores admin searches */ |
211 | var $email; |
212 | var $ip; |
0337d704 |
213 | |
214 | // }}} |
215 | // {{{ constructor |
94f6c381 |
216 | |
0337d704 |
217 | function QuickSearch($_fieldFormName) |
218 | { |
219 | $this->fieldFormName = $_fieldFormName; |
220 | $this->get_request(); |
a14159bf |
221 | if (preg_match(":[\]\[{}~/§_`|%$^=+]|\*\*:u", $this->value)) { |
a7de4ef7 |
222 | new ThrowError('Un champ contient un caractère interdit rendant la recherche impossible.'); |
0337d704 |
223 | } |
224 | } |
225 | |
226 | // }}} |
227 | // {{{ function isempty() |
228 | |
229 | function isempty() |
230 | { |
bbf610b8 |
231 | return empty($this->strings) && empty($this->ranges) && empty($this->email) && empty($this->ip); |
0337d704 |
232 | } |
233 | |
234 | // }}} |
235 | // {{{ function get_request() |
94f6c381 |
236 | |
0337d704 |
237 | function get_request() |
238 | { |
94f6c381 |
239 | parent::get_request(); |
240 | $s = replace_accent(trim($this->value)); |
bbf610b8 |
241 | $r = $s = str_replace('*','%',$s); |
242 | |
243 | if (S::has_perms() && strpos($s, '@') !== false) { |
244 | $this->email = $s; |
245 | } else if (S::has_perms() && preg_match('/[0-9]+\.([0-9]+|%)\.([0-9]+|%)\.([0-9]+|%)/', $s)) { |
246 | $this->ip = $s; |
247 | } |
248 | if ($this->email || $this->ip) { |
249 | $this->strings = $this->ranges = array(); |
250 | return; |
251 | } |
252 | |
94f6c381 |
253 | $s = preg_replace('!\d+!', ' ', $s); |
94f6c381 |
254 | $this->strings = preg_split("![^a-zA-Z%]+!",$s, -1, PREG_SPLIT_NO_EMPTY); |
255 | |
bbf610b8 |
256 | $s = preg_replace('! *- *!', '-', $r); |
94f6c381 |
257 | $s = preg_replace('!([<>]) *!', ' \1', $s); |
258 | $s = preg_replace('![^0-9\-><]!', ' ', $s); |
259 | $s = preg_replace('![<>\-] !', '', $s); |
260 | $ranges = preg_split('! +!', $s, -1, PREG_SPLIT_NO_EMPTY); |
261 | $this->ranges=Array(); |
262 | foreach ($ranges as $r) { |
263 | if (preg_match('!^([<>]\d{4}|\d{4}(-\d{4})?)$!', $r)) $this->ranges[] = $r; |
264 | } |
0337d704 |
265 | } |
266 | |
267 | // }}} |
268 | // {{{ function get_where_statement() |
94f6c381 |
269 | |
0337d704 |
270 | function get_where_statement() |
271 | { |
94f6c381 |
272 | $where = Array(); |
273 | foreach ($this->strings as $i => $s) { |
c16b5562 |
274 | if (Env::i('with_soundex') && strlen($s) > 1) { |
94f6c381 |
275 | $t = soundex_fr($s); |
276 | $where[] = "sn$i.soundex = '$t'"; |
277 | } else { |
278 | $t = str_replace('*', '%', $s).'%'; |
279 | $t = str_replace('%%', '%', $t); |
280 | $where[] = "sn$i.token LIKE '$t'"; |
281 | } |
282 | } |
283 | |
284 | $wherep = Array(); |
285 | foreach ($this->ranges as $r) { |
286 | if (preg_match('!^\d{4}$!', $r)) { |
287 | $wherep[] = "u.promo=$r"; |
288 | } elseif (preg_match('!^(\d{4})-(\d{4})$!', $r, $matches)) { |
289 | $p1=min(intval($matches[1]), intval($matches[2])); |
290 | $p2=max(intval($matches[1]), intval($matches[2])); |
291 | $wherep[] = "(u.promo>=$p1 AND u.promo<=$p2)"; |
292 | } elseif (preg_match('!^<(\d{4})!', $r, $matches)) { |
293 | $wherep[] = "u.promo<={$matches[1]}"; |
294 | } elseif (preg_match('!^>(\d{4})!', $r, $matches)) { |
295 | $wherep[] = "u.promo>={$matches[1]}"; |
296 | } |
297 | } |
298 | if (!empty($wherep)) { |
0337d704 |
299 | $where[] = '('.join(' OR ',$wherep).')'; |
300 | } |
bbf610b8 |
301 | if (!empty($this->email)) { |
302 | $where[] = 'ems.email = ' . XDB::escape($this->email); |
303 | } |
304 | if (!empty($this->ip)) { |
305 | $ip = XDB::escape($this->ip); |
306 | $where[] = "( ls.ip = $ip OR ls.forward_ip = $ip )"; |
307 | } |
3b2f9d11 |
308 | |
94f6c381 |
309 | return join(" AND ", $where); |
0337d704 |
310 | } |
311 | |
312 | // }}} |
313 | // {{{ get_select_statement |
314 | function get_select_statement() |
315 | { |
316 | $join = ""; |
c0c9f772 |
317 | $and = ''; |
c16b5562 |
318 | $uniq = ''; |
94f6c381 |
319 | foreach ($this->strings as $i => $s) { |
c0c9f772 |
320 | if (!S::logged()) { |
321 | $and = "AND FIND_IN_SET('public', sn$i.flags)"; |
c16b5562 |
322 | } |
323 | $myu = str_replace('snv', "sn$i", $uniq); |
324 | $join .= "INNER JOIN search_name AS sn$i ON (u.user_id = sn$i.uid $and$myu)\n"; |
325 | $uniq .= " AND sn$i.token != snv.token"; |
0337d704 |
326 | } |
bbf610b8 |
327 | if (!empty($this->email)) { |
328 | $join .= "LEFT JOIN emails AS ems ON (ems.uid = u.user_id)"; |
329 | } |
330 | if (!empty($this->ip)) { |
331 | $join .= "INNER JOIN logger.sessions AS ls ON (ls.uid = u.user_id)\n"; |
332 | } |
0337d704 |
333 | return $join; |
334 | } |
335 | // }}} |
336 | // {{{ function get_order_statement() |
94f6c381 |
337 | |
0337d704 |
338 | function get_order_statement() |
339 | { |
340 | return false; |
341 | } |
342 | |
343 | // }}} |
344 | // {{{ function get_score_statement |
94f6c381 |
345 | |
0337d704 |
346 | function get_score_statement() |
347 | { |
348 | $sum = array('0'); |
94f6c381 |
349 | foreach ($this->strings as $i => $s) { |
0337d704 |
350 | $sum[] .= "SUM(sn$i.score + IF('$s'=sn$i.token,5,0))"; |
351 | } |
352 | return join('+', $sum).' AS score'; |
353 | } |
354 | |
355 | // }}} |
356 | } |
357 | |
358 | // }}} |
359 | // {{{ class NumericSField [Integer fields] |
360 | |
a7de4ef7 |
361 | /** classe de champ numérique entier (offset par exemple) |
0337d704 |
362 | */ |
363 | class NumericSField extends SField |
364 | { |
365 | // {{{ constructor |
94f6c381 |
366 | |
0337d704 |
367 | /** constructeur |
a7de4ef7 |
368 | * (récupère la requête de l'utilisateur pour ce champ) */ |
0337d704 |
369 | function NumericSField($_fieldFormName) |
370 | { |
371 | $this->fieldFormName = $_fieldFormName; |
372 | $this->get_request(); |
373 | } |
374 | |
375 | // }}} |
376 | // {{{ function get_request() |
94f6c381 |
377 | |
a7de4ef7 |
378 | /** récupère la requête de l'utilisateur et échoue s'il ne s'agit pas d'un entier */ |
0337d704 |
379 | function get_request() |
380 | { |
381 | parent::get_request(); |
382 | if (empty($this->value)) { |
383 | $this->value = 0; |
384 | } |
385 | if (!preg_match("/^[0-9]+$/", $this->value)) { |
a7de4ef7 |
386 | new ThrowError('Un champ numérique contient des caractères alphanumériques.'); |
0337d704 |
387 | } |
388 | } |
94f6c381 |
389 | |
0337d704 |
390 | // }}} |
391 | } |
392 | |
393 | // }}} |
394 | // {{{ class RefSField [ ??? ] |
395 | |
396 | class RefSField extends SField |
397 | { |
398 | // {{{ properties |
94f6c381 |
399 | |
0337d704 |
400 | var $refTable; |
401 | var $refAlias; |
402 | var $refCondition; |
403 | var $exact = true; |
404 | |
405 | // }}} |
406 | // {{{ constructor |
407 | |
408 | function RefSField($_fieldFormName, $_fieldDbName='', $_refTable, $_refAlias, $_refCondition, $_exact=true) |
409 | { |
410 | $this->fieldFormName = $_fieldFormName; |
411 | $this->fieldDbName = $_fieldDbName; |
412 | $this->refTable = $_refTable; |
413 | $this->refAlias = $_refAlias; |
414 | $this->refCondition = $_refCondition; |
415 | $this->exact = $_exact; |
416 | $this->get_request(); |
417 | } |
418 | |
419 | // }}} |
420 | // {{{ function get_request() |
94f6c381 |
421 | |
0337d704 |
422 | function get_request() { |
423 | parent::get_request(); |
424 | if ($this->value=='00' || $this->value=='0') { |
425 | $this->value=''; |
426 | } |
427 | } |
428 | |
429 | // }}} |
430 | // {{{ function too_large() |
431 | |
432 | function too_large() |
433 | { |
434 | return ($this->value==''); |
435 | } |
436 | |
437 | // }}} |
438 | // {{{ function compare() |
439 | |
440 | function compare() |
441 | { |
442 | $val = addslashes($this->value); |
443 | return $this->exact ? "='$val'" : " LIKE '%$val%'"; |
444 | } |
445 | |
446 | // }}} |
447 | // {{{ function get_single_match_statement() |
448 | |
449 | function get_single_match_statement($field) |
450 | { |
451 | return $field.$this->compare(); |
452 | } |
453 | |
454 | // }}} |
455 | // {{{ function get_single_where_statement() |
456 | |
457 | function get_single_where_statement($field) |
458 | { |
459 | return $this->refTable=='' ? $this->get_single_match_statement($field) : false; |
460 | } |
461 | |
462 | // }}} |
463 | // {{{ function get_select_statement() |
464 | |
465 | function get_select_statement() |
466 | { |
467 | if ($this->value=='' || $this->refTable=='') { |
468 | return false; |
469 | } |
470 | $res = implode(' OR ', array_filter(array_map(array($this, 'get_single_match_statement'), $this->fieldDbName))); |
471 | return "INNER JOIN {$this->refTable} AS {$this->refAlias} ON ({$this->refCondition} AND ($res) )"; |
472 | } |
473 | |
474 | // }}} |
475 | } |
476 | |
477 | // }}} |
56670b6a |
478 | |
479 | // {{{ class RefSFieldMultipleTable |
480 | class MapSField extends RefSField |
481 | { |
94f6c381 |
482 | var $mapId; |
483 | |
56670b6a |
484 | function MapSField($_fieldFormName, $_fieldDbName='', $_refTable, $_refAlias, $_refCondition, $_mapId=false) |
485 | { |
350e6926 |
486 | if ($_mapId === false) |
5e2307dc |
487 | $this->mapId = Env::v($_fieldFormName, ''); |
350e6926 |
488 | else |
489 | $this->mapId = $_mapId; |
a2aa8436 |
490 | $this->value = $this->mapId; |
350e6926 |
491 | $this->RefSField($_fieldFormName, $_fieldDbName, $_refTable, $_refAlias, $_refCondition, true, false); |
56670b6a |
492 | } |
787bb3d7 |
493 | |
56670b6a |
494 | function get_select_statement() |
495 | { |
350e6926 |
496 | if ($this->mapId === '') return false; |
56670b6a |
497 | $res = implode(' OR ', array_filter(array_map(array($this, 'get_single_match_statement'), $this->fieldDbName))); |
498 | foreach ($this->refTable as $i => $refT) |
499 | $last = $i; |
500 | $inner = ""; |
501 | foreach ($this->refTable as $i => $refT) |
502 | $inner .= " INNER JOIN {$refT} AS {$this->refAlias[$i]} ON ({$this->refCondition[$i]} ".(($i == $last)?"AND ($res) ":"").")"; |
503 | return $inner; |
504 | } |
505 | function get_request() |
506 | { |
350e6926 |
507 | $this->value = $this->mapId; |
56670b6a |
508 | } |
509 | } |
510 | |
0337d704 |
511 | // {{{ class RefWithSoundexSField [ ??? ] |
512 | |
513 | class RefWithSoundexSField extends RefSField |
514 | { |
515 | // {{{ function compare() |
94f6c381 |
516 | |
0337d704 |
517 | function compare() |
518 | { |
94f6c381 |
519 | return "='".soundex_fr($this->value)."'"; |
0337d704 |
520 | } |
521 | |
522 | // }}} |
523 | } |
524 | |
525 | // }}} |
526 | // {{{ class StringSField [String fields] |
527 | |
528 | /** classe de champ texte (nom par exemple) |
529 | */ |
530 | class StringSField extends SField |
531 | { |
532 | // {{{ function get_request() |
94f6c381 |
533 | |
a7de4ef7 |
534 | /** récupère la requête de l'utilisateur et échoue si la chaîne contient des caractères |
0337d704 |
535 | * interdits */ |
536 | function get_request() |
537 | { |
538 | parent::get_request(); |
a14159bf |
539 | if (preg_match(":[\]\[<>{}~/§_`|%$^=+]|\*\*:u", $this->value)) { |
a7de4ef7 |
540 | new ThrowError('Un champ contient un caractère interdit rendant la recherche impossible.'); |
0337d704 |
541 | } |
542 | } |
543 | |
544 | // }}} |
545 | // {{{ function length() |
546 | |
a7de4ef7 |
547 | /** donne la longueur de la requête de l'utilisateur |
548 | * (au sens strict i.e. pas d'* ni d'espace ou de trait d'union -> les contraintes réellement |
549 | * imposées par l'utilisateur) */ |
0337d704 |
550 | function length() |
551 | { |
a14159bf |
552 | $cleaned = replace_accent(strtolower($this->value)); |
553 | $length = strlen(ereg_replace('[a-z0-9]', '', $cleaned)); |
554 | return strlen($this->value) - $length; |
0337d704 |
555 | } |
556 | |
557 | // }}} |
558 | // {{{ function too_large() |
559 | |
560 | function too_large() |
561 | { |
562 | return ($this->length()<2); |
563 | } |
564 | |
565 | // }}} |
566 | // {{{ function get_single_where_statement() |
567 | |
a7de4ef7 |
568 | /** clause WHERE correspondant à un champ de la bdd et à ce champ de formulaire |
569 | * @param field nom de champ de la bdd concerné par la clause */ |
0337d704 |
570 | function get_single_where_statement($field) |
571 | { |
572 | $regexp = strtr(addslashes($this->value), '-*', '_%'); |
573 | return "$field LIKE '$regexp%'"; |
574 | } |
575 | |
576 | // }}} |
577 | // {{{ function get_order_statement() |
578 | |
a7de4ef7 |
579 | /** clause ORDER BY correspondant à ce champ de formulaire */ |
0337d704 |
580 | function get_order_statement() |
581 | { |
582 | if ($this->value!='' && $this->fieldResultName!='') { |
583 | return "{$this->fieldResultName}!='".addslashes($this->value)."'"; |
584 | } else { |
585 | return false; |
586 | } |
587 | } |
588 | |
589 | // }}} |
590 | } |
591 | |
592 | // }}} |
593 | // {{{ class NameSField [Names : serach 'n%' + '% b'] |
594 | |
595 | /** classe pour les noms : on cherche en plus du like 'foo%' le like '% foo' (particules) |
596 | +*/ |
597 | class NameSField extends StringSField |
598 | { |
599 | // {{{ function get_single_where_statement() |
94f6c381 |
600 | |
0337d704 |
601 | function get_single_where_statement($field) |
602 | { |
603 | $regexp = strtr(addslashes($this->value), '-*', '_%'); |
604 | return "$field LIKE '$regexp%' OR $field LIKE '% $regexp%' OR $field LIKE '%-$regexp%'"; |
605 | } |
606 | |
607 | // }}} |
608 | // {{{ function get_order_statement() |
94f6c381 |
609 | |
0337d704 |
610 | function get_order_statement() |
611 | { |
612 | if ($this->value!='' && $this->fieldResultName!='') { |
613 | return "{$this->fieldResultName} NOT LIKE '".addslashes($this->value)."'"; |
614 | } else { |
615 | return false; |
616 | } |
617 | } |
618 | |
619 | // }}} |
620 | } |
621 | |
622 | // }}} |
623 | // {{{ class StringWithSoundexSField [Strings + soundex] |
624 | |
625 | /** classe de champ texte avec soundex (nom par exemple) |
626 | */ |
627 | class StringWithSoundexSField extends StringSField |
628 | { |
629 | // {{{ function get_single_where_statement() |
630 | |
a7de4ef7 |
631 | /** clause WHERE correspondant à un champ de la bdd et à ce champ de formulaire |
632 | * @param field nom de champ de la bdd concerné par la clause */ |
0337d704 |
633 | function get_single_where_statement($field) { |
634 | return $field.'="'.soundex_fr($this->value).'"'; |
635 | } |
636 | |
637 | // }}} |
638 | } |
639 | |
640 | // }}} |
641 | // {{{ class PromoSField [Prom field] |
642 | |
643 | /** classe de champ de promotion */ |
644 | class PromoSField extends SField |
645 | { |
646 | // {{{ properties |
94f6c381 |
647 | |
a7de4ef7 |
648 | /** opérateur de comparaison (<,>,=) de la promo utilisé pour ce champ de formulaire */ |
0337d704 |
649 | var $compareField; |
650 | |
651 | // }}} |
652 | // {{{ constructor |
653 | |
787bb3d7 |
654 | /** constructeur |
a7de4ef7 |
655 | * compareField est un champ de formulaire très simple qui ne sert qu'à la construction de la |
0337d704 |
656 | * clause WHERE de la promo */ |
657 | function PromoSField($_fieldFormName, $_compareFieldFormName, $_fieldDbName, $_fieldResultName) |
658 | { |
659 | parent::SField($_fieldFormName, $_fieldDbName, $_fieldResultName); |
660 | $this->compareField = new SField($_compareFieldFormName); |
661 | } |
662 | |
663 | // }}} |
664 | // {{{ function get_request() |
665 | |
a7de4ef7 |
666 | /** récupère la requête utilisateur et échoue si le champ du formulaire ne représente pas une |
667 | * promotion (nombre à 4 chiffres) */ |
0337d704 |
668 | function get_request() |
669 | { |
670 | parent::get_request(); |
671 | if (preg_match('/^[0-9]{2}$/', $this->value)){ |
672 | $this->value = intval($this->value) + 1900; |
673 | } |
674 | if (!(empty($this->value) or preg_match('/^[0-9]{4}$/', $this->value))) { |
a7de4ef7 |
675 | new ThrowError('La promotion est une année à quatre chiffres.'); |
0337d704 |
676 | } |
677 | } |
678 | |
679 | // }}} |
680 | // {{{ function is_a_single_promo() |
681 | |
a7de4ef7 |
682 | /** teste si la requête est de la forme =promotion -> contrainte forte imposée -> elle suffit |
683 | * pour autoriser un affichage des résultats alors que <promotion est insuffisant */ |
0337d704 |
684 | function is_a_single_promo() |
685 | { |
686 | return ($this->compareField->value=='=' && $this->value!=''); |
687 | } |
688 | |
689 | // }}} |
690 | // {{{ function too_large() |
691 | |
692 | function too_large() |
693 | { |
694 | return !$this->is_a_single_promo(); |
695 | } |
696 | |
697 | // }}} |
698 | // {{{ function get_single_where_statement() |
699 | |
a7de4ef7 |
700 | /** clause WHERE correspondant à ce champ */ |
0337d704 |
701 | function get_single_where_statement($field) |
702 | { |
703 | return $field.$this->compareField->value.$this->value; |
704 | } |
705 | |
706 | // }}} |
707 | // {{{ function get_url() |
708 | |
a7de4ef7 |
709 | /** récupérer le bout d'URL correspondant aux paramètres permettant d'imiter une requête |
710 | * d'un utilisateur assignant la valeur $this->value à ce champ et assignant l'opérateur de |
711 | * comparaison adéquat */ |
0337d704 |
712 | function get_url() |
713 | { |
714 | if (!($u=parent::get_url())) { |
715 | return false; |
716 | } |
717 | return $u.'&'.$this->compareField->get_url(); |
718 | } |
719 | |
720 | // }}} |
721 | } |
722 | |
723 | // }}} |
724 | // {{{ class SFieldGroup [Group fields] |
725 | |
726 | /** classe groupant des champs de formulaire de recherche */ |
727 | class SFieldGroup |
728 | { |
729 | // {{{ properties |
94f6c381 |
730 | |
a7de4ef7 |
731 | /** tableau des classes correspondant aux champs groupés */ |
0337d704 |
732 | var $fields; |
733 | /** type de groupe : ET ou OU */ |
734 | var $and; |
735 | |
736 | // }}} |
737 | // {{{ constuctor |
738 | |
739 | /** constructeur */ |
740 | function SFieldGroup($_and, $_fields) |
741 | { |
742 | $this->fields = $_fields; |
743 | $this->and = $_and; |
744 | } |
745 | |
746 | // }}} |
747 | // {{{ function too_large() |
748 | |
749 | function too_large() |
750 | { |
751 | $b = true; |
a2aa8436 |
752 | for ($i=0 ; $b && $i<count($this->fields) ; $i++) { |
753 | $b = $b && $this->fields[$i]->too_large(); |
0337d704 |
754 | } |
755 | return $b; |
756 | } |
757 | |
758 | // }}} |
759 | // {{{ function field_get_select() |
760 | |
761 | function field_get_select($f) |
762 | { |
763 | return $f->get_select_statement(); |
764 | } |
765 | |
766 | // }}} |
767 | // {{{ function field_get_where() |
768 | |
a7de4ef7 |
769 | /** récupérer la clause WHERE d'un objet champ de recherche */ |
0337d704 |
770 | function field_get_where($f) |
771 | { |
772 | return $f->get_where_statement(); |
773 | } |
774 | |
775 | // }}} |
776 | // {{{ function field_get_order() |
777 | |
a7de4ef7 |
778 | /** récupérer la clause ORDER BY d'un objet champ de recherche */ |
0337d704 |
779 | function field_get_order($f) |
780 | { |
781 | return $f->get_order_statement(); |
782 | } |
783 | |
784 | // }}} |
785 | // {{{ function field_get_url() |
786 | |
a7de4ef7 |
787 | /** récupérer le bout d'URL correspondant à un objet champ de recherche */ |
0337d704 |
788 | function field_get_url($f) |
789 | { |
790 | return $f->get_url(); |
791 | } |
94f6c381 |
792 | |
0337d704 |
793 | // }}} |
794 | // {{{ function get_select_statement() |
795 | |
796 | function get_select_statement() |
797 | { |
798 | return implode(' ', array_filter(array_map(array($this, 'field_get_select'), $this->fields))); |
799 | } |
800 | |
801 | // }}} |
802 | // {{{ function get_where_statement() |
803 | |
a7de4ef7 |
804 | /** récupérer la clause WHERE du groupe de champs = conjonction (ET) ou disjonction (OU) de |
805 | * clauses des champs élémentaires */ |
0337d704 |
806 | function get_where_statement() |
807 | { |
808 | $joinText = $this->and ? ' AND ' : ' OR '; |
809 | $res = implode($joinText, array_filter(array_map(array($this, 'field_get_where'), $this->fields))); |
810 | return $res == '' ? '' : "($res)"; |
811 | } |
812 | |
813 | // }}} |
814 | // {{{ function get_order_statement() |
815 | |
a7de4ef7 |
816 | /** récupérer la clause ORDER BY du groupe de champs = conjonction (ET) ou disjonction (OU) de |
817 | * clauses des champs élémentaires */ |
0337d704 |
818 | function get_order_statement() |
819 | { |
820 | $order = array_filter(array_map(array($this, 'field_get_order'), $this->fields)); |
821 | return count($order)>0 ? implode(',', $order) : false; |
822 | } |
823 | |
824 | // }}} |
825 | // {{{ function get_url() |
826 | |
a7de4ef7 |
827 | /** récupérer le bout d'URL correspondant à ce groupe de champs = concaténation des bouts d'URL |
828 | * des champs élémentaires */ |
0337d704 |
829 | function get_url($others=Array()) |
830 | { |
831 | $url = array_filter(array_map(array($this, 'field_get_url'), $this->fields)); |
832 | foreach ($url as $key=>$val) { |
833 | if (empty($val)) { |
834 | unset($url[$key]); |
835 | } |
836 | } |
837 | foreach ($others as $key=>$val) { |
838 | if (!empty($val)) { |
839 | $url[] = "$key=$val"; |
840 | } |
841 | } |
842 | return count($url)>0 ? implode('&', $url) : false; |
843 | } |
844 | |
845 | // }}} |
846 | } |
847 | |
848 | // }}} |
849 | |
a7de4ef7 |
850 | // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: |
0337d704 |
851 | ?> |