- Modification des templates :
authorBenjamin Renard <brenard@easter-eggs.com>
Wed, 18 Jun 2008 12:27:35 +0000 (12:27 +0000)
committerBenjamin Renard <brenard@easter-eggs.com>
Wed, 18 Jun 2008 12:27:35 +0000 (12:27 +0000)
 -> Le choix du niveau est maintenant dans le menu de gauche
 -> Le logo est cliquable (retour à l'accueil)
- Mise en cache des subDnLdapServer (sous-niveaux)
- Modification majeur sur le module de recherche :
  -> Refonte du mécanisme de la page
-> Ajout du cache de recherche (gain notable de rapidité)
-> Ajout d'un message quand la recherche ne retourne aucun résultat
-> Possibilité de faire une recherche récursive
- Personnalisation rendu possible du nom donné au concepte de niveau
- LSldapObject : Correction d'un bug dans la méthode listObjects() : Warning
  lors de certains retours vides.
- LSsession :
  -> Création de méthode pour centraliser les tests d'activation des caches
  -> Proprité ajax_displate : permet l'affichage des debugs à travers les
   requêtes ajax du type 'update'
- LSsmoothbox : Modification de l'affichage

18 files changed:
trunk/conf/config.inc.php
trunk/includes/class/class.LSldapObject.php
trunk/includes/class/class.LSsession.php
trunk/includes/functions.php
trunk/includes/js/LSdefault.js
trunk/includes/js/LSselect.js
trunk/includes/js/LSsession_login.js
trunk/includes/js/LSsmoothbox.js
trunk/index_ajax.php
trunk/select.php
trunk/templates/css/base.css
trunk/templates/images/refresh.png [new file with mode: 0644]
trunk/templates/login.tpl
trunk/templates/select.tpl
trunk/templates/select_table.tpl
trunk/templates/top.tpl
trunk/templates/viewList.tpl
trunk/view.php

index 9dc795e..258386d 100644 (file)
@@ -25,7 +25,9 @@ $GLOBALS['LSconfig'] = array(
   'NetLDAP2' => '/usr/share/php/Net/LDAP2.php',
   'Smarty' => '/var/www/tmp/Smarty-2.6.18/libs/Smarty.class.php',
   'lang' => 'fr_FR.UTF8',
-  'cacheLSrights' => false,
+  'cacheLSrights' => true,
+  'cacheSubDn' => true,
+  'cacheSearch' => true,
   'ldap_servers' => array (
     array (
       'name' => 'LSexample',
@@ -53,6 +55,7 @@ $GLOBALS['LSconfig'] = array(
           )
         ),
         'cacheLSrights' => false,
+        'cacheSearch' => true,
       'authobject' => 'LSeepeople',
       'authobject_pwdattr' => 'userPassword',
       'recoverPassword' => array(
index 3c49622..62a09bc 100644 (file)
@@ -746,10 +746,15 @@ class LSldapObject {
         // Si recherche unique
         else {
           // préparation du retour finale
-          $ret_final=array();
-          foreach($ret as $obj)
-            $ret_final[]=$obj['dn'];
-          $ret=$ret_final;
+          if (is_array($ret)) {
+            $ret_final=array();
+            foreach($ret as $obj)
+              $ret_final[]=$obj['dn'];
+            $ret=$ret_final;
+          }
+          else {
+            $ret=array();
+          }
           break;
         }
       }
index 726d112..2c43324 100644 (file)
@@ -46,6 +46,8 @@ class LSsession {
   );
   var $LSaccess = array();
   var $tmp_file = array();
+  var $_subDnLdapServer = array();
+  var $ajaxDisplay = false;
 
   /**
    * Constructeur
@@ -243,7 +245,7 @@ class LSsession {
         $this -> ldapServerId = $_SESSION['LSsession']['ldapServerId'];
         $this -> tmp_file     = $_SESSION['LSsession']['tmp_file'];
         
-        if ( ($GLOBALS['LSconfig']['cacheLSrights']) || ($this -> ldapServer['cacheLSrights']) ) {
+        if ( $this -> cacheLSrights() ) {
           $this -> ldapServer = $_SESSION['LSsession']['ldapServer'];
           $this -> LSrights   = $_SESSION['LSsession']['LSrights'];
           $this -> LSaccess   = $_SESSION['LSsession']['LSaccess'];
@@ -258,6 +260,11 @@ class LSsession {
           $this -> loadLSobjects();
           $this -> loadLSrights();
         }
+        
+        if ( $this -> cacheSudDn() && (!isset($_REQUEST['LSsession_topDn_refresh'])) ) {
+          $this -> _subDnLdapServer = $_SESSION['LSsession_subDnLdapServer'];
+        }
+        
         $this -> loadLSobject($this -> ldapServer['authobject']);
         $this -> LSuserObject = new $this -> ldapServer['authobject']();
         $this -> LSuserObject -> loadData($this -> dn);
@@ -466,7 +473,7 @@ class LSsession {
                     $this -> rdn = $_POST['LSsession_user'];
                     $this -> loadLSrights();
                     $this -> loadLSaccess();
-                    $GLOBALS['Smarty'] -> assign('LSsession_username',$this -> LSuserObject -> getDisplayValue());
+                    $GLOBALS['Smarty'] -> assign('LSsession_username',$this -> LSuserObject -> getValue('rdn'));
                     $_SESSION['LSsession']=get_object_vars($this);
                     return true;
                   }
@@ -549,6 +556,9 @@ class LSsession {
   * @retval mixed Tableau des subDn, false si une erreur est survenue.
   */
   function getSubDnLdapServer() {
+    if ($this -> cacheSudDn() && isset($this -> _subDnLdapServer[$this -> ldapServerId])) {
+      return $this -> _subDnLdapServer[$this -> ldapServerId];
+    }
     if ( is_array($this ->ldapServer['subDn']) ) {
       $return=array();
       foreach($this ->ldapServer['subDn'] as $subDn_name => $subDn_config) {
@@ -588,12 +598,32 @@ class LSsession {
           $return[$subDn_config] = $subDn_name;
         }
       }
+      if ($this -> cacheSudDn()) {
+        $this -> _subDnLdapServer[$this -> ldapServerId]=$return;
+        $_SESSION['LSsession_subDnLdapServer'] = $this -> _subDnLdapServer;
+      }
       return $return;
     }
     else {
       return;
     }
   }
+  
+  /**
+   * Retourne la liste de subDn du serveur Ldap utilise
+   * trié par la profondeur dans l'arboressence (ordre décroissant)
+   * 
+   * @return array() Tableau des subDn trié
+   */  
+  function getSortSubDnLdapServer() {
+    if(isset($_SESSION['LSsession']['LSview_subDnLdapServer']) && $this -> cacheSudDn()) {
+      return $_SESSION['LSsession']['LSview_subDnLdapServer'];
+    }
+    $subDnLdapServer = $this  -> getSubDnLdapServer();
+    uksort($subDnLdapServer,"compareDn");
+    $_SESSION['LSsession']['LSview_subDnLdapServer']=$subDnLdapServer;
+    return $subDnLdapServer;
+  }
 
  /**
   * Retourne les options d'une liste déroulante pour le choix du topDn
@@ -825,20 +855,28 @@ class LSsession {
     // Niveau
     $listTopDn = $this -> getSubDnLdapServer();
     if (is_array($listTopDn)) {
-      $GLOBALS['Smarty'] -> assign('label_level',_('Niveau'));
+      $GLOBALS['Smarty'] -> assign('label_level',$this -> getLevelLabel());
+      $GLOBALS['Smarty'] -> assign('_refresh',_('Rafraîchir'));
       $LSsession_topDn_index = array();
       $LSsession_topDn_name = array();
       foreach($listTopDn as $index => $name) {
         $LSsession_topDn_index[]  = $index;
         $LSsession_topDn_name[]   = $name;
       }
-      $GLOBALS['Smarty'] -> assign('LSsession_topDn_index',$LSsession_topDn_index);
-      $GLOBALS['Smarty'] -> assign('LSsession_topDn_name',$LSsession_topDn_name);
-      $GLOBALS['Smarty'] -> assign('LSsession_topDn',$this -> topDn);
+      $GLOBALS['Smarty'] -> assign('LSsession_subDn_indexes',$LSsession_topDn_index);
+      $GLOBALS['Smarty'] -> assign('LSsession_subDn_names',$LSsession_topDn_name);
+      $GLOBALS['Smarty'] -> assign('LSsession_subDn',$this -> topDn);
+      $GLOBALS['Smarty'] -> assign('LSsession_subDnName',$this -> getSubDnName());
     }
     
-    $GLOBALS['LSerror'] -> display();
-    debug_print();
+    if ($this -> ajaxDisplay) {
+      $GLOBALS['Smarty'] -> assign('error_txt',json_encode($GLOBALS['LSerror']->getErrors()));
+      $GLOBALS['Smarty'] -> assign('debug_txt',json_encode(debug_print(true)));
+    }
+    else {
+      $GLOBALS['LSerror'] -> display();
+      debug_print();
+    }
     if (!$this -> template)
       $this -> setTemplate('empty.tpl');
     $GLOBALS['Smarty'] -> display($this -> template);
@@ -1184,6 +1222,69 @@ class LSsession {
     }
   }
 
+  /**
+   * Retourne true si le cache des droits est activé
+   *
+   * @author Benjamin Renard <brenard@easter-eggs.com>
+   * 
+   * @retval boolean True si le cache des droits est activé, false sinon.
+   */
+  function cacheLSrights() {
+    return ( ($GLOBALS['LSconfig']['cacheLSrights']) || ($this -> ldapServer['cacheLSrights']) );
+  }
+
+  /**
+   * Retourne true si le cache des subDn est activé
+   *
+   * @author Benjamin Renard <brenard@easter-eggs.com>
+   * 
+   * @retval boolean True si le cache des subDn est activé, false sinon.
+   */
+  function cacheSudDn() {
+    return (($GLOBALS['LSconfig']['cacheSubDn']) || ($this -> ldapServer['cacheSubDn']));
+  }
+  
+  /**
+   * Retourne true si le cache des recherches est activé
+   *
+   * @author Benjamin Renard <brenard@easter-eggs.com>
+   * 
+   * @retval boolean True si le cache des recherches est activé, false sinon.
+   */
+  function cacheSearch() {
+    return (($GLOBALS['LSconfig']['cacheSearch']) || ($this -> ldapServer['cacheSearch']));
+  }
+  
+  /**
+   * Retourne le label des niveaux pour le serveur ldap courant
+   * 
+   * @author Benjamin Renard <brenard@easter-eggs.com>
+   * 
+   * @retval string Le label des niveaux pour le serveur ldap dourant
+   */
+  function getLevelLabel() {
+    return ($this -> ldapServer['levelLabel']!='')?$this -> ldapServer['levelLabel']:_('Niveau');
+  }
+  
+  /**
+   * Retourne le nom du subDn
+   * 
+   * @param[in] $subDn string subDn
+   * 
+   * @return string Le nom du subDn ou '' sinon
+   */
+  function getSubDnName($subDn=false) {
+    if (!$subDn) {
+      $subDn = $this -> topDn;
+    }
+    if ($this -> getSubDnLdapServer()) {
+      if (isset($this -> _subDnLdapServer[$this -> ldapServerId][$subDn])) {
+        return $this -> _subDnLdapServer[$this -> ldapServerId][$subDn];
+      }
+    }
+    return '';
+  }
+
 }
 
 ?>
index d82efec..f78707a 100644 (file)
@@ -258,5 +258,12 @@ function debug_print($return=false) {
     }
     return $retVal;
   }
+  
+  function compareDn($a,$b) {
+    if (substr_count($a,',') > substr_count($b,','))
+      return -1;
+    else 
+      return 1;
+  }
 
 ?>
index a354c75..74df852 100644 (file)
@@ -31,7 +31,7 @@ var LSdefault = new Class({
 
     onLSdebugHiddenClick: function(event){
       new Event(event).stop();
-      new Fx.Style(this.LSdebug,'opacity',{duration:500}).start(1,0);
+      new Fx.Style(this.LSdebug,'opacity',{duration:500}).start(0.8,0);
     },
 
     displayDebugBox: function() {
@@ -46,8 +46,7 @@ var LSdefault = new Class({
     },
 
     displayDebug: function(html) {
-      this.LSdebug.empty();
-      this.LSdebug.setHTML(html);
+      this.LSdebugInfos.setHTML(html);
       this.displayDebugBox();
     },
 
index 33d8b92..978f80d 100644 (file)
@@ -1,17 +1,24 @@
 var LSselect = new Class({
     initialize: function(){
-      this.initializeContent();
+      this.main_page = $('LSobject-select-main-div').getParent();
+      this.content = $('content');
       
-      $$('form.LSselect_search').each(function(el) {
-        var input = new Element('input');
-        input.setProperty('name','ajax');
-        input.setProperty('type','hidden');
-        input.injectInside(el);
-        el.addEvent('submit',this.onSubmitSearchForm.bindWithEvent(this,el));
-      }, this);
+      this.LSselect_search_form = $('LSselect_search_form');
+      var input = new Element('input');
+      input.setProperty('name','ajax');
+      input.setProperty('type','hidden');
+      input.injectInside(this.LSselect_search_form);
+      
+      this.LSselect_search_form.addEvent('submit',this.onSubmitSearchForm.bindWithEvent(this));
       
       this.LSselect_topDn = $('LSselect_topDn');
-      this.LSselect_topDn.addEvent('change',this.onChangeLSselect_topDn.bind(this));
+      if (this.LSselect_topDn) {
+        this.LSselect_topDn.addEvent('change',this.onChangeLSselect_topDn.bind(this));
+      }
+      this.LSselect_refresh_btn = $('LSselect_refresh_btn');
+      this.LSselect_refresh_btn.addEvent('click',this.onClickLSselect_refresh_btn.bind(this));
+      
+      this.initializeContent();
     },
     
     initializeContent: function() {
@@ -32,10 +39,8 @@ var LSselect = new Class({
           objectdn:   checkbox.value,
           objecttype: $('LSselect-object').getProperties('caption').caption
         };
-        LSdebug('plus');
       }
       else {
-        LSdebug('mois');
         var data = {
           template:   'LSselect',
           action:     'dropLSselectobject-item',
@@ -64,40 +69,50 @@ var LSselect = new Class({
     
     onChangePageClickComplete: function(responseText, responseXML) {
       varLSdefault.loadingImgHide(this.searchImgload);
-      $('content').setHTML(responseText);
+      this.content.setHTML(responseText);
       this.initializeContent();
     },
     
     onChangeLSselect_topDn: function() {
-      form = this.LSselect_topDn.getParent().getParent();
-      this.submitSearchForm(form);
+      this.submitSearchForm();
     },
     
-    onSubmitSearchForm: function(event, form) {
+    onSubmitSearchForm: function(event) {
       new Event(event).stop();
-      this.submitSearchForm(form);
+      this.submitSearchForm();
     },
     
-    submitSearchForm: function(form) {
+    submitSearchForm: function() {
       var imgload = varLSdefault.loadingImgDisplay($('title'),'inside');
-      form.send({
-        update: $('content'),
-        onComplete: this.onSubmitSearchFormComplete.bind(this,imgload)
+      this.LSselect_search_form.send({
+        update: this.content,
+        onComplete: this.onSubmitSearchFormComplete.bind(this,imgload),
+        evalScripts: true
       });
     },
     
     onSubmitSearchFormComplete: function(imgload) {
       varLSdefault.loadingImgHide(imgload);
+      if (typeof(debug_txt)!="undefined") {
+        var debug = Json.evaluate(debug_txt);
+        if (debug) {
+          varLSdefault.displayDebug(debug.toString());
+        }
+      }
+      if (typeof(error_txt)!="undefined") {
+        var error=Json.evaluate(error_txt);
+        if (error) {
+          varLSdefault.displayDebug(error.toString());
+        }
+      }
       this.initializeContent();
     },
-    
-    submit: function() {
-      var values = new Array();
-      $('content').getElements('input[name^=LSobjects_selected]').each(function(el) {
-        values.push(el.value);
-      },this);
-      return values;
-    }
-
 
+    onClickLSselect_refresh_btn: function() {
+      var input = new Element('input');
+      input.setProperty('name','refresh');
+      input.setProperty('type','hidden');
+      input.injectInside(this.LSselect_search_form);
+      this.submitSearchForm();
+    }
 });
index c663b43..6080f07 100644 (file)
@@ -49,6 +49,7 @@ var LSsession_login = new Class({
         if (data.list_topDn) {
           $('LSsession_topDn').getParent().setHTML(data.list_topDn);
           LSdebug($('LSsession_topDn').innerHTML);
+          $('LSsession_topDn_label').setHTML(data.levelLabel);
           $$('.loginform-level').each(function(el) {
             el.setStyle('display','block');
           });
index 2cfdac8..60d95f1 100644 (file)
@@ -22,8 +22,8 @@ var LSsmoothbox = new Class({
       this.pnav = new Element('p');
       this.pnav.setProperty('id','pnav-LSsmoothbox');
       
-      this.pnav.injectInside(this.win);
       this.frame.injectInside(this.win);      
+      this.pnav.injectInside(this.win);
       
       $$('a.LSsmoothbox').each(function(el) {
         el.addEvent('click',this.clickA.bindWithEvent(this,el));
index 65b64e1..313b8e8 100644 (file)
@@ -24,7 +24,10 @@ if (!isset($_ERRORS)) {
               $list = $GLOBALS['LSsession'] -> getSubDnLdapServerOptions($_SESSION['LSsession_topDn']);
               if (is_string($list)) {
                 $list="<select name='LSsession_topDn' id='LSsession_topDn'>".$list."</select>";
-                $data = array('list_topDn' => $list);
+                $data = array(
+                  'list_topDn' => $list,
+                  'levelLabel' => $GLOBALS['LSsession'] -> getLevelLabel()
+                );
               }
               else if (is_array($list)){
                 $data = array('LSerror' => $GLOBALS['LSerror']->getErrors());
index d885b33..97da284 100644 (file)
@@ -29,121 +29,253 @@ if($LSsession -> startLSsession()) {
   if (isset($_REQUEST['LSobject'])) {
     $LSobject = $_REQUEST['LSobject'];
     
-    if ( $GLOBALS['LSsession'] -> loadLSobject($_REQUEST['LSobject']) ) {
-        $objectList=array();
-        $object = new $_REQUEST['LSobject']();
-        
+    if ( $GLOBALS['LSsession'] -> loadLSobject($LSobject) ) {
+      $objectList=array();
+      $object = new $LSobject();
+      
+      $GLOBALS['Smarty']->assign('pagetitle',$object -> getLabel());
+      $GLOBALS['Smarty']->assign('LSobject_list_objectname',$object -> getLabel());
+      
+      if (isset($_SESSION['LSsession']['LSsearch'][$LSobject])) {
+        $filter = $_SESSION['LSsession']['LSsearch'][$LSobject]['filter'];
+        if (isCompatibleDNs($_SESSION['LSsession']['LSsearch'][$LSobject]['topDn'],$GLOBALS['LSsession'] -> topDn)) {
+          $topDn = $_SESSION['LSsession']['LSsearch'][$LSobject]['topDn'];
+          debug("topDn from cache : ".$topDn);
+        }
+        else {
+          $topDn = $object -> config['container_dn'].','.$GLOBALS['LSsession'] -> topDn;
+          debug("topDn from cache : ".$topDn);
+        }
+        $params = $_SESSION['LSsession']['LSsearch'][$LSobject]['params'];
+        $pattern = $_SESSION['LSsession']['LSsearch'][$LSobject]['pattern'];
+        $recur = $_SESSION['LSsession']['LSsearch'][$LSobject]['recur'];
+        $approx = $_SESSION['LSsession']['LSsearch'][$LSobject]['approx'];
+        $selectedTopDn = $_SESSION['LSsession']['LSsearch'][$LSobject]['selectedTopDn'];
+      }
+      else {
+        $filter = NULL;
+        $topDn = $object -> config['container_dn'].','.$GLOBALS['LSsession'] -> topDn;
+        $params = array('scope' => 'one');
+        $pattern = false;
+        $recur = false;
+        $approx = false;
+        $selectedTopDn = $GLOBALS['LSsession'] -> topDn;
+      }
+      
+      if (isset($_REQUEST['LSview_search_submit'])) {
+        if (isset($_REQUEST['LSview_pattern']) && ($_REQUEST['LSview_pattern']!=$pattern)) {
+          $pattern = $_REQUEST['LSview_pattern'];
+        }
+
+        $approx = (isset($_REQUEST['LSview_approx']));
         
-        if ( $_REQUEST['LSview_pattern']!='' ) {
+        if ($pattern && $pattern!='') {
           $filter='(|';
-          if ( isset($_REQUEST['LSview_approx']) ) {
+          if ($approx) {
             foreach ($object -> attrs as $attr_name => $attr_val) {
-              $filter.='('.$attr_name.'~='.$_REQUEST['LSview_pattern'].')';
+              $filter.='('.$attr_name.'~='.$pattern.')';
             }
           }
           else {
             foreach ($object -> attrs as $attr_name => $attr_val) {
-              $filter.='('.$attr_name.'=*'.$_REQUEST['LSview_pattern'].'*)';
-            }              
+              $filter.='('.$attr_name.'=*'.$pattern.'*)';
+            }
           }
           $filter.=')';
-          $GLOBALS['Smarty']->assign('LSobject_list_filter','filter='.urlencode($filter));
-        }
-        else if ($_REQUEST['filter']) {
-          $filter=urldecode($_REQUEST['filter']);
-          $GLOBALS['Smarty']->assign('LSobject_list_filter','filter='.$_REQUEST['filter']);
         }
         else {
-          $filter=NULL;
-          $GLOBALS['Smarty']->assign('LSobject_list_filter','');
+          $filter = NULL;
         }
-       
-       $topDn = $object -> config['container_dn'].','.$GLOBALS['LSsession'] -> topDn;
-       if(isset($_REQUEST['LSselect_topDn'])) {
-        if ($GLOBALS['LSsession'] -> validSubDnLdapServer($_REQUEST['LSselect_topDn'])) {
-          $topDn = $object -> config['container_dn'].','.$_REQUEST['LSselect_topDn'];
+        
+        if (isset($_REQUEST['LSview_recur'])) {
+          $recur = true;
+          $params['scope'] = 'sub';
+          if ($GLOBALS['LSsession'] -> validSubDnLdapServer($_REQUEST['LSselect_topDn'])) {
+            $topDn = $_REQUEST['LSselect_topDn'];
+            $selectedTopDn = $topDn;
+          }
+          else {
+            $topDn = $GLOBALS['LSsession'] -> topDn;
+            $selectedTopDn = $topDn;
+          }
         }
-       }
-       
-       $list=$object -> listObjects($filter,$topDn);
-        $nbObjects=count($list);
-
-        if ($nbObjects > NB_LSOBJECT_LIST_SELECT) {
-          if (isset($_GET['page'])) {
-            $list = array_slice($list, ($_GET['page']) * NB_LSOBJECT_LIST_SELECT, NB_LSOBJECT_LIST_SELECT);
-            $GLOBALS['Smarty']->assign('LSobject_list_currentpage',$_GET['page']);
-            $GLOBALS['Smarty']->assign('LSobject_list_nbpage',ceil($nbObjects / NB_LSOBJECT_LIST_SELECT));
+        else {
+          $recur = false;
+          $params['scope'] = 'one';
+          if ($GLOBALS['LSsession'] -> validSubDnLdapServer($_REQUEST['LSselect_topDn'])) {
+            $topDn = $object -> config['container_dn'].','.$_REQUEST['LSselect_topDn'];
+            $selectedTopDn = $_REQUEST['LSselect_topDn'];
           }
           else {
-            $list = array_slice($list, 0, NB_LSOBJECT_LIST_SELECT);
-            $GLOBALS['Smarty']->assign('LSobject_list_currentpage',0);
-            $GLOBALS['Smarty']->assign('LSobject_list_nbpage',ceil($nbObjects / NB_LSOBJECT_LIST_SELECT));
+            $topDn = $object -> config['container_dn'].','.$GLOBALS['LSsession'] -> topDn;
+            $selectedTopDn = $GLOBALS['LSsession'] -> topDn;
           }
         }
+      }
+      
+      // Sauvegarde en Session
+      $_SESSION['LSsession']['LSsearch'][$LSobject] = array(
+        'filter' => $filter,
+        'topDn' => $topDn,
+        'params' => $params,
+        'pattern' => $pattern,
+        'recur' => $recur,
+        'approx' => $approx,
+        'selectedTopDn' => $selectedTopDn
+      );
+
+      $GLOBALS['Smarty']->assign('LSview_search_pattern',$pattern);
+
+      if ($recur) {
+        $GLOBALS['Smarty']->assign('LSview_search_recur',true);
+      }
+      if ($approx) {
+        $GLOBALS['Smarty']->assign('LSview_search_approx',true);
+      }
+      $GLOBALS['Smarty']->assign('LSselect_topDn',$selectedTopDn);
+      
+      // Hidden fields
+      $GLOBALS['Smarty']->assign('LSview_search_hidden_fields',array(
+        'LSobject' => $LSobject,
+        'LSview_search_submit' => 1,
+        'ajax' => 1
+      ));
+      
+      // Hash de la recherche déterminer à partir des paramètres de la recherche
+      $hash = mhash (MHASH_MD5, 
+        print_r(
+          array(
+            'LSobject' => $LSobject,
+            'filter' => $filter,
+            'topDn' => $topDn,
+            'params' => $params
+          ),
+          true
+        )
+      );
+      
+      
+      
+      if (($GLOBALS['LSsession'] -> cacheSearch()) && isset($_SESSION['LSsession']['LSsearch'][$hash]) && (!isset($_REQUEST['refresh']))) {
+        // On affiche à partir du cache
+        $searchData=$_SESSION['LSsession']['LSsearch'][$hash];
+        debug('From cache');
+      }
+      else {
+        debug('Load');
+        $LSview_actions[] = array (
+          'label' => _('Rafraîchir'),
+          'url' => 'view.php?LSobject='.$LSobject.'&amp;refresh',
+          'action' => 'refresh'
+        );
+        
+        $list=$object -> listObjects($filter,$topDn,$params);
+        $nbObjects=count($list);
+        $searchData['LSobject_list_nbresult']=$nbObjects;
+
         $c=0;
+        
+        $subDnLdapServer = $GLOBALS['LSsession'] -> getSortSubDnLdapServer();
         foreach($list as $thisObject) {
-          $c++;
-          unset($actions);
-          if ($GLOBALS['LSsession'] -> canAccess($_REQUEST['LSobject'],$thisObject->getValue('dn'))) {
-            if ($c%2==0) {
-              $tr='bis';
-            }
-            else {
-              $tr='';
-            }
+          if ($GLOBALS['LSsession'] -> canAccess($LSobject,$thisObject->getValue('dn'))) {
+
+            $c++;
+            unset($actions);
             
-            if (is_array($_SESSION['LSselect'][$_REQUEST['LSobject']])) {
-              if(in_array($thisObject -> getValue('dn'),$_SESSION['LSselect'][$_REQUEST['LSobject']])) {
-                $select = true;
+            $subDn_name=false;
+            reset($subDnLdapServer);
+            while (!$subDn_name && next($subDnLdapServer)) {
+              if (isCompatibleDNs(key($subDnLdapServer),$thisObject -> getValue('dn'))) {
+                $subDn_name=current($subDnLdapServer);
               }
-              else {
-                $select = false;
-              }
-            }
-            else {
-              $select = false;
             }
             
             $objectList[]=array(
               'dn' => $thisObject->getValue('dn'),
               'displayValue' => $thisObject->getDisplayValue(),
-              'actions' => $actions,
-              'tr' => $tr,
-              'select' => $select
+              'subDn' => $subDn_name
             );
           }
+          else {
+            debug($thisObject->getValue('dn'));
+          }
         }
+        $searchData['objectList']=$objectList;
+        $searchData['LSview_actions'] = $LSview_actions;
+        if ($GLOBALS['LSsession'] -> cacheSearch()) {
+          $_SESSION['LSsession']['LSsearch'][$hash]=$searchData;
+        }
+      }
+      $GLOBALS['Smarty']->assign('LSobject_list_nbresult',$searchData['LSobject_list_nbresult']);
+      
+      // Pagination
+      if ($searchData['LSobject_list_nbresult'] > NB_LSOBJECT_LIST) {
+        if (isset($_REQUEST['page'])) {
+          $searchData['objectList'] = array_slice($searchData['objectList'], ($_REQUEST['page']) * NB_LSOBJECT_LIST, NB_LSOBJECT_LIST);
+          $GLOBALS['Smarty']->assign('LSobject_list_currentpage',$_REQUEST['page']);
+          
+        }
+        else {
+          $searchData['objectList'] = array_slice($searchData['objectList'], 0, NB_LSOBJECT_LIST);
+          $GLOBALS['Smarty']->assign('LSobject_list_currentpage',0);
+        }
+        $searchData['LSobject_list_nbpage']=ceil($searchData['LSobject_list_nbresult'] / NB_LSOBJECT_LIST);
+        $GLOBALS['Smarty']->assign('LSobject_list_nbpage',$searchData['LSobject_list_nbpage']);
+      }
+      
+      // Bis/Pas Bis + Select/Pas Select
+      for($i=0;$i<count($searchData['objectList']);$i++) {
+        if ($i%2==0) {
+          $tr='bis';
+        }
+        else {
+          $tr='';
+        }
+        $searchData['objectList'][$i]['tr']=$tr;
         
-        
-        $GLOBALS['LSsession'] -> addJSscript('LSview.js');
-        //$GLOBALS['LSsession'] -> addJSscript('LSselect.js');
-        
-        $GLOBALS['Smarty']->assign('LSview_search',array(
-          'action' => $_SERVER['PHP_SELF'],
-          'submit' => _('Rechercher'),
-          'LSobject' => $_REQUEST['LSobject']
-        ));
-        
-        $GLOBALS['Smarty']->assign('pagetitle',$object -> getLabel());
-        $GLOBALS['Smarty']->assign('LSobject_list_objectname',$object -> getLabel());
-        $GLOBALS['Smarty']->assign('LSobject_list_nbresult',$nbObjects);
-        $GLOBALS['Smarty']->assign('LSobject_list',$objectList);
-        $GLOBALS['Smarty']->assign('LSobject_list_objecttype',$_REQUEST['LSobject']);
-        if (isset($_REQUEST['ajax'])) {
-          $GLOBALS['LSsession'] -> setTemplate('select_table.tpl');
+        if (is_array($_SESSION['LSselect'][$LSobject])) {
+          if(in_array($searchData['objectList'][$i]['dn'],$_SESSION['LSselect'][$LSobject])) {
+            $select = true;
+          }
+          else {
+            $select = false;
+          }
         }
         else {
-          $GLOBALS['LSsession'] -> setTemplate('select.tpl');
+          $select = false;
         }
+        $searchData['objectList'][$i]['select']=$select;
+      }        
+      
+      $GLOBALS['LSsession'] -> addJSscript('LSview.js');
+      
+      $GLOBALS['Smarty']->assign('LSview_search',array(
+        'action' => $_SERVER['PHP_SELF'],
+        'submit' => _('Rechercher'),
+        'LSobject' => $LSobject
+      ));
+      
+      $GLOBALS['Smarty']->assign('LSview_search_recur_label',_('Recherche récursive'));
+      $GLOBALS['Smarty']->assign('LSview_search_approx_label',_('Recherche approximative'));
+
+      $GLOBALS['Smarty']->assign('LSobject_list_without_result_label',_("Cette recherche n'a retourné aucun résultat."));
+      $GLOBALS['Smarty']->assign('LSobject_list',$searchData['objectList']);
+      $GLOBALS['Smarty']->assign('LSobject_list_objecttype',$LSobject);
+      $GLOBALS['Smarty'] -> assign('LSview_actions',$searchData['LSview_actions']);
+      if (isset($_REQUEST['ajax'])) {
+        $GLOBALS['LSsession'] -> setTemplate('select_table.tpl');
+      }
+      else {
+        $GLOBALS['LSsession'] -> setTemplate('select.tpl');
+      }
+      $GLOBALS['LSsession'] -> ajaxDisplay = true;
     }
     else {
-      $GLOBALS['LSerror'] -> addErrorCode(1004,$_REQUEST['LSobject']);
-      $GLOBALS['LSsession'] -> setTemplate('blank.tpl');
+      $GLOBALS['LSerror'] -> addErrorCode(1004,$LSobject);
     }
   }
   else {
     $GLOBALS['LSerror'] -> addErrorCode(1012);
-    $GLOBALS['LSsession'] -> setTemplate('blank.tpl');
   }
 }
 else {
index cbc08b7..2e72e57 100644 (file)
@@ -68,13 +68,13 @@ hr {
 
 #LSsession_topDn {
   height:                   1.5em;
+  width:                    150px;
 }
 
 #LSsession_topDn_form {
-  float:                    left;
-  font-size:                0.7em;
+  width:                    150px;
+  margin:                   5px;
   color:                    #fff;
-  
 }
 
 #user_name {
@@ -108,11 +108,19 @@ td.LSobject-list {
   padding:            0.1em;
 }
 
+td.LSobject-list-without-result {
+  text-align:         center;
+}
+
 th.LSobject-list {
   background-color:   #52bce5;
   color:              #fff;
 }
 
+td.LSobject-list-subdn {
+  width:              15em;
+}
+
 tr.LSobject-list-bis {
   background-color:   #ecf8fd;
 }
@@ -233,9 +241,13 @@ div.LSselect_search {
   float:              right;
 }
 
+#LSview_search_param {
+  margin:             0px;
+  padding:            0px;
+}
+
 label.LSview_search {
   font-size:          0.6em;
-  display:            block;
 }
 
 input[type='text'].LSview_search {
@@ -276,3 +288,13 @@ form.LSselect_search {
 img.LSrelation-btn {
   margin-left:        0.5em;
 }
+
+.btn {
+  cursor:             pointer;
+}
+
+#LSview_subDnName {
+  float:              left;
+  margin:             0.5em;
+  margin-bottom:      0em;
+}
diff --git a/trunk/templates/images/refresh.png b/trunk/templates/images/refresh.png
new file mode 100644 (file)
index 0000000..ff803be
Binary files /dev/null and b/trunk/templates/images/refresh.png differ
index b46e80d..ca03218 100644 (file)
@@ -25,7 +25,7 @@
   <dd {$loginform_ldapserver_style}>
     <select name='LSsession_ldapserver' id='LSsession_ldapserver'>{html_options values=$loginform_ldapservers_index output=$loginform_ldapservers_name selected=$ldapServerId}</select>
   </dd>
-  <dt class='loginform-level' {$loginform_ldapserver_style}>{$loginform_label_level}</dt>
+  <dt class='loginform-level' id='LSsession_topDn_label' {$loginform_ldapserver_style}>{$loginform_label_level}</dt>
   <dd class='loginform-level' {$loginform_ldapserver_style}><select name='LSsession_topDn' id='LSsession_topDn'>{html_options values=$loginform_topdn_index output=$loginform_topdn_name selected=$topDn}</select></dd>
   <dt>{$loginform_label_user}</dt>
   <dd><input type='text' name='LSsession_user' /></dd>
index 66879e3..687d658 100644 (file)
@@ -1,21 +1,28 @@
-<div class='LSobject-select'>
+<div class='LSobject-select' id='LSobject-select-main-div'>
   <h1 id='title'>
     {$pagetitle}
   </h1>
-  <form action='{$LSview_search.action}' method='post' class='LSview_search LSselect_search'>
-    <input type='hidden' name='LSobject' value='{$LSview_search.LSobject}' />
+
+  <form action='{$LSview_search.action}' method='post' class='LSview_search LSselect_search btn' id='LSselect_search_form'>
+    {foreach from=$LSview_search_hidden_fields item=field_value key=field_name}
+      <input type='hidden' name='{$field_name}' value='{$field_value}' />
+    {/foreach}
     
-    {if $LSsession_topDn!=""}
+    {if $LSsession_subDn!=""}
       <label id='LSselect_topDn_label'>{$label_level}
         <select name='LSselect_topDn' id='LSselect_topDn'>
-          {html_options values=$LSsession_topDn_index output=$LSsession_topDn_name selected=$LSsession_topDn}
+          {html_options values=$LSsession_subDn_indexes output=$LSsession_subDn_names selected=$LSselect_subDn}
         </select>
       </label>
     {/if}
     <div class='LSselect_search'>
-      <input type='text' name='LSview_pattern' class='LSview_search' />
-      <input type='submit' value='{$LSview_search.submit}' class='LSview_search' />
-      <label class='LSview_search'>Recherche approximative : <input type='checkbox' name='LSview_approx' class='LSview_search' /></label>
+      <input type='text' name='LSview_pattern' class='LSview_search' value="{$LSview_search_pattern}"/>
+      <input type='submit' value='{$LSview_search.submit}' name='LSview_search_submit' class='LSview_search' />
+      <img src='templates/images/refresh.png' alt='{$_refresh}' title='{$_refresh}' id='LSselect_refresh_btn' />
+      <p id='LSview_search_param'>
+        <label class='LSview_search'>{$LSview_search_approx_label} : <input type='checkbox' name='LSview_approx' class='LSview_search' {if $LSview_search_approx!=''}checked{/if} /></label>
+        <label class='LSview_search'>{$LSview_search_recur_label} : <input type='checkbox' name='LSview_recur' class='LSview_search' {if $LSview_search_recur!=''}checked{/if}/></label>
+      </p>
     </div>
   </form>
   <div id='content'>
index 29b21d9..b845c7f 100644 (file)
@@ -2,12 +2,18 @@
   <tr class='LSobject-list'>
     <th class='LSobject-list LSobject-select-check'></th>
     <th class='LSobject-list'>{$LSobject_list_objectname}</th>
+    {if $label_level}<th class='LSobject-list'>{$label_level}</th>{/if}
   </tr>
 {foreach from=$LSobject_list item=object}
     <tr class='LSobject-list{if $object.tr=='bis'} LSobject-list-bis{/if}'>
         <td class='LSobject-list LSobject-select-check'><input type='checkbox' name='LSobjects_selected[]' value='{$object.dn}' {if $object.select}checked{/if} class='LSobject-select' /></td>
         <td class='LSobject-list LSobject-select-names'>{$object.displayValue}</td>
+        {if $label_level}<td class='LSobject-list LSobject-select-level'>{$object.subDn}</td>{/if}
     </tr>
+{foreachelse}
+    <tr class='LSobject-list'>
+      <td colspan='3' class='LSobject-list-without-result'>{$LSobject_list_without_result_label}</td>
+    </tr> 
 {/foreach}
 </table>
 {if $LSobject_list_nbpage}
@@ -21,3 +27,7 @@
   {/section}
   </p>
 {/if}
+<script type='text/javascript'>
+debug_txt = {$debug_txt};
+error_txt = {$error_txt};
+</script>
index 64a8747..ac7624b 100644 (file)
@@ -2,7 +2,7 @@
  "http://www.w3.org/TR/html4/loose.dtd">
 <html>
   <head>
-               <meta http-equiv="content-type" content="text/html; charset=UTF-8">
+    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
     <title>LdapSaisie{if $pagetitle != ''} - {$pagetitle}{/if}</title>
     <link rel="stylesheet" type="text/css" href="templates/css/base.css" title="Normal" />
     <link rel="stylesheet" type="text/css" href="templates/css/base_print.css" media='print' title="Normal" />
 
 <div id='main'>
   <div id='left'>
-    <img src='templates/images/logo.png' alt='Logo' id='logo'/>
+    <a href='index.php'><img src='templates/images/logo.png' alt='Logo' id='logo'/></a>
+    
+    {if $LSsession_subDn!=""}
+      <form action="index.php" method='post' id='LSsession_topDn_form'>
+        <label>{$label_level}
+          <a href="index.php?LSsession_topDn_refresh"><img src='templates/images/refresh.png' alt='{$_refresh}' title='{$_refresh}' /></a>
+          <select name='LSsession_topDn' id='LSsession_topDn'>
+            {html_options values=$LSsession_subDn_indexes output=$LSsession_subDn_names selected=$LSsession_subDn}
+          </select>
+        </label>
+      </form>
+    {/if}
     <ul class='menu'>
     {foreach from=$LSaccess item=item key=LSobject_type}
       <li class='menu'><a href='view.php?LSobject={$LSobject_type}' class='menu'>{$item.label}</a></li>
   <div id='right'>
     
     
-    {if $LSsession_topDn!=""}
-      <form action="index.php" method='post' id='LSsession_topDn_form'>
-        <label>{$label_level}
-          <select name='LSsession_topDn' id='LSsession_topDn'>
-            {html_options values=$LSsession_topDn_index output=$LSsession_topDn_name selected=$LSsession_topDn}
-          </select>
-        </label>
-      </form>
-    {/if}
+
     <p id='status'>
     Connecté en tant que <span id='user_name'>{$LSsession_username}</span></b> <a href='index.php?LSsession_logout'><img src='templates/images/logout.png' alt='Logout' title='Logout' /></a>
     </p>
index dc99720..7935072 100644 (file)
@@ -1,9 +1,14 @@
 {include file='top.tpl'}
       <form action='{$LSview_search.action}' method='post' class='LSview_search'>
-        <input type='hidden' name='LSobject' value='{$LSview_search.LSobject}' />
-        <input type='text' name='LSview_pattern' class='LSview_search' />
-        <input type='submit' value='{$LSview_search.submit}' class='LSview_search' />
-        <label class='LSview_search'>Recherche approximative : <input type='checkbox' name='LSview_approx' class='LSview_search' /></label>
+        {foreach from=$LSview_search_hidden_fields item=value key=name}
+          <input type='hidden' name='{$name}' value='{$value}' />
+        {/foreach}
+        <input type='text' name='LSview_pattern' class='LSview_search' value="{$LSview_search_pattern}"/>
+        <input type='submit' value='{$LSview_search.submit}' name='LSview_search_submit' class='LSview_search' />
+        <p id='LSview_search_param'>
+          <label class='LSview_search'>{$LSview_search_approx_label} : <input type='checkbox' name='LSview_approx' class='LSview_search' {if $LSview_search_approx!=''}checked{/if} /></label>
+          <label class='LSview_search'>{$LSview_search_recur_label} : <input type='checkbox' name='LSview_recur' class='LSview_search' {if $LSview_search_recur!=''}checked{/if}/></label>
+        </p>
       </form>
     <h1>
       {$pagetitle}
       {/foreach}
     </p>
     {/if}
-    <table class='LSobject-list'>
-      <tr class='LSobject-list'>
-        <th class='LSobject-list'>{$LSobject_list_objectname}</th>
-        <th class='LSobject-list'>{$_Actions}</th>
-      </tr>
-    {foreach from=$LSobject_list item=object}
+
+      <table class='LSobject-list'>
+        <tr class='LSobject-list'>
+          <th class='LSobject-list'>{$LSobject_list_objectname}</th>
+          {if $label_level}<th class='LSobject-list'>{$label_level}</th>{/if}
+          <th class='LSobject-list'>{$_Actions}</th>
+        </tr>
+        {foreach from=$LSobject_list item=object}
         <tr class='LSobject-list{if $object.tr=='bis'} LSobject-list-bis{/if}'>
             <td class='LSobject-list LSobject-list-names'><a href='view.php?LSobject={$LSobject_list_objecttype}&amp;dn={$object.dn}'  class='LSobject-list'>{$object.displayValue}</a> </td>
+            {if $label_level}<td class='LSobject-list LSobject-list-subdn'>{$object.subDn}</td>{/if}
             <td class='LSobject-list LSobject-list-actions'>
             {if $object.actions!=''}
             {foreach from=$object.actions item=item}
             {/if}
             </td>
         </tr>
-    {/foreach}
+        {foreachelse}
+          <tr class='LSobject-list'>
+            <td colspan='3' class='LSobject-list-without-result'>{$LSobject_list_without_result_label}</td>
+          </tr>  
+        {/foreach}
     </table>
     {if $LSobject_list_nbpage}
       <p class='LSobject-list-page'>
index bafdefb..c6fdc9c 100644 (file)
@@ -28,41 +28,44 @@ $GLOBALS['LSsession'] = new LSsession();
 if($LSsession -> startLSsession()) {
   if (isset($_REQUEST['LSobject'])) {
     $LSobject = $_REQUEST['LSobject'];
+    $dn = $_REQUEST['dn'];
     
     if ( $LSobject == 'SELF' ) {
-      $_REQUEST['LSobject'] = $GLOBALS['LSsession']-> LSuserObject -> getType();
-      $_REQUEST['dn'] = $GLOBALS['LSsession']-> LSuserObject -> getValue('dn');
+      $LSobject = $GLOBALS['LSsession']-> LSuserObject -> getType();
+      $dn = $GLOBALS['LSsession']-> LSuserObject -> getValue('dn');
     }
-    if ( $GLOBALS['LSsession'] -> loadLSobject($_REQUEST['LSobject']) ) {
-      if ( isset($_REQUEST['dn']) ) {
-        if ($GLOBALS['LSsession'] -> canAccess($_REQUEST['LSobject'],$_REQUEST['dn'])) {
-          if ( $GLOBALS['LSsession'] -> canEdit($_REQUEST['LSobject'],$_REQUEST['dn']) ) {
+    
+    if ( $GLOBALS['LSsession'] -> loadLSobject($LSobject) ) {
+      // Affichage d'un objet
+      if ( $dn!='' ) {
+        if ($GLOBALS['LSsession'] -> canAccess($LSobject,$dn)) {
+          if ( $GLOBALS['LSsession'] -> canEdit($LSobject,$dn) ) {
             $LSview_actions[] = array(
               'label' => _('Modifier'),
-              'url' =>'modify.php?LSobject='.$_REQUEST['LSobject'].'&amp;dn='.$_REQUEST['dn'],
+              'url' =>'modify.php?LSobject='.$LSobject.'&amp;dn='.$dn,
               'action' => 'modify'
             );
           }
           
-          if ($GLOBALS['LSsession'] -> canCreate($_REQUEST['LSobject'])) {
+          if ($GLOBALS['LSsession'] -> canCreate($LSobject)) {
             $LSview_actions[] = array(
               'label' => _('Copier'),
-              'url' =>'create.php?LSobject='.$_REQUEST['LSobject'].'&amp;load='.$_REQUEST['dn'],
+              'url' =>'create.php?LSobject='.$LSobject.'&amp;load='.$dn,
               'action' => 'copy'
             );
           }
           
-          if ($GLOBALS['LSsession'] -> canRemove($_REQUEST['LSobject'],$_REQUEST['dn'])) {
+          if ($GLOBALS['LSsession'] -> canRemove($LSobject,$dn)) {
             $LSview_actions[] = array(
               'label' => _('Supprimer'),
-              'url' => 'remove.php?LSobject='.$_REQUEST['LSobject'].'&amp;dn='.$_REQUEST['dn'],
+              'url' => 'remove.php?LSobject='.$LSobject.'&amp;dn='.$dn,
               'action' => 'delete'
             );
           }
           
-          if ($GLOBALS['LSsession']-> LSuserObject -> getValue('dn') != $_REQUEST['dn']) {
-            $object = new $_REQUEST['LSobject']();
-            $object -> loadData($_REQUEST['dn']);
+          if ($GLOBALS['LSsession']-> LSuserObject -> getValue('dn') != $dn) {
+            $object = new $LSobject();
+            $object -> loadData($dn);
             $GLOBALS['Smarty'] -> assign('pagetitle',$object -> getDisplayValue());
           }
           else {
@@ -134,135 +137,248 @@ if($LSsession -> startLSsession()) {
           $GLOBALS['LSerror'] -> addErrorCode(1011);
         }
       }
+      // Affichage d'une liste d'un type d'objet
       else {
         $objectList=array();
-        $object = new $_REQUEST['LSobject']();
+        $object = new $LSobject();
+        
         $GLOBALS['Smarty']->assign('pagetitle',$object -> getLabel());
         $GLOBALS['Smarty']->assign('LSobject_list_objectname',$object -> getLabel());
         
-        if ($GLOBALS['LSsession'] -> canCreate($_REQUEST['LSobject'])) {
-          $LSview_actions[] = array (
-            'label' => _('Nouveau'),
-            'url' => 'create.php?LSobject='.$_REQUEST['LSobject'],
-            'action' => 'create'
-          );
-          $canCopy=true;
-        }
-        
-        if ( $_REQUEST['LSview_pattern']!='' ) {
-          $filter='(|';
-          if ( isset($_REQUEST['LSview_approx']) ) {
-            foreach ($object -> attrs as $attr_name => $attr_val) {
-              $filter.='('.$attr_name.'~='.$_REQUEST['LSview_pattern'].')';
-            }
+        if (isset($_SESSION['LSsession']['LSsearch'][$LSobject])) {
+          $filter = $_SESSION['LSsession']['LSsearch'][$LSobject]['filter'];
+          $params = $_SESSION['LSsession']['LSsearch'][$LSobject]['params'];
+          $pattern = $_SESSION['LSsession']['LSsearch'][$LSobject]['pattern'];
+          $recur = $_SESSION['LSsession']['LSsearch'][$LSobject]['recur'];
+          if ($recur) {
+            $topDn = $GLOBALS['LSsession'] -> topDn;
           }
           else {
-            foreach ($object -> attrs as $attr_name => $attr_val) {
-              $filter.='('.$attr_name.'=*'.$_REQUEST['LSview_pattern'].'*)';
-            }              
+            $topDn = $object -> config['container_dn'].','.$GLOBALS['LSsession'] -> topDn;
           }
-          $filter.=')';
-          $GLOBALS['Smarty']->assign('LSobject_list_filter','filter='.urlencode($filter));
-        }
-        else if ($_REQUEST['filter']) {
-          $filter=urldecode($_REQUEST['filter']);
-          $GLOBALS['Smarty']->assign('LSobject_list_filter','filter='.$_REQUEST['filter']);
+          $approx = $_SESSION['LSsession']['LSsearch'][$LSobject]['approx'];
         }
         else {
-          $filter=NULL;
-          $GLOBALS['Smarty']->assign('LSobject_list_filter','');
+          $filter = NULL;
+          $topDn = $object -> config['container_dn'].','.$GLOBALS['LSsession'] -> topDn;
+          $params = array('scope' => 'one');
+          $pattern = false;
+          $recur = false;
+          $approx = false;
         }
-       
-       $topDn = $object -> config['container_dn'].','.$GLOBALS['LSsession'] -> topDn;
-       
-        $list=$object -> listObjects($filter,$topDn);
-        $nbObjects=count($list);
-        $GLOBALS['Smarty']->assign('LSobject_list_nbresult',$nbObjects);
-        if ($nbObjects > NB_LSOBJECT_LIST) {
-          if (isset($_REQUEST['page'])) {
-            $list = array_slice($list, ($_REQUEST['page']) * NB_LSOBJECT_LIST, NB_LSOBJECT_LIST);
-            $GLOBALS['Smarty']->assign('LSobject_list_currentpage',$_REQUEST['page']);
-            $GLOBALS['Smarty']->assign('LSobject_list_nbpage',ceil($nbObjects / NB_LSOBJECT_LIST));
+        
+        if (isset($_REQUEST['LSview_search_submit'])) {
+          if (isset($_REQUEST['LSview_pattern']) && ($_REQUEST['LSview_pattern']!=$pattern)) {
+            $pattern = $_REQUEST['LSview_pattern'];
+          }
+
+          $approx = (isset($_REQUEST['LSview_approx']));
+          
+          if ($pattern && $pattern!='') {
+            $filter='(|';
+            if ($approx) {
+              foreach ($object -> attrs as $attr_name => $attr_val) {
+                $filter.='('.$attr_name.'~='.$pattern.')';
+              }
+            }
+            else {
+              foreach ($object -> attrs as $attr_name => $attr_val) {
+                $filter.='('.$attr_name.'=*'.$pattern.'*)';
+              }
+            }
+            $filter.=')';
           }
           else {
-            $list = array_slice($list, 0, NB_LSOBJECT_LIST);
-            $GLOBALS['Smarty']->assign('LSobject_list_currentpage',0);
-            $GLOBALS['Smarty']->assign('LSobject_list_nbpage',ceil($nbObjects / NB_LSOBJECT_LIST));
+            $filter = NULL;
+          }
+          
+          if (isset($_REQUEST['LSview_recur'])) {
+            $recur = true;
+            $params['scope'] = 'sub';
+            $topDn = $GLOBALS['LSsession'] -> topDn;
+          }
+          else {
+            $recur = false;
+            $params['scope'] = 'one';
+            $topDn = $object -> config['container_dn'].','.$GLOBALS['LSsession'] -> topDn;
           }
         }
-        $c=0;
-        foreach($list as $thisObject) {
-          $c++;
-          unset($actions);
-          if ($GLOBALS['LSsession'] -> canAccess($_REQUEST['LSobject'],$thisObject->getValue('dn'))) {
-            $actions[] = array(
-              'label' => _('Voir'),
-              'url' =>'view.php?LSobject='.$_REQUEST['LSobject'].'&amp;dn='.$thisObject -> getValue('dn'),
-              'action' => 'view'
+        
+        // Sauvegarde en Session
+        $_SESSION['LSsession']['LSsearch'][$LSobject] = array(
+          'filter' => $filter,
+          'topDn' => $topDn,
+          'params' => $params,
+          'pattern' => $pattern,
+          'recur' => $recur,
+          'approx' => $approx
+        );
+
+        $GLOBALS['Smarty']->assign('LSview_search_pattern',$pattern);
+
+        if ($recur) {
+          $GLOBALS['Smarty']->assign('LSview_search_recur',true);
+        }
+        if ($approx) {
+          $GLOBALS['Smarty']->assign('LSview_search_approx',true);
+        }
+        
+        // Hidden fields
+        $GLOBALS['Smarty']->assign('LSview_search_hidden_fields',array(
+          'LSobject' => $LSobject,
+          'LSview_search_submit' => 1
+        ));
+        
+        // Hash de la recherche déterminer à partir des paramètres de la recherche
+        $hash = mhash (MHASH_MD5, 
+          print_r(
+            array(
+              'LSobject' => $LSobject,
+              'filter' => $filter,
+              'topDn' => $topDn,
+              'params' => $params
+            ),
+            true
+          )
+        );
+        
+        if (($GLOBALS['LSsession'] -> cacheSearch()) && isset($_SESSION['LSsession']['LSsearch'][$hash]) && (!isset($_REQUEST['refresh']))) {
+          // On affiche à partir du cache
+          $searchData=$_SESSION['LSsession']['LSsearch'][$hash];
+          debug('Recherche : From cache');
+        }
+        else {
+          debug('Recherche : Load');
+          if ($GLOBALS['LSsession'] -> canCreate($LSobject)) {
+            $LSview_actions[] = array (
+              'label' => _('Nouveau'),
+              'url' => 'create.php?LSobject='.$LSobject,
+              'action' => 'create'
             );
-            
-            if ($GLOBALS['LSsession'] -> canEdit($_REQUEST['LSobject'],$thisObject->getValue('dn'))) {
-              $actions[]=array(
-                'label' => _('Modifier'),
-                'url' => 'modify.php?LSobject='.$_REQUEST['LSobject'].'&amp;dn='.$thisObject->getValue('dn'),
-                'action' => 'modify'
-              );
-            }
-            
-            if ($canCopy) {
+            $canCopy=true;
+          }
+          $LSview_actions[] = array (
+            'label' => _('Rafraîchir'),
+            'url' => 'view.php?LSobject='.$LSobject.'&amp;refresh',
+            'action' => 'refresh'
+          );
+          
+          $list=$object -> listObjects($filter,$topDn,$params);
+          $nbObjects=count($list);
+          $searchData['LSobject_list_nbresult']=$nbObjects;
+
+          $c=0;
+          
+          $subDnLdapServer = $GLOBALS['LSsession'] -> getSortSubDnLdapServer();
+          foreach($list as $thisObject) {
+            if ($GLOBALS['LSsession'] -> canAccess($LSobject,$thisObject->getValue('dn'))) {
+              $subDn_name=false;
+              if ($subDnLdapServer) {
+                reset($subDnLdapServer);
+                while (!$subDn_name && next($subDnLdapServer)) {
+                  if (isCompatibleDNs(key($subDnLdapServer),$thisObject -> getValue('dn'))) {
+                    $subDn_name=current($subDnLdapServer);
+                  }
+                }
+              }
+              $c++;
+              unset($actions);
+              
               $actions[] = array(
-                'label' => _('Copier'),
-                'url' =>'create.php?LSobject='.$_REQUEST['LSobject'].'&amp;load='.$thisObject -> getValue('dn'),
-                'action' => 'copy'
+                'label' => _('Voir'),
+                'url' =>'view.php?LSobject='.$LSobject.'&amp;dn='.$thisObject -> getValue('dn'),
+                'action' => 'view'
               );
-            }
-            
-            if ($GLOBALS['LSsession'] -> canRemove($thisObject -> getType(),$thisObject -> getValue('dn'))) {
-              $actions[] = array (
-                'label' => _('Supprimer'),
-                'url' => 'remove.php?LSobject='.$_REQUEST['LSobject'].'&amp;dn='.$thisObject -> getValue('dn'),
-                'action' => 'delete'
+              
+              if ($GLOBALS['LSsession'] -> canEdit($LSobject,$thisObject->getValue('dn'))) {
+                $actions[]=array(
+                  'label' => _('Modifier'),
+                  'url' => 'modify.php?LSobject='.$LSobject.'&amp;dn='.$thisObject->getValue('dn'),
+                  'action' => 'modify'
+                );
+              }
+              
+              if ($canCopy) {
+                $actions[] = array(
+                  'label' => _('Copier'),
+                  'url' =>'create.php?LSobject='.$LSobject.'&amp;load='.$thisObject -> getValue('dn'),
+                  'action' => 'copy'
+                );
+              }
+              
+              if ($GLOBALS['LSsession'] -> canRemove($thisObject -> getType(),$thisObject -> getValue('dn'))) {
+                $actions[] = array (
+                  'label' => _('Supprimer'),
+                  'url' => 'remove.php?LSobject='.$LSobject.'&amp;dn='.$thisObject -> getValue('dn'),
+                  'action' => 'delete'
+                );
+              }
+              
+              if (count($objectList)%2==0) {
+                $tr='bis';
+              }
+              else {
+                $tr='';
+              }
+              
+              $objectList[]=array(
+                'dn' => $thisObject->getValue('dn'),
+                'displayValue' => $thisObject->getDisplayValue(),
+                'actions' => $actions,
+                'tr' => $tr,
+                'subDn' => $subDn_name
               );
             }
-            
-            if ($c%2==0) {
-              $tr='bis';
-            }
             else {
-              $tr='';
+              debug($thisObject->getValue('dn'));
             }
+          }
+          $searchData['objectList']=$objectList;
+          $searchData['LSview_actions'] = $LSview_actions;
+          if ($GLOBALS['LSsession'] -> cacheSearch()) {
+            $_SESSION['LSsession']['LSsearch'][$hash]=$searchData;
+          }
+        }
+        
+        $GLOBALS['Smarty']->assign('LSobject_list_nbresult',$searchData['LSobject_list_nbresult']);
+        
+        // Pagination
+        if ($searchData['LSobject_list_nbresult'] > NB_LSOBJECT_LIST) {
+          if (isset($_REQUEST['page'])) {
+            $searchData['objectList'] = array_slice($searchData['objectList'], ($_REQUEST['page']) * NB_LSOBJECT_LIST, NB_LSOBJECT_LIST);
+            $GLOBALS['Smarty']->assign('LSobject_list_currentpage',$_REQUEST['page']);
             
-            $objectList[]=array(
-              'dn' => $thisObject->getValue('dn'),
-              'displayValue' => $thisObject->getDisplayValue(),
-              'actions' => $actions,
-              'tr' => $tr
-            );
           }
           else {
-            debug($thisObject->getValue('dn'));
+            $searchData['objectList'] = array_slice($searchData['objectList'], 0, NB_LSOBJECT_LIST);
+            $GLOBALS['Smarty']->assign('LSobject_list_currentpage',0);
           }
+          $searchData['LSobject_list_nbpage']=ceil($searchData['LSobject_list_nbresult'] / NB_LSOBJECT_LIST);
+          $GLOBALS['Smarty']->assign('LSobject_list_nbpage',$searchData['LSobject_list_nbpage']);
         }
+        
         $GLOBALS['LSsession'] -> addJSscript('LSview.js');
-
         
         $GLOBALS['Smarty']->assign('LSview_search',array(
           'action' => $_SERVER['PHP_SELF'],
           'submit' => _('Rechercher'),
-          'LSobject' => $_REQUEST['LSobject']
+          'LSobject' => $LSobject
         ));
         
-        
+        $GLOBALS['Smarty']->assign('LSview_search_recur_label',_('Recherche récursive'));
+        $GLOBALS['Smarty']->assign('LSview_search_approx_label',_('Recherche approximative'));
+
+        $GLOBALS['Smarty']->assign('LSobject_list_without_result_label',_("Cette recherche n'a retourné aucun résultat."));
         $GLOBALS['Smarty']->assign('_Actions',_('Actions'));
         $GLOBALS['Smarty']->assign('_Modifier',_('Modifier'));
-        $GLOBALS['Smarty']->assign('LSobject_list',$objectList);
-        $GLOBALS['Smarty']->assign('LSobject_list_objecttype',$_REQUEST['LSobject']);
-        $GLOBALS['Smarty'] -> assign('LSview_actions',$LSview_actions);
+        $GLOBALS['Smarty']->assign('LSobject_list',$searchData['objectList']);
+        $GLOBALS['Smarty']->assign('LSobject_list_objecttype',$LSobject);
+        $GLOBALS['Smarty'] -> assign('LSview_actions',$searchData['LSview_actions']);
         $GLOBALS['LSsession'] -> setTemplate('viewList.tpl');
       }
     }
     else {
-      $GLOBALS['LSerror'] -> addErrorCode(1004,$_REQUEST['LSobject']);
+      $GLOBALS['LSerror'] -> addErrorCode(1004,$LSobject);
     }
   }
   else {