changes on Fiche, normalize Search code
authorPierre Habouzit (MadCoder <pierre.habouzit@m4x.org>
Thu, 2 Dec 2004 13:46:30 +0000 (13:46 +0000)
committerFlorent Bruneau <florent.bruneau@polytechnique.org>
Thu, 26 Jun 2008 21:26:22 +0000 (23:26 +0200)
Fiche :
    - Hide the «formation» if the field is empty.

Search :
    - Normalize a lot of stuff.
    - Shorten urls when possible (all hardcoded settings like with_soundex disappeared !).
    - Factorise more bits of code.
    - Prepare search to be an quite independant module.

git-archimport-id: opensource@polytechnique.org--2005/platal--mainline--0.9--patch-16

17 files changed:
htdocs/advanced_search.php
htdocs/listes/archives.php
htdocs/search.php
include/conf.d/search.globals.inc.php
include/conf.d/search.menu.inc.php [new file with mode: 0644]
include/conf.d/tmp.menu.inc.php
include/search.classes.inc.php
install.d/search/files
templates/admin/index.tpl
templates/fiche.tpl
templates/listes/archives.head.tpl
templates/listes/archives.tpl
templates/search.adv.form.tpl
templates/search.adv.links.tpl
templates/search.quick.form.tpl
templates/search.quick.tpl
templates/search.tpl

index e900fa4..aad6805 100644 (file)
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: advanced_search.php,v 1.36 2004/11/27 16:44:33 x2000bedo Exp $
  ***************************************************************************/
 
 require_once("xorg.inc.php");
 require_once("search.classes.inc.php");
 new_skinned_page('search.tpl', AUTH_COOKIE);
+
 $page->assign('advanced',1);
 $page->assign('public_directory',0);
 require_once("applis.func.inc.php");
 require_once("geoloc.inc.php");
 
-function form_prepare() {
+// {{{ function form_prepare()
+
+function form_prepare()
+{
     global $page,$globals;
     $page->assign('formulaire',1);
-    $sql = 'SELECT a2 AS id,IF(nat=\'\',pays,nat) AS text FROM geoloc_pays ORDER BY text';
-    $page->mysql_assign($sql,'choix_nationalites');
-    $sql = 'SELECT id,text FROM binets_def ORDER BY text';
-    $page->mysql_assign($sql,'choix_binets');
-    $sql = 'SELECT id,text FROM groupesx_def ORDER BY text';
-    $page->mysql_assign($sql,'choix_groupesx');
-    $sql = 'SELECT id,text FROM sections ORDER BY text';
-    $page->mysql_assign($sql,'choix_sections');
-    $sql = 'SELECT id,text FROM applis_def ORDER BY text';
-    $page->mysql_assign($sql,'choix_schools');
-    if (empty($_REQUEST['school']))
+    $page->mysql_assign('SELECT a2 AS id,IF(nat=\'\',pays,nat) AS text FROM geoloc_pays ORDER BY text', 'choix_nationalites');
+    $page->mysql_assign('SELECT id,fonction_fr FROM fonctions_def ORDER BY fonction_fr', 'choix_postes');
+    $page->mysql_assign('SELECT id,text FROM binets_def ORDER BY text',       'choix_binets');
+    $page->mysql_assign('SELECT id,text FROM groupesx_def ORDER BY text',     'choix_groupesx');
+    $page->mysql_assign('SELECT id,text FROM sections ORDER BY text',         'choix_sections');
+    $page->mysql_assign('SELECT id,text FROM applis_def ORDER BY text',       'choix_schools');
+    $page->mysql_assign('SELECT id,label FROM emploi_secteur ORDER BY label', 'choix_secteurs');
+
+    if (empty($_REQUEST['school'])) {
         $sql = 'DESCRIBE applis_def type';
-    else
+    } else {
         $sql = 'SELECT type FROM applis_def WHERE id='.$_REQUEST['school'];
-    $result = $globals->db->query($sql);
-    $row = mysql_fetch_row($result);
+    }
+    $res = $globals->db->query($sql);
+    $row = mysql_fetch_row($res);
     if (empty($_REQUEST['school'])) {
         $types = explode('(',$row[1]);
         $types = str_replace("'","",substr($types[1],0,-1));
-    }
-    else
+    } else {
         $types = $row[0];
-    $page->assign('choix_diplomas',explode(',',$types));
-    $sql = 'SELECT id,label FROM emploi_secteur ORDER BY label';
-    $page->mysql_assign($sql,'choix_secteurs');
-    $sql = 'SELECT id,fonction_fr FROM fonctions_def ORDER BY fonction_fr';
-    $page->mysql_assign($sql,'choix_postes');
+    }
+    mysql_free_result($res);
+    $page->assign('choix_diplomas', explode(',',$types));
 }
 
+// }}}
 
 if (!array_key_exists('rechercher', $_REQUEST)) {
     form_prepare();
-} 
-else {
-    $page->assign('formulaire',0);
-
-    $with_soundex = !empty($_REQUEST['with_soundex']);
+} else {
 
-    if ($with_soundex) {
-        $nameField = new RefWithSoundexSField('name',array('rn.nom1_soundex','rn.nom2_soundex','rn.nom3_soundex'),'recherche_soundex','rn','u.matricule = rn.matricule');
+    if ($with_soundex = !empty($_REQUEST['with_soundex'])) {
+        $nameField      = new RefWithSoundexSField('name',array('rn.nom1_soundex','rn.nom2_soundex','rn.nom3_soundex'),'recherche_soundex','rn','u.matricule = rn.matricule');
         $firstnameField = new RefWithSoundexSField('firstname',array('rp.prenom1_soundex','rp.prenom2_soundex'),'recherche_soundex','rp','u.matricule = rp.matricule');
     } else {
-        $nameField = new NameSField('name',array('u.nom','u.epouse'),'');
+        $nameField      = new NameSField('name',array('u.nom','u.epouse'),'');
         $firstnameField = new StringSField('firstname',array('u.prenom'),'');
     }
-    $promo1Field = new PromoSField('promo1','egal1',array('u.promo'),'');
-    $promo2Field = new PromoSField('promo2','egal2',array('u.promo'),'');
-    $womanField = new RefSField('woman',array('FIND_IN_SET(u.flags,\'femme\')+1'),'','','');
+    
+    $promo1Field     = new PromoSField('promo1','egal1',array('u.promo'),'');
+    $promo2Field     = new PromoSField('promo2','egal2',array('u.promo'),'');
+    $womanField      = new RefSField('woman',array('FIND_IN_SET(u.flags,\'femme\')+1'),'','','');
     $subscriberField = new RefSField('subscriber',array('!(u.perms IN (\'admin\',\'user\'))+1'),'','','');
-    $aliveField = new RefSField('alive',array('(u.deces!=0)+1'),'','','');
+    $aliveField      = new RefSField('alive',array('(u.deces!=0)+1'),'','','');
    
-    $townField = new RefSField('ville',array('av.ville'),'adresses','av','u.user_id=av.uid',false);
-    $countryField = new RefSField('pays',array('ap.pays'),'adresses','ap','u.user_id=ap.uid');
-    $regionField = new RefSField('region',array('ar.region'),'adresses','ar','u.user_id=ar.uid');
+    $townField       = new RefSField('ville',array('av.ville'),'adresses','av','u.user_id=av.uid',false);
+    $countryField    = new RefSField('pays',array('ap.pays'),'adresses','ap','u.user_id=ap.uid');
+    $regionField     = new RefSField('region',array('ar.region'),'adresses','ar','u.user_id=ar.uid');
    
     $entrepriseField = new RefSField('entreprise',array('ee.entreprise'),'entreprises','ee','u.user_id=ee.uid',false);
-    $posteField = new RefSField('poste',array('ep.fonction'),'entreprises','ep','u.user_id=ep.uid');
-    $secteurField = new RefSField('secteur',array('fm.secteur'),'entreprises','fm','u.user_id=fm.uid');
-    $cvField = new RefSField('cv',array('u.cv'),'','','',false);
+    $posteField      = new RefSField('poste',array('ep.fonction'),'entreprises','ep','u.user_id=ep.uid');
+    $secteurField    = new RefSField('secteur',array('fm.secteur'),'entreprises','fm','u.user_id=fm.uid');
+    $cvField         = new RefSField('cv',array('u.cv'),'','','',false);
    
-    $nationaliteField = new RefSField('nationalite',array('u.nationalite'),'','','');
-    $binetField = new RefSField('binet',array('b.binet_id'),'binets_ins','b','u.user_id=b.user_id');
-    $groupexField = new RefSField('groupex',array('g.gid'),'groupesx_ins','g','u.user_id=g.guid');
-    $sectionField = new RefSField('section',array('u.section'),'','','');
-    $schoolField = new RefSField('school',array('as.aid'),'applis_ins','`as`','u.user_id=as.uid');
-    $diplomaField = new RefSField('diploma',array('ad.type'),'applis_ins','ad','u.user_id=ad.uid');
+    $natField        = new RefSField('nationalite',array('u.nationalite'),'','','');
+    $binetField      = new RefSField('binet',array('b.binet_id'),'binets_ins','b','u.user_id=b.user_id');
+    $groupexField    = new RefSField('groupex',array('g.gid'),'groupesx_ins','g','u.user_id=g.guid');
+    $sectionField    = new RefSField('section',array('u.section'),'','','');
+    $schoolField     = new RefSField('school',array('as.aid'),'applis_ins','`as`','u.user_id=as.uid');
+    $diplomaField    = new RefSField('diploma',array('ad.type'),'applis_ins','ad','u.user_id=ad.uid');
   
-    $freeField = new RefSField('free',array('u.libre'),'','','',false);
+    $freeField       = new RefSField('free',array('u.libre'),'','','',false);
+    $offset          = new NumericSField('offset');
   
-    $fields = new
-    SFieldGroup(true,array($nameField,$firstnameField,$promo1Field,$promo2Field,$womanField,$subscriberField,$aliveField,
-    $townField,$countryField,$regionField,
-    $entrepriseField,$posteField,$secteurField,$cvField,
-    $nationaliteField,$binetField,$groupexField,$sectionField,$schoolField,$diplomaField,
-    $freeField));
+    $fields          = new SFieldGroup(true, array( $nameField, $firstnameField, $promo1Field,
+                $promo2Field, $womanField, $subscriberField, $aliveField, $townField, $countryField,
+                $regionField, $entrepriseField, $posteField, $secteurField, $cvField, $natField,
+                $binetField, $groupexField, $sectionField, $schoolField, $diplomaField, $freeField)
+            );
+
     
-    if ($fields->too_large())
-    {
+    if ($fields->too_large()) {
         form_prepare();
         new ThrowError('Recherche trop générale.');
     }
-    $offset = new NumericSField('offset');
    
     $where = $fields->get_where_statement();
-    $sql = 'SELECT SQL_CALC_FOUND_ROWS
-                       DISTINCT u.matricule,u.matricule_ax,u.user_id,
-                       u.nom,
-                       u.prenom,
-                       u.promo,
-                       a.alias AS forlife,
+    $sql = 'SELECT SQL_CALC_FOUND_ROWS DISTINCT
+                       u.nom, u.prenom,
                        '.$globals->search->result_fields.'
                        c.uid AS contact,
                        w.ni_id AS contact
-                 FROM  auth_user_md5  AS u'
-          .$fields->get_select_statement()
-       .((!empty($_REQUEST['only_referent']))?' INNER JOIN mentor AS m ON (m.uid = u.user_id)':'')
-       .'   LEFT JOIN  aliases        AS a ON (u.user_id = a.id AND a.type="a_vie")
+                 FROM  auth_user_md5  AS u 
+            '.$fields->get_select_statement().'
+            '.(empty($_REQUEST['only_referent']) ? '' : ' INNER JOIN mentor AS m ON (m.uid = u.user_id)').'
+            LEFT JOIN  aliases        AS a ON (u.user_id = a.id AND a.type="a_vie")
             LEFT JOIN  contacts       AS c ON (c.uid='.((array_key_exists('uid',$_SESSION))?$_SESSION['uid']:0).' AND c.contact=u.user_id)
             LEFT JOIN  watch_nonins   AS w ON (w.ni_id=u.user_id AND w.uid='.((array_key_exists('uid',$_SESSION))?$_SESSION['uid']:0).')
             '.$globals->search->result_where_statement.'
-                '.(($where!='')?('WHERE '.$where):'').'
+                '.(empty($where) ? '' : "WHERE  $where").'
              ORDER BY  '.(logged() && !empty($_REQUEST['mod_date_sort']) ? 'date DESC,' :'')
-                       .implode(',',array_filter(array($fields->get_order_statement(),'promo DESC,NomSortKey,prenom'))).'
+                       .implode(',',array_filter(array($fields->get_order_statement(), 'promo DESC, NomSortKey, prenom'))).'
                 LIMIT  '.$offset->value.','.$globals->search->per_page;
 
     $page->mysql_assign($sql, 'resultats', 'nb_resultats','nb_resultats_total');
-    $nbpages = ($page->get_template_vars('nb_resultats_total')-1)/$globals->search->per_page;
-    $page->assign('offsets',range(0,$nbpages));
-    $page->assign('offset',$offset->value);
-    $page->assign('url_args',$fields->get_url());
-    $page->assign('with_soundex',$with_soundex);
-    $page->assign('mod_date_sort',!empty($_REQUEST['mod_date_sort']));
-    $page->assign('perpage',$globals->search->per_page);
-    $page->assign('is_admin',has_perms());
+    $nb_tot  = $page->get_template_vars('nb_resultats_total');
+    $nbpages = ($nb_tot - 1)/$globals->search->per_page;
+
+    $url_ext = Array(
+        'mod_date_sort' => !empty($_REQUEST['mod_date_sort']),
+        'rechercher'    => true,
+        'with_soundex'  => $with_soundex
+    );
+
+    $page->assign('offset',   $offset->value);
+    $page->assign('offsets',  range(0, $nbpages));
+    $page->assign('url_args', $fields->get_url($url_ext));
+    $page->assign('perpage',  $globals->search->per_page);
     
-    if(!$page->get_template_vars('nb_resultats_total')) {
+    if (empty($nb_tot)) {
         form_prepare();
         new ThrowError('il n\'existe personne correspondant à ces critères dans la base !');
-    }
-    if($page->get_template_vars('nb_resultats_total')>800) {
+    } elseif ($nb_tot > $globals->search->private_max) {
         form_prepare();
         new ThrowError('Recherche trop générale');
     }
index 2f34a61..e8e08ee 100644 (file)
@@ -17,8 +17,6 @@
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: archives.php,v 1.4 2004/11/30 18:39:19 x2000habouzit Exp $
  ***************************************************************************/
 
 if(empty($_REQUEST['liste'])) header('Location: index.php');
index 8993fe3..871e2a4 100644 (file)
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: search.php,v 1.52 2004/11/22 20:04:36 x2000habouzit Exp $
  ***************************************************************************/
 
 require_once("xorg.inc.php");
 require_once("search.classes.inc.php");
 
 new_skinned_page('search.tpl', AUTH_PUBLIC);
-if(logged()) {
+if (logged()) {
     new_skinned_page('search.tpl', AUTH_COOKIE);
 }
 
-$page->assign('advanced',0);
 require_once("applis.func.inc.php");
 require_once("geoloc.inc.php");
 
-if (array_key_exists('quick', $_REQUEST)) {
-    $page->assign('formulaire',0);
+if (isset($_REQUEST['quick'])) {
+    $page->assign('formulaire', 0);
 
     $qSearch = new QuickSearch('quick');
-    $fields = new SFieldGroup(true,array($qSearch));
+    $fields  = new SFieldGroup(true, array($qSearch));
+    $offset  = new NumericSField('offset');
     
-    if ($qSearch->isempty())
-    {
+    if ($qSearch->isempty()) {
        new ThrowError('Recherche trop générale.');
     }
-    
-    $offset = new NumericSField('offset');
    
-    $sql = 'SELECT SQL_CALC_FOUND_ROWS 
-                       DISTINCT '.$qSearch->get_mark_statement().',r.matricule,u.matricule_ax,u.user_id,
+    $sql = 'SELECT SQL_CALC_FOUND_ROWS  DISTINCT 
                        UPPER(IF(u.nom!="",u.nom,u.nom_ini)) AS nom,
                        IF(u.prenom!="",u.prenom,u.prenom_ini) AS prenom,
-                       u.promo AS promo,
-                       a.alias AS forlife,
                        '.$globals->search->result_fields.'
                        c.uid AS contact,
-                      w.ni_id AS watch
-                 FROM  auth_user_md5  AS r
-            LEFT JOIN  auth_user_md5  AS u   ON (u.matricule=r.matricule)
+                      w.ni_id AS watch,
+                       '.$qSearch->get_mark_statement().'
+                 FROM  auth_user_md5  AS u
             LEFT JOIN  aliases        AS a   ON (u.user_id = a.id AND a.type="a_vie")
             LEFT JOIN  contacts       AS c   ON (c.uid='.((array_key_exists('uid',$_SESSION))?$_SESSION['uid']:0).' AND c.contact=u.user_id)
             LEFT JOIN  watch_nonins   AS w   ON (w.ni_id=u.user_id AND w.uid='.((array_key_exists('uid',$_SESSION))?$_SESSION['uid']:0).')
@@ -64,36 +56,32 @@ if (array_key_exists('quick', $_REQUEST)) {
                 WHERE  '.$fields->get_where_statement().'
                HAVING  mark>0
              ORDER BY  '.(logged() && !empty($_REQUEST['mod_date_sort']) ? 'date DESC,' :'')
-                       .implode(',',array_filter(array($fields->get_order_statement(),'u.promo DESC,NomSortKey,prenom'))).'
+                       .implode(',',array_filter(array($fields->get_order_statement(), 'u.promo DESC, NomSortKey, prenom'))).'
                 LIMIT  '.$offset->value.','.$globals->search->per_page;
 
     $page->mysql_assign($sql, 'resultats', 'nb_resultats','nb_resultats_total');
-    echo mysql_error();
-    
-    $nbpages = ($page->get_template_vars('nb_resultats_total')-1)/$globals->search->per_page;
-    $page->assign('offsets',range(0,$nbpages));
-    $page->assign('url_args',$fields->get_url());
-    $page->assign('mod_date_sort',!empty($_REQUEST['mod_date_sort']));
-    $page->assign('offset',$offset->value);
-    $page->assign('perpage',$globals->search->per_page);
-    $page->assign('is_admin',has_perms());
+    $nb_total = $page->get_template_vars('nb_resultats_total');
+    $nbpages  = ($nb_total-1)/$globals->search->per_page;
+
+    $url_ext = Array(
+        'mod_date_sort' => !empty($_REQUEST['mod_date_sort'])
+    );
+    $page->assign('offset',   $offset->value);
+    $page->assign('offsets',  range(0, $nbpages));
+    $page->assign('url_args', $fields->get_url($url_ext));
+    $page->assign('perpage',  $globals->search->per_page);
     
-    if (!logged() &&
-       $page->get_template_vars('nb_resultats_total')>$globals->search->public_max)
-    {
+    if (!logged() && $nb_total > $globals->search->public_max) {
        new ThrowError('Votre recherche a généré trop de résultats pour un affichage public.');
-    }
-    
-    if($page->get_template_vars('nb_resultats_total')>800) {
+    } elseif ($nb_total > $globals->search->private_max) {
         new ThrowError('Recherche trop générale');
-    }
-
-    if(!$page->get_template_vars('nb_resultats_total')) {
+    } elseif (empty($nb_total)) {
         new ThrowError('il n\'existe personne correspondant à ces critères dans la base !');
     }
-}
-else
+
+} else {
     $page->assign('formulaire',1);
+}
 
 $page->register_modifier('display_lines', 'display_lines');
 $page->run();
index 00ab2c4..338b5ac 100644 (file)
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-    $Id: banana.globals.inc.php,v 1.2 2004/12/01 14:25:44 x2000habouzit Exp $
  ***************************************************************************/
 
 // {{{ class SearchConfig
 
 class SearchConfig
 {
-    var $public_max = 25;
-    var $per_page   = 20;
+    var $public_max  =  25;
+    var $private_max = 800;
+
+    var $per_page    =  20;
 }
 
 // }}}
diff --git a/include/conf.d/search.menu.inc.php b/include/conf.d/search.menu.inc.php
new file mode 100644 (file)
index 0000000..0afe4fd
--- /dev/null
@@ -0,0 +1,6 @@
+<?php
+
+$this->addPrivateEntry(XOM_GROUPS, 00, 'Annuaire',         'search.php');
+$this->addPublicEntry(XOM_EXT,     00, 'Annuaire de l\'X', 'search.php');
+
+?>
index edc834d..adb1840 100644 (file)
@@ -13,7 +13,6 @@ $this->addPrivateEntry(XOM_SERVICES, 20, 'Listes de diffusion',   'listes/');
 $this->addPrivateEntry(XOM_SERVICES, 30, 'Envoyer un mail',       'sendmail.php');
 $this->addPrivateEntry(XOM_SERVICES, 40, 'Patte cassée',          'pattecassee.php');
        
-$this->addPrivateEntry(XOM_GROUPS,   00, 'Annuaire',              'search.php');
 $this->addPrivateEntry(XOM_GROUPS,   10, 'Trombi promo',          'trombipromo.php');
 $this->addPrivateEntry(XOM_GROUPS,   20, 'Conseil Pro.',          'referent.php');
 $this->addPrivateEntry(XOM_GROUPS,   30, 'Groupes X',             'http://www.polytechnique.net/plan.php');
@@ -32,7 +31,6 @@ $this->addPublicEntry(XOM_US,    00, 'Me connecter !',         'login.php');
 $this->addPublicEntry(XOM_US,    10, 'M\'inscrire',            'inscription/');
 $this->addPublicEntry(XOM_US,    20, 'Pourquoi m\'inscrire ?', 'docs/services.php');
 
-$this->addPublicEntry(XOM_EXT,   00, 'Annuaire de l\'X',       'search.php');
 $this->addPublicEntry(XOM_EXT,   10, 'Associations X',         'http://www.polytechnique.net/');
 $this->addPublicEntry(XOM_EXT,   20, 'Recrutement',            'http://www.manageurs.com/');
 
index e22c9cc..2e2889d 100644 (file)
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: search.classes.inc.php,v 1.37 2004/11/22 17:28:14 x2000habouzit Exp $
  ***************************************************************************/
 
 require_once("xorg.misc.inc.php");
 
-/*
- * Variables globales pour l'affichage des résultats de la recherche
- */
+// {{{ Global variables used for the search Queries
+
 $globals->search->result_fields = '
+                u.user_id, u.promo, u.matricule, u.matricule_ax,
                if(u.epouse=\'\', u.nom, u.epouse) AS NomSortKey,
                 u.epouse,u.date,u.web,u.mobile,
                 u.deces!=0 AS dcd,u.deces,
                u.perms IN (\'admin\',\'user\') AS inscrit,
                u.perms != \'pending\' AS wasinscrit,
                FIND_IN_SET(\'femme\', u.flags) AS sexe,
+                a.alias AS forlife,
                 ad0.text AS app0text, ad0.url AS app0url, ai0.type AS app0type,
                 ad1.text AS app1text, ad1.url AS app1url, ai1.type AS app1type,
                 e.entreprise, es.label AS secteur, ef.fonction_fr AS fonction,
@@ -51,34 +50,56 @@ $globals->search->result_where_statement = '
                 LEFT JOIN  geoloc_pays    AS gp  ON (adr.pays = gp.a2)
                 LEFT JOIN  geoloc_region  AS gr  ON (adr.pays = gr.a2 AND adr.region = gr.region)';
 
-function display_lines($text) {
+// }}}
+// {{{ function display_lines()
+
+/**
+ * This function is a heuristic that approximatively tells
+ * how many lines of output the contact list will use.
+ */
+function display_lines($text)
+{
     $n = 0;
-    $i=-1;
-    while(($i=strpos($text,'<tr>',$i+1))!==false) $n++;
-    $i=-1;
-    while(($i=strpos($text,'<div class="nom">',$i+1))!==false) $n++;
+    $tokens = Array('<tr>', '<div class="nom">');
+    foreach ($tokens as $t) {
+        $i = -1;
+        while ( ($i = strpos($text,$t,$i+1))!==false) { $n++; }
+    }
     return $n;
 }
 
-/** classe qui gère les erreurs dans les requêtes des utilisateurs finaux
- * passe le message d'erreur au template de page et exécute le template
+// }}}
+// {{{ class ThrowError
+
+/** handle errors for end-users queries
+ * assign the error message and runs the templates
+ *
+ * @author Jean-Sebastien Bedo
  */
-class ThrowError {
-    /** constucteur
-     * @param explain message explicatif de l'erreur de l'utilisateur
+class ThrowError
+{
+    /** constuctor
+     * @param  $explain string  the error (in natural language)
      */
-    function ThrowError($explain) {
+    function ThrowError($explain)
+    {
         global $page;
         $page->assign('error','Erreur : '.$explain);
         $page->run();
     }
 }
 
+// }}}
+// {{{ class SField                                     [Base class]
+
 /** classe de base représentant un champ de recherche
  * (correspond à un champ du formulaire mais peut être à plusieurs champs de la bdd)
  * interface étendue pour chaque type de champ particulier
  */
-class SField {
+class SField
+{
+    // {{{ properties
+    
     /** le nom du champ dans le formulaire HTML */
     var $fieldFormName;
     /** champs de la bdd correspondant à ce champ sous forme d'un tableau */
@@ -89,70 +110,118 @@ class SField {
     /** valeur du champ instanciée par l'utilisateur */
     var $value;
 
+    // }}}
+    // {{{ constructor
+
     /** constructeur
      * (récupère la requête de l'utilisateur pour ce champ) */
-    function SField($_fieldFormName,$_fieldDbName='',$_fieldResultName='') {
-        $this->fieldFormName = $_fieldFormName;
-        $this->fieldDbName = $_fieldDbName;
+    function SField($_fieldFormName, $_fieldDbName='', $_fieldResultName='')
+    {
+        $this->fieldFormName   = $_fieldFormName;
+        $this->fieldDbName     = $_fieldDbName;
         $this->fieldResultName = $_fieldResultName;
         $this->get_request();
     }
 
+    // }}}
+    // {{{ function get_request()
+
     /** récupérer la requête de l'utilisateur 
      * on met une chaîne vide si le champ n'a pas été complété */
-    function get_request() {
-        $this->value =
-        (isset($_REQUEST[$this->fieldFormName]))?trim($_REQUEST[$this->fieldFormName]):'';
+    function get_request()
+    {
+        $this->value = (isset($_REQUEST[$this->fieldFormName])) ? trim($_REQUEST[$this->fieldFormName]) : '';
     }
 
+    // }}}
+    // {{{ function get_where_statement()
+    
     /** récupérer la clause correspondant au champ dans la clause WHERE de la requête
      * on parcourt l'ensemble des champs de la bdd de $fieldDbName et on associe 
      * à chacun d'entre eux une clause spécifique
      * la clause totale et la disjonction de ces clauses spécifiques */
-    function get_where_statement() {
-        if ($this->value=='')
+    function get_where_statement()
+    {
+        if ($this->value=='') {
             return false;
-        $res = implode(' OR ',array_filter(array_map(array($this,'get_single_where_statement'),$this->fieldDbName)));
-        return ($res!='')?('('.$res.')'):'';
+        }
+        $res = implode(' OR ', array_filter(array_map(array($this, 'get_single_where_statement'), $this->fieldDbName)));
+        return empty($res) ? '' : "($res)";
     }
 
+    // }}}
+    // {{{ function get_order_statement()
+    
     /** récupérer la clause correspondant au champ dans la clause ORDER BY de la requête
      * utilisé par exemple pour placer d'abord le nom égal à la requête avant les approximations */
-    function get_order_statement() {
+    function get_order_statement()
+    {
         return false;
     }
 
-    function get_select_statement() {
+    // }}}
+    // {{{ function get_select_statement()
+
+    function get_select_statement()
+    {
         return false;
     }
 
+    // }}}
+    // {{{ function get_url()
+
     /** récupérer le bout d'URL correspondant aux paramètres permettant d'imiter une requête d'un
      * utilisateur assignant la valeur $this->value à ce champ */
-    function get_url() {
-        if ($this->value=='')
+    function get_url()
+    {
+        if (empty($this->value)) {
             return false;
-        else
+        } else {
             return $this->fieldFormName.'='.urlencode($this->value);
+        }
     }
+
+    // }}}
 }
 
-class QuickSearch extends SField {
+// }}}
+// {{{ class QuickSearch                                [Google Like]
+
+class QuickSearch extends SField
+{
+    // {{{ properties
+    
+    /** stores tokens */
     var $strings;
+    /** stores numerical ranges */
     var $ranges;
 
-    function QuickSearch($_fieldFormName) {
+    // }}}
+    // {{{ constructor
+    
+    function QuickSearch($_fieldFormName)
+    {
         $this->fieldFormName = $_fieldFormName;
         $this->get_request();
-        if (preg_match(":[\]\[{}~/§_`|%$^=+]|\*\*:", $this->value))
+        if (preg_match(":[\]\[{}~/§_`|%$^=+]|\*\*:", $this->value)) {
             new ThrowError('Un champ contient un caractère interdit rendant la recherche impossible.');
+        }
     }
 
-    function isempty() {
+    // }}}
+    // {{{ function isempty()
+
+    function isempty()
+    {
        return empty($this->strings) && empty($this->ranges);
     }
+
+    // }}}
+    // {{{ function get_request()
     
-    function get_request() {
-       SField::get_request();
+    function get_request()
+    {
+       parent::get_request();
        $s = replace_accent(trim($this->value));
        $s = preg_replace('!\d+!', ' ', $s);
        $s = preg_replace('! - !', '', $s);
@@ -166,318 +235,521 @@ class QuickSearch extends SField {
        $s = preg_replace('![<>\-] !', '', $s);
        $ranges = preg_split('! +!', $s, -1, PREG_SPLIT_NO_EMPTY);
        $this->ranges=Array();
-       foreach($ranges as $r) {
-           if(preg_match('!^([<>]\d{4}|\d{4}(-\d{4})?)$!', $r)) $this->ranges[] = $r;
+       foreach ($ranges as $r) {
+           if (preg_match('!^([<>]\d{4}|\d{4}(-\d{4})?)$!', $r)) $this->ranges[] = $r;
        }
     }
 
-    function get_where_statement() {
+    // }}}
+    // {{{ function get_where_statement()
+    
+    function get_where_statement()
+    {
        $where = Array();
-       foreach($this->strings as $s) {
+       foreach ($this->strings as $s) {
            $t = '%'.str_replace('*', '%', $s).'%';
            $t = str_replace('%%', '%', $t);
-           $where[] = "(r.nom LIKE '$t' OR r.epouse LIKE '$t' OR r.prenom LIKE '$t')";
+           $where[] = "(u.nom LIKE '$t' OR u.epouse LIKE '$t' OR u.prenom LIKE '$t')";
        }
        
        $wherep = Array();
-       foreach($this->ranges as $r) {
-           if(preg_match('!^\d{4}$!', $r)) {
-               $wherep[] = "r.promo=$r";
-           } elseif(preg_match('!^(\d{4})-(\d{4})$!', $r, $matches)) {
+       foreach ($this->ranges as $r) {
+           if (preg_match('!^\d{4}$!', $r)) {
+               $wherep[] = "u.promo=$r";
+           } elseif (preg_match('!^(\d{4})-(\d{4})$!', $r, $matches)) {
                $p1=min(intval($matches[1]), intval($matches[2]));
                $p2=max(intval($matches[1]), intval($matches[2]));
-               $wherep[] = "(r.promo>=$p1 AND r.promo<=$p2)";
-           } elseif(preg_match('!^<(\d{4})!', $r, $matches)) {
-               $wherep[] = "r.promo<={$matches[1]}";
-           } elseif(preg_match('!^>(\d{4})!', $r, $matches)) {
-               $wherep[] = "r.promo>={$matches[1]}";
+               $wherep[] = "(u.promo>=$p1 AND u.promo<=$p2)";
+           } elseif (preg_match('!^<(\d{4})!', $r, $matches)) {
+               $wherep[] = "u.promo<={$matches[1]}";
+           } elseif (preg_match('!^>(\d{4})!', $r, $matches)) {
+               $wherep[] = "u.promo>={$matches[1]}";
            }
        }
-       if(!empty($wherep)) $where[] = '('.join(' OR ',$wherep).')';
+       if (!empty($wherep)) {
+            $where[] = '('.join(' OR ',$wherep).')';
+        }
        return join(" AND ", $where);
     }
+
+    // }}}
+    // {{{ function get_mark_statement()
     
-    function get_mark_statement() {
-       if(empty($this->strings)) return "1 AS mark";
-       $order = Array();
-       foreach($this->strings as $s) {
-           $order[] = "(r.nom='$s' OR r.epouse='$s')*100 + "
-                    .  "(r.prenom='$s') * 10 + "
-                    .  "(r.nom LIKE '$s%' OR r.epouse LIKE '$s%')";
+    function get_mark_statement()
+    {
+       if (empty($this->strings)) {
+            return "1 AS mark";
+        }
+       $order = "0";
+       foreach ($this->strings as $s) {
+           $order .= " + (u.nom='$s' OR u.epouse='$s')*100 + (u.prenom='$s')*10 + (u.nom LIKE '$s%' OR u.epouse LIKE '$s%')";
        }
-       $res = join(' + ', $order);
-       if($res) return "$res AS mark";
+        return $order.' AS mark';
     }
-    function get_order_statement() {
-       if(empty($this->strings)) return false;
-        return "mark DESC";
+
+    // }}}
+    // {{{ function get_order_statement()
+    
+    function get_order_statement()
+    {
+        return 'mark DESC';
     }
+
+    // }}}
 }
-               
+
+// }}}
+// {{{ class NumericSField                              [Integer fields]
 
 /** classe de champ numérique entier (offset par exemple)
  */
-class NumericSField extends SField {
+class NumericSField extends SField
+{
+    // {{{ constructor
+    
     /** constructeur
      * (récupère la requête de l'utilisateur pour ce champ) */
-    function NumericSField($_fieldFormName) {
+    function NumericSField($_fieldFormName)
+    {
         $this->fieldFormName = $_fieldFormName;
         $this->get_request();
     }
+
+    // }}}
+    // {{{ function get_request()
     
     /** récupère la requête de l'utilisateur et échoue s'il ne s'agit pas d'un entier */
-    function get_request() {
+    function get_request()
+    {
         parent::get_request();
-        if ($this->value=='')
+        if (empty($this->value)) {
             $this->value = 0;
-        if (!preg_match("/^[0-9]+$/", $this->value))
+        }
+        if (!preg_match("/^[0-9]+$/", $this->value)) {
             new ThrowError('Un champ numérique contient des caractères alphanumériques.');
+        }
     }
+    
+    // }}}
 }
 
-class RefSField extends SField {
+// }}}
+// {{{ class RefSField                                  [ ??? ]
+
+class RefSField extends SField
+{
+    // {{{ properties
+    
     var $refTable;
     var $refAlias;
     var $refCondition;
-    var $exact=true;
+    var $exact = true;
+
+    // }}}
+    // {{{ constructor
 
-    function RefSField($_fieldFormName,$_fieldDbName='',$_refTable,$_refAlias,$_refCondition,$_exact=true) {
+    function RefSField($_fieldFormName, $_fieldDbName='', $_refTable, $_refAlias, $_refCondition, $_exact=true)
+    {
         $this->fieldFormName = $_fieldFormName;
-        $this->fieldDbName = $_fieldDbName;
-        $this->refTable = $_refTable;
-        $this->refAlias = $_refAlias;
-        $this->refCondition = $_refCondition;
-        $this->exact = $_exact;
+        $this->fieldDbName   = $_fieldDbName;
+        $this->refTable      = $_refTable;
+        $this->refAlias      = $_refAlias;
+        $this->refCondition  = $_refCondition;
+        $this->exact         = $_exact;
         $this->get_request();
     }
+
+    // }}}
+    // {{{ function get_request()
     
     function get_request() {
         parent::get_request();
-        if ($this->value=='00' || $this->value=='0')
+        if ($this->value=='00' || $this->value=='0') {
             $this->value='';
+        }
     }
 
-    function too_large() {
+    // }}}
+    // {{{ function too_large()
+
+    function too_large()
+    {
         return ($this->value=='');
     }
 
-    function compare() {
-        if ($this->exact)
-            return "='".$this->value."'";
-        else
-            return " LIKE '%".$this->value."%'";
+    // }}}
+    // {{{ function compare()
+
+    function compare()
+    {
+        return $this->exact ? "='{$this->value}'" : " LIKE '%{$this->value}%'";
     }
 
-    function get_single_match_statement($field) {
+    // }}}
+    // {{{ function get_single_match_statement()
+
+    function get_single_match_statement($field)
+    {
         return $field.$this->compare();
     }
 
-    function get_single_where_statement($field) {
-        if ($this->refTable=='')
-            return $this->get_single_match_statement($field);
-        return false;
+    // }}}
+    // {{{ function get_single_where_statement()
+
+    function get_single_where_statement($field)
+    {
+        return $this->refTable=='' ? $this->get_single_match_statement($field) : false;
     }
 
-    function get_select_statement() {
-        if ($this->value=='' || $this->refTable=='')
+    // }}}
+    // {{{ function get_select_statement()
+
+    function get_select_statement()
+    {
+        if ($this->value=='' || $this->refTable=='') {
             return false;
-        $res = implode(' OR ',array_filter(array_map(array($this,'get_single_match_statement'),$this->fieldDbName)));
-        return 'INNER JOIN '.$this->refTable.' AS '.$this->refAlias.
-        ' ON('.$this->refCondition.' AND '.'('.$res.')'.")";
+        }
+        $res = implode(' OR ', array_filter(array_map(array($this, 'get_single_match_statement'), $this->fieldDbName)));
+        return "INNER JOIN {$this->refTable} AS {$this->refAlias} ON ({$this->refCondition} AND ($res) )";
     }
+
+    // }}}
 }
 
-class RefWithSoundexSField extends RefSField {
-    function compare() {
+// }}}
+// {{{ class RefWithSoundexSField                       [ ??? ]
+
+class RefWithSoundexSField extends RefSField
+{
+    // {{{ function compare()
+    
+    function compare()
+    {
        return "='".soundex_fr($this->value)."'";
     }
+
+    // }}}
 }
 
+// }}}
+// {{{ class StringSField                               [String fields]
+
 /** classe de champ texte (nom par exemple)
  */
-class StringSField extends SField {
+class StringSField extends SField
+{
+    // {{{ function get_request()
+    
     /** récupère la requête de l'utilisateur et échoue si la chaîne contient des caractères
      * interdits */
-    function get_request() {
+    function get_request()
+    {
         parent::get_request();
-        if (preg_match(":[\]\[<>{}~/§_`|%$^=+]|\*\*:", $this->value))
+        if (preg_match(":[\]\[<>{}~/§_`|%$^=+]|\*\*:", $this->value)) {
             new ThrowError('Un champ contient un caractère interdit rendant la recherche impossible.');
+        }
     }
 
+    // }}}
+    // {{{ function length()
+
     /** donne la longueur de la requête de l'utilisateur
      * (au sens strict i.e. pas d'* ni d'espace ou de trait d'union -> les contraintes réellement
      * imposées par l'utilisateur) */
-    function length() {
+    function length()
+    {
         global $lc_accent,$uc_accent;
-        return
-        strlen($this->value)-strlen(ereg_replace('[a-z'.$lc_accent.$uc_accent.']','',strtolower($this->value)));
+        return strlen($this->value) - strlen(ereg_replace('[a-z'.$lc_accent.$uc_accent.']', '', strtolower($this->value)));
     }
 
-    function too_large() {
+    // }}}
+    // {{{ function too_large()
+
+    function too_large()
+    {
         return ($this->length()<2);
     }
 
+    // }}}
+    // {{{ function get_single_where_statement()
+
     /** clause WHERE correspondant à un champ de la bdd et à ce champ de formulaire
      * @param field nom de champ de la bdd concerné par la clause */
-    function get_single_where_statement($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).".*'";
-
-        //Nouvelle version plus rapide
-        $regexp = str_replace('-','_',$this->value);
-        $regexp = str_replace('*','%',$regexp);
+    function get_single_where_statement($field)
+    {
+        $regexp = strtr($this->value, '-*', '_%');
         return "$field LIKE '$regexp%'";
     }
 
+    // }}}
+    // {{{ function get_order_statement()
+
     /** clause ORDER BY correspondant à ce champ de formulaire */
-    function get_order_statement() {
-        if ($this->value!='' && $this->fieldResultName!='')
-            return $this->fieldResultName.'!="'.$this->value.'"';
-        else
+    function get_order_statement()
+    {
+        if ($this->value!='' && $this->fieldResultName!='') {
+            return "{$this->fieldResultName}!='{$this->value}'";
+        } else {
             return false;
+        }
     }
+
+    // }}}
 }
 
+// }}}
+// {{{ class NameSField                                 [Names : serach 'n%' + '% b']
+
 /** classe pour les noms : on cherche en plus du like 'foo%' le like '% foo' (particules)
 +*/
-class NameSField extends StringSField {
-    function get_single_where_statement($field) {
-        $regexp = str_replace('-','_',$this->value);
-        $regexp = str_replace('*','%',$regexp);
+class NameSField extends StringSField
+{
+    // {{{ function get_single_where_statement()
+    
+    function get_single_where_statement($field)
+    {
+        $regexp = strtr($this->value, '-*', '_%');
         return "$field LIKE '$regexp%' OR $field LIKE '% $regexp%' OR $field LIKE '%-$regexp%'";
     }
+
+    // }}}
+    // {{{ function get_order_statement()
     
-    function get_order_statement() {
-        if ($this->value!='' && $this->fieldResultName!='')
-            return $this->fieldResultName.' NOT LIKE "'.$this->value.'"';
-        else
+    function get_order_statement()
+    {
+        if ($this->value!='' && $this->fieldResultName!='') {
+            return "{$this->fieldResultName} NOT LIKE '{$this->value}'";
+        } else {
             return false;
+        }
     }
+
+    // }}}
 }
 
+// }}}
+// {{{ class StringWithSoundexSField                    [Strings + soundex]
+
 /** classe de champ texte avec soundex (nom par exemple)
  */
-class StringWithSoundexSField extends StringSField {
+class StringWithSoundexSField extends StringSField
+{
+    // {{{ function get_single_where_statement()
+
     /** clause WHERE correspondant à un champ de la bdd et à ce champ de formulaire
      * @param field nom de champ de la bdd concerné par la clause */
     function get_single_where_statement($field) {
         return $field.'="'.soundex_fr($this->value).'"';
     }
+
+    // }}}
 }
 
+// }}}
+// {{{ class PromoSField                                [Prom field]
+
 /** classe de champ de promotion */
-class PromoSField extends SField {
+class PromoSField extends SField
+{
+    // {{{ properties
+    
     /** opérateur de comparaison (<,>,=) de la promo utilisé pour ce champ de formulaire */
     var $compareField;
 
+    // }}}
+    // {{{ constructor
+
     /** constructeur 
      * compareField est un champ de formulaire très simple qui ne sert qu'à la construction de la
      * clause WHERE de la promo */
-    function PromoSField($_fieldFormName,$_compareFieldFormName,$_fieldDbName,$_fieldResultName) {
-        parent::SField($_fieldFormName,$_fieldDbName,$_fieldResultName);
+    function PromoSField($_fieldFormName, $_compareFieldFormName, $_fieldDbName, $_fieldResultName)
+    {
+        parent::SField($_fieldFormName, $_fieldDbName, $_fieldResultName);
         $this->compareField = new SField($_compareFieldFormName);
     }
 
+    // }}}
+    // {{{ function get_request()
+
     /** récupère la requête utilisateur et échoue si le champ du formulaire ne représente pas une
      * promotion (nombre à 4 chiffres) */
-    function get_request() {
+    function get_request()
+    {
         parent::get_request();
-        if (!(empty($this->value) or preg_match("/^[0-9]{4}$/", $this->value)))
+        if (!(empty($this->value) or preg_match('/^[0-9]{4}$/', $this->value))) {
             new ThrowError('La promotion est une année à quatre chiffres.');
+        }
     }
 
+    // }}}
+    // {{{ function is_a_single_promo()
+
     /** teste si la requête est de la forme =promotion -> contrainte forte imposée -> elle suffit
      * pour autoriser un affichage des résultats alors que <promotion est insuffisant */
-    function is_a_single_promo() {
+    function is_a_single_promo()
+    {
         return ($this->compareField->value=='=' && $this->value!='');
     }
 
-    function too_large() {
-        return (!$this->is_a_single_promo());
+    // }}}
+    // {{{ function too_large()
+
+    function too_large()
+    {
+        return !$this->is_a_single_promo();
     }
 
+    // }}}
+    // {{{ function get_single_where_statement()
+
     /** clause WHERE correspondant à ce champ */
-    function get_single_where_statement($field) {
+    function get_single_where_statement($field)
+    {
         return $field.$this->compareField->value.$this->value;
     }
 
+    // }}}
+    // {{{ function get_url()
+
     /** récupérer le bout d'URL correspondant aux paramètres permettant d'imiter une requête
      * d'un utilisateur assignant la valeur $this->value à ce champ et assignant l'opérateur de
      * comparaison adéquat */
-    function get_url() {
-        if (!($u=parent::get_url()))
+    function get_url()
+    {
+        if (!($u=parent::get_url())) {
             return false;
-        return $u.'&'.$this->compareField->get_url();
+        }
+        return $u.'&amp;'.$this->compareField->get_url();
     }
+
+    // }}}
 }
 
+// }}}
+// {{{ class SFieldGroup                                [Group fields]
+
 /** classe groupant des champs de formulaire de recherche */
-class SFieldGroup {
+class SFieldGroup
+{
+    // {{{ properties
+    
     /** tableau des classes correspondant aux champs groupés */
     var $fields;
     /** type de groupe : ET ou OU */
     var $and;
 
+    // }}}
+    // {{{ constuctor
+
     /** constructeur */
-    function SFieldGroup($_and,$_fields) {
+    function SFieldGroup($_and, $_fields)
+    {
         $this->fields = $_fields;
-        $this->and = $_and;
+        $this->and    = $_and;
     }
 
-    function too_large() {
+    // }}}
+    // {{{ function too_large()
+
+    function too_large()
+    {
         $b = true;
-        for ($i=0;$i<count($this->fields);$i++)
-            $b = $b && $this->fields[$i]->too_large();
+        for ($i=0; $b && $i<count($this->fields); $i++) {
+            $b &= $this->fields[$i]->too_large();
+        }
         return $b;
     }
 
-    function field_get_select($f) {
+    // }}}
+    // {{{ function field_get_select()
+
+    function field_get_select($f)
+    {
         return $f->get_select_statement();
     }
 
+    // }}}
+    // {{{ function field_get_where()
+
     /** récupérer la clause WHERE d'un objet champ de recherche */
-    function field_get_where($f) {
+    function field_get_where($f)
+    {
         return $f->get_where_statement();
     }
 
+    // }}}
+    // {{{ function field_get_order()
+
     /** récupérer la clause ORDER BY d'un objet champ de recherche */
-    function field_get_order($f) {
+    function field_get_order($f)
+    {
         return $f->get_order_statement();
     }
 
+    // }}}
+    // {{{ function field_get_url()
+
     /** récupérer le bout d'URL correspondant à un objet champ de recherche */
-    function field_get_url($f) {
+    function field_get_url($f)
+    {
         return $f->get_url();
     }
+    
+    // }}}
+    // {{{ function get_select_statement()
 
-    function get_select_statement() {
-        return implode(' ',array_filter(array_map(array($this,'field_get_select'),$this->fields)));
+    function get_select_statement()
+    {
+        return implode(' ', array_filter(array_map(array($this, 'field_get_select'), $this->fields)));
     }
 
+    // }}}
+    // {{{ function get_where_statement()
+
     /** récupérer la clause WHERE du groupe de champs = conjonction (ET) ou disjonction (OU) de
      * clauses des champs élémentaires */
-    function get_where_statement() {
-        $joinText=($this->and)?' AND ':' OR ';
-        $res = implode($joinText,array_filter(array_map(array($this,'field_get_where'),$this->fields)));
-        return ($res!='')?('('.$res.')'):'';
+    function get_where_statement()
+    {
+        $joinText = $this->and ? ' AND ' : ' OR ';
+        $res = implode($joinText, array_filter(array_map(array($this, 'field_get_where'), $this->fields)));
+        return $res == '' ? '' : "($res)";
     }
 
+    // }}}
+    // {{{ function get_order_statement()
+
     /** récupérer la clause ORDER BY du groupe de champs = conjonction (ET) ou disjonction (OU) de
      * clauses des champs élémentaires */
-    function get_order_statement() {
-        $order = array_filter(array_map(array($this,'field_get_order'),$this->fields));
-        return (count($order)>0)?implode(',',$order):false;
+    function get_order_statement()
+    {
+        $order = array_filter(array_map(array($this, 'field_get_order'), $this->fields));
+        return count($order)>0 ? implode(',', $order) : false;
     }
 
+    // }}}
+    // {{{ function get_url()
+
     /** récupérer le bout d'URL correspondant à ce groupe de champs = concaténation des bouts d'URL
      * des champs élémentaires */
-    function get_url() {
-        $url = array_filter(array_map(array($this,'field_get_url'),$this->fields));
-        return (count($url)>0)?implode('&',$url):false;
-    }
+    function get_url($others=Array())
+    {
+        $url = array_filter(array_map(array($this, 'field_get_url'), $this->fields));
+        foreach ($url as $key=>$val) {
+            if (empty($val)) {
+                unset($url[$key]);
+            }
+        }
+        foreach ($others as $key=>$val) {
+            if (!empty($val)) {
+                $url[$key] = $val;
+            }
+        }
+        return count($url)>0 ? implode('&amp;', $url) : false;
+    }
+
+    // }}}
 }
 
+// }}}
+
 ?>
index ea59be8..0ff7d58 100644 (file)
@@ -1,6 +1,8 @@
 htdocs/advanced_search.php
 htdocs/search.php
 include/search.classes.inc.php
+include/conf.d/search.globals.inc.php
+include/conf.d/search.menu.inc.php
 bin/cron/recherche.php
 bin/cron/recherche.pl
 bin/cron/recherche.sql
index 343eee1..56b4360 100644 (file)
@@ -27,7 +27,7 @@
   {foreach from=$index2 key=h2 item=index3}
   <tr class="{cycle values="impair,pair"}">
     <td>
-      <strong>{$h2} : </strong>
+      <strong>{$h2} :</strong>&nbsp;&nbsp;
       {foreach from=$index3 item=ln name=ln}
       <a href="{rel}/{$ln.url}">{$ln.txt}</a>
       {if !$smarty.foreach.ln.last}
index 96ec513..5ad5025 100644 (file)
@@ -77,7 +77,7 @@ function chgMainWinLoc( strPage ) {
         {if $iso3166}
         <img src='{"images/"|url}flags/{$iso3166}.gif' alt='{$nationalite}' height='14' title='{$nationalite}' />&nbsp;
         {/if}
-        X {$promo}&nbsp;-&nbsp;Formation&nbsp;: {$applis|smarty:nodefaults}
+        X {$promo}{if $applis}&nbsp;-&nbsp;Formation&nbsp;: {$applis|smarty:nodefaults}{/if}
         {if $is_referent}
         [<a href="fiche_referent.php?user={$forlife}" class='popup'>Ma fiche référent</a>]
         {/if}
index 4dfea0d..3470f46 100644 (file)
@@ -16,8 +16,6 @@
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: archives.head.tpl,v 1.1 2004/11/28 22:51:29 x2000habouzit Exp $
  ***************************************************************************}
 
 {literal}
index 91e4fd6..4d7153c 100644 (file)
@@ -16,8 +16,6 @@
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: archives.tpl,v 1.4 2004/12/01 11:15:12 x2000habouzit Exp $
  ***************************************************************************}
 
 {dynamic}
index 4cf7251..a246935 100644 (file)
@@ -16,8 +16,6 @@
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: search.adv.form.tpl,v 1.6 2004/11/27 17:44:00 x2000bedo Exp $
  ***************************************************************************}
 
 <h1>Recherche avancée</h1>
@@ -35,7 +33,7 @@
       <td>
         <input type="text" name="name" size="32" value="{$smarty.request.name}" />
         {if $smarty.request.name && !$with_soundex && $smarty.request.recherche}
-        <a class='smaller' href="{$smarty.server.PHP_SELF}?with_soundex=1&amp;rechercher=1&amp;{$url_args}&amp;mod_date_sort={$mod_date_sort}">
+        <a class='smaller' href="{$smarty.server.PHP_SELF}?with_soundex=1&amp;{$url_args}">
           étendre par proximité sonore
         </a>
         {/if}
@@ -46,7 +44,7 @@
       <td>
         <input type="text" name="firstname" size="32" value="{$smarty.request.firstname}" />
         {if $smarty.request.firstname && !$with_soundex && $smarty.request.recherche}
-        <a class='smaller' href="{$smarty.server.PHP_SELF}?with_soundex=1&amp;rechercher=1&amp;{$url_args}&amp;mod_date_sort={$mod_date_sort}">
+        <a class='smaller' href="{$smarty.server.PHP_SELF}?with_soundex=1&amp;{$url_args}">
           étendre par proximité sonore
         </a>
         {/if}
index 9280a81..de92a70 100644 (file)
@@ -16,8 +16,6 @@
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: search.adv.links.tpl,v 1.1 2004/11/04 13:50:45 x2000habouzit Exp $
  ***************************************************************************}
 
  {if $do_title}<h1>Recherche avancée</h1>{/if}
 <ul>
   {if !$with_soundex && ($smarty.request.firstname || $smarty.request.name)}
   <li>Étendre ta recherche par <strong>
-    <a  href="{$smarty.server.PHP_SELF}?with_soundex=1&amp;rechercher=1&amp;{$url_args}&amp;mod_date_sort={$mod_date_sort}">proximité sonore</a>
+    <a  href="{$smarty.server.PHP_SELF}?with_soundex=1&amp;{$url_args}">proximité sonore</a>
   </strong>
   </li>
   {/if}
 
-  <li><strong><a href="{$smarty.server.PHP_SELF}?{$url_args}&amp;mod_date_sort={$mod_date_sort}">Modifier</a>
+  <li><strong><a href="{$smarty.server.PHP_SELF}?{$url_args}">Modifier</a>
   </strong> ta recherche
   </li>
 
index 029f52d..3634824 100644 (file)
@@ -16,8 +16,6 @@
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: search.quick.form.tpl,v 1.4 2004/11/23 10:07:28 x2000habouzit Exp $
  ***************************************************************************}
 
 <h1>Recherche simple dans l'annuaire</h1>
index 4fe5f11..d19c8bb 100644 (file)
@@ -16,8 +16,6 @@
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: search.quick.tpl,v 1.3 2004/11/23 10:07:28 x2000habouzit Exp $
  ***************************************************************************}
 
 {include file="search.quick.form.tpl"}
index 3dcd945..b206429 100644 (file)
@@ -16,8 +16,6 @@
  *  along with this program; if not, write to the Free Software            *
  *  Foundation, Inc.,                                                      *
  *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA                *
- ***************************************************************************
-        $Id: search.tpl,v 1.30 2004/11/18 15:17:42 x2000habouzit Exp $
  ***************************************************************************}
 
 {dynamic}
   {if $perpage < $nb_resultats_total}
   <p>
     {if $offset!=0}
-    <a href="{$smarty.server.PHP_SELF}?with_soundex={$with_soundex}&amp;rechercher=1&amp;{$url_args}&amp;offset={$offset-$perpage}&amp;mod_date_sort={$mod_date_sort}">Précédent</a>
+    <a href="{$smarty.server.PHP_SELF}?{$url_args}&amp;offset={$offset-$perpage}">Précédent</a>
     &nbsp;
     {/if}
     {section name=offset loop=$offsets}
       {if $offset!=$smarty.section.offset.index*$perpage}
-      <a href="{$smarty.server.PHP_SELF}?with_soundex={$with_soundex}&amp;rechercher=1&amp;{$url_args}&amp;offset={$smarty.section.offset.index*$perpage}&amp;mod_date_sort={$mod_date_sort}">{$smarty.section.offset.index+1}</a>
+      <a href="{$smarty.server.PHP_SELF}?{$url_args}&amp;offset={$smarty.section.offset.index*$perpage}">{$smarty.section.offset.index+1}</a>
       {else}
       <span class="error">{$smarty.section.offset.index+1}</span>
       {/if}
       &nbsp;
     {/section}
     {if $offset < $nb_resultats_total-$perpage}
-    <a href="{$smarty.server.PHP_SELF}?with_soundex={$with_soundex}&amp;rechercher=1&amp;{$url_args}&amp;offset={$offset+$perpage}&amp;mod_date_sort={$mod_date_sort}">Suivant</a>
+    <a href="{$smarty.server.PHP_SELF}?{$url_args}&amp;offset={$offset+$perpage}">Suivant</a>
     &nbsp;
     {/if}
   </p>