Début d'implémentation de recherche.php (=>search.php)
authorx2000bedo <x2000bedo>
Mon, 2 Aug 2004 22:43:31 +0000 (22:43 +0000)
committerx2000bedo <x2000bedo>
Mon, 2 Aug 2004 22:43:31 +0000 (22:43 +0000)
Dans un premier temps, je développe une page de recherche simplifiée pour les champs
nom,prénom,promo sans soundex puis on proposera l'option avec soundex puis enfin une recherche
avancée qui ne concernera que les inscrits (avec les champs binets etc...)

J'ai choisi d'implémenter une classe pour chaque type de champ. Je pense que ça rend le machin
plus clair.

Il reste à améliorer l'affichage des résultats (limitations à 10 par page et navigation + liens vers
la fiche pour les inscrits) pour cette recherche simplifiée.

htdocs/search.php [new file with mode: 0644]
include/search.classes.inc.php [new file with mode: 0644]
templates/search.tpl [new file with mode: 0644]

diff --git a/htdocs/search.php b/htdocs/search.php
new file mode 100644 (file)
index 0000000..76e37c1
--- /dev/null
@@ -0,0 +1,33 @@
+<?php
+require("auto.prepend.inc.php");
+require("search.classes.inc.php");
+// choix entre partie publique (annuaire_public est vrai) et partie privée de l'annuaire.
+$public_directory = ((isset($_REQUEST['public_directory']) && $_REQUEST['public_directory']==1));
+if ($public_directory)
+    new_skinned_page('search.tpl', AUTH_PUBLIC);
+else
+    new_skinned_page('search.tpl', AUTH_COOKIE);
+if (array_key_exists('rechercher', $_POST)) {
+    $page->assign('formulaire',0);
+    $nameField = new StringSField('name',array('u.nom','u.epouse'));
+    $firstnameField = new StringSField('firstname',array('u.prenom'));
+    $promoField = new PromoSField('promo','egal','u.promo');
+    $fields = new SFieldGroup(true,array($nameField,$firstnameField,$promoField));
+    $nameField = new StringSField('name',array('i.nom'));
+    $firstnameField = new StringSField('firstname',array('i.prenom'));
+    $promoField = new PromoSField('promo','egal','i.promo');
+    $fields2 = new SFieldGroup(true,array($nameField,$firstnameField,$promoField));
+    $sql = '(SELECT u.nom,u.prenom,u.promo 
+            FROM auth_user_md5 AS u  
+            WHERE '.$fields->get_where_statement().')
+            UNION
+            (SELECT i.nom,i.prenom,i.promo
+            FROM identification AS i
+            WHERE '.$fields2->get_where_statement().')
+            ORDER BY promo DESC,nom,prenom';
+    $page->mysql_assign($sql, 'resultats', 'nb_resultats');
+}
+else
+    $page->assign('formulaire',1);
+$page->run();
+?>
diff --git a/include/search.classes.inc.php b/include/search.classes.inc.php
new file mode 100644 (file)
index 0000000..0a9f549
--- /dev/null
@@ -0,0 +1,100 @@
+<?php
+class SField {
+    var $fieldFormName;
+    var $fieldDbName;
+    var $value;
+
+    function SField($_fieldFormName,$_fieldDbName='') {
+        $this->fieldFormName = $_fieldFormName;
+        $this->fieldDbName = $_fieldDbName;
+        $this->get_request();
+    }
+
+    function get_request() {
+        $this->value =
+        (isset($_REQUEST[$this->fieldFormName]))?trim(stripslashes($_REQUEST[$this->fieldFormName])):'';
+    }
+
+    function error($explain) {
+        global $page;
+        $page->assign('error',$explain);
+        $page->run();
+    }
+
+    function get_where_statement() {
+        return ($this->value!='');
+    }
+}
+
+class StringSField extends SField {
+    function get_request() {
+        parent::get_request();
+        if (preg_match(":[][<>{}~/§_`|%$^=+]|\*\*:", $this->value))
+            $this->error('Un champ contient un caractère interdit rendant la recherche'
+            .' impossible.<br>');
+    }
+
+    function length() {
+        return
+        length($this->value)-length(ereg_replace('[a-z]'.$CARACTERES_ACCENTUES,'',strtolower($this->value)));
+    }
+
+    function get_like($field) {
+        //on rend les traits d'union et les espaces équivalents
+        $regexp = preg_replace('/[ -]/','[ \-]',$this->value);
+        //on remplace le pseudo language des * par une regexp
+        $regexp = str_replace('*','.+',$regexp);
+        return $field." RLIKE '^(.*[ -])?".replace_accent_regexp($regexp).".*'";
+    }
+
+    function get_where_statement() {
+        if (!parent::get_where_statement())
+            return false;
+        return '('.implode(' OR ',array_map(array($this,'get_like'),$this->fieldDbName)).')';
+    }
+}
+
+class PromoSField extends SField {
+    var $compareField;
+
+    function PromoSField($_fieldFormName,$_compareFieldFormName,$_fieldDbName) {
+        parent::SField($_fieldFormName,$_fieldDbName);
+        $this->compareField = new SField($_compareFieldFormName);
+    }
+
+    function get_request() {
+        parent::get_request();
+        if (!(empty($this->value) or preg_match("/^[0-9]{4}$/", $this->value)))
+            $this->error('La promotion est une année à quatre chiffres.<br>');
+    }
+
+    function is_a_single_promo() {
+        return ($this->compareField->value=='=' && $this->value!='');
+    }
+
+    function get_where_statement() {
+        if (!parent::get_where_statement())
+            return false;
+        return $this->fieldDbName.$this->compareField->value.$this->value;
+    }
+}
+
+class SFieldGroup {
+    var $fields;
+    var $and;
+
+    function SFieldGroup($_and,$_fields) {
+        $this->fields = $_fields;
+        $this->and = $_and;
+    }
+
+    function field_get_where($f) {
+        return $f->get_where_statement();
+    }
+
+    function get_where_statement() {
+        $joinText=($this->and)?' AND ':' OR ';
+        return '('.implode($joinText,array_filter(array_map(array($this,'field_get_where'),$this->fields))).')';
+    }
+}
+?>
diff --git a/templates/search.tpl b/templates/search.tpl
new file mode 100644 (file)
index 0000000..2dae2a0
--- /dev/null
@@ -0,0 +1,54 @@
+{dynamic}
+{if $formulaire==0}
+  <div class="rubrique">
+    Résultats
+  </div>
+  <p class="smaller">
+    {if $nb_resultats==0}Aucune{else}{$nb_resultats}{/if} réponse{if $nb_resultats>1}s{/if}.
+  </p>
+  <table class="bicol">
+    {section name=resultat loop=$resultats}
+    <tr class="{if $smarty.section.resultat.index is even}pair{else}impair{/if}">
+      <td>
+      <strong>{$resultats[resultat].nom} {$resultats[resultat].prenom}</strong>
+      </td>
+      <td>
+      (X {$resultats[resultat].promo})
+      </td>
+    </tr>
+    {/section}
+  </table>
+{else}
+  <div class="rubrique">
+    Recherche
+  </div>
+  <div class="center">
+    <form action="{$smarty.server.PHP_SELF}" method="post">
+    <table class="tinybicol" cellpadding="3" summary="Recherche">
+      <tr>
+        <td>Nom</td>
+        <td><input type="text" name="name" size="50" maxlength="50" /></td>
+      </tr>
+      <tr>
+        <td>Prénom</td>
+        <td><input type="text" name="firstname" size="50" maxlength="50" /></td>
+      </tr>
+      <tr>
+        <td>Promotion</td>
+        <td>
+        <select name="egal">
+        <option value="=" selected>&nbsp;=&nbsp;</option>
+        <option value=">" >&nbsp;&gt;&nbsp;</option>
+        <option value="<" >&nbsp;&lt;&nbsp;</option>
+        </select>
+        <input type="text" name="promo" size="4" maxlength="4" />
+        </td>
+      </tr>
+      <tr>
+        <td colspan="2" class="center"><input type="submit" name="rechercher" value="Ok" /></td>
+      </tr>
+    </table>
+    </form>
+  </div>
+{/if}
+{/dynamic}