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