5e4fd85c8e9b849c4df60ea6d69bdf4b44e26a7e
[ldapsaisie.git] / trunk / includes / class / class.LSldapObject.php
1 <?php
2 /*******************************************************************************
3  * Copyright (C) 2007 Easter-eggs
4  * http://ldapsaisie.labs.libre-entreprise.org
5  *
6  * Author: See AUTHORS file in top-level directory.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version 2
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21 ******************************************************************************/
22
23 $GLOBALS['LSsession'] -> loadLSclass('LSattribute');
24
25 /**
26  * Base d'un objet ldap
27  *
28  * Cette classe définis la base de tout objet ldap géré par LdapSaisie
29  *
30  * @author Benjamin Renard <brenard@easter-eggs.com>
31  */
32 class LSldapObject { 
33   
34   var $config = array();
35   var $type_name;
36   var $attrs = array();
37   var $forms;
38   var $view;
39   var $dn=false;
40   var $other_values=array();
41   var $submitError=true;
42   var $_whoami=NULL;
43   
44   /**
45    * Constructeur
46    *
47    * Cette methode construit l'objet et définis la configuration.
48    * Elle lance la construction du tableau d'attributs représentés par un objet LSattribute.
49    *
50    * @author Benjamin Renard <brenard@easter-eggs.com>
51    *
52    * @param[in] $type_name [<b>required</b>] string Le nom du type de l'objet
53    * @param[in] $config array La configuration de l'objet
54    *
55    * @retval boolean true si l'objet a été construit, false sinon.
56    */ 
57   function LSldapObject($type_name,$config='auto') {
58     $this -> type_name = $type_name;
59     $this -> config = $config;
60     if($config=='auto') {
61       if(isset($GLOBALS['LSobjects'][$type_name])) {
62         $this -> config = $GLOBALS['LSobjects'][$type_name];
63       }
64       else {
65         $GLOBALS['LSerror'] -> addErrorCode(21);
66         return;
67       }
68     }
69     foreach($this -> config['attrs'] as $attr_name => $attr_config) {
70       if(!$this -> attrs[$attr_name]=new LSattribute($attr_name,$attr_config,$this)) {
71         return;
72       }
73     }
74     return true;
75   }
76   
77   /**
78    * Charge les données de l'objet
79    *
80    * Cette methode définis le DN de l'objet et charge les valeurs de attributs de l'objet
81    * à partir de l'annuaire.
82    *
83    * @author Benjamin Renard <brenard@easter-eggs.com>
84    *
85    * @param[in] $dn string Le DN de l'objet.
86    *
87    * @retval boolean true si la chargement a réussi, false sinon.
88    */ 
89   function loadData($dn) {
90     $this -> dn = $dn;
91     $data = $GLOBALS['LSldap'] -> getAttrs($dn);
92     if(!empty($data)) {
93       foreach($this -> attrs as $attr_name => $attr) {
94         if(!$this -> attrs[$attr_name] -> loadData($data[$attr_name]))
95           return;
96       }
97       return true;
98     }
99     return;
100   }
101   
102   /**
103    * Recharge les données de l'objet
104    *
105    * @author Benjamin Renard <brenard@easter-eggs.com>
106    *
107    * @retval boolean true si la rechargement a réussi, false sinon.
108    */ 
109   function reloadData() {
110     $data = $GLOBALS['LSldap'] -> getAttrs($this -> dn);
111     foreach($this -> attrs as $attr_name => $attr) {
112       if(!$this -> attrs[$attr_name] -> reloadData($data[$attr_name]))
113         return;
114     }
115     return true;
116   }
117   
118   /**
119    * Retourne le format d'affichage de l'objet
120    *
121    * @author Benjamin Renard <brenard@easter-eggs.com>
122    *
123    * @retval string Format d'affichage de l'objet.
124    */ 
125   function getDisplayAttributes() {
126     return $this -> config['select_display_attrs'];
127   }
128   
129   /**
130    * Retourne la valeur descriptive d'affichage de l'objet
131    * 
132    * Cette fonction retourne la valeur descriptive d'affichage de l'objet en fonction
133    * du format défini dans la configuration de l'objet ou spécifié en paramètre.
134    *
135    * @author Benjamin Renard <brenard@easter-eggs.com>
136    *
137    * @param[in] $spe [<i>optionnel</i>] string Format d'affichage de l'objet
138    *
139    * @retval string Valeur descriptive d'affichage de l'objet
140    */ 
141   function getDisplayValue($spe='') {
142     if ($spe=='') {
143       $spe = $this -> getDisplayAttributes();
144     }
145     return $this -> getFData($spe,&$this -> attrs,'getDisplayValue');
146   }
147   
148   /**
149    * Chaine formatée
150    * 
151    * Cette fonction retourne la valeur d'une chaine formatée en prennant les valeurs
152    * de l'objet.
153    *
154    * @author Benjamin Renard <brenard@easter-eggs.com>
155    *
156    * @param[in] $format string Format de la chaine
157    *
158    * @retval string Valeur d'une chaine formatée
159    */ 
160   function getFData($format) {
161     $format=getFData($format,$this,'getValue');
162     return $format;
163   }
164   
165   /**
166    * Construit un formulaire de l'objet
167    * 
168    * Cette méthode construit un formulaire LSform à partir de la configuration de l'objet
169    * et de chaque attribut.
170    *
171    * @param[in] $idForm [<b>required</b>] Identifiant du formulaire a créer
172    * @param[in] $load DN d'un objet similaire dont la valeur des attribut doit être chargé dans le formulaire.
173    *
174    * @author Benjamin Renard <brenard@easter-eggs.com>
175    *
176    * @retval LSform Le formulaire crée
177    */ 
178   function getForm($idForm,$load=NULL) {
179     $GLOBALS['LSsession'] -> loadLSclass('LSform');
180     $LSform = new LSform($this,$idForm);
181     $this -> forms[$idForm] = array($LSform,$load);
182     
183     if ($load) {
184       $type = $this -> getType();
185       $loadObject = new $type();
186       if (!$loadObject -> loadData($load)) {
187         $load=false;
188       }
189     }
190     
191     if ($load) {
192       foreach($this -> attrs as $attr_name => $attr) {
193         if(!$this -> attrs[$attr_name] -> addToForm($LSform,$idForm,$this,$loadObject -> getValue($attr_name))) {
194           $LSform -> can_validate = false;
195         }
196       }
197     }
198     else {
199       foreach($this -> attrs as $attr_name => $attr) {
200         if(!$this -> attrs[$attr_name] -> addToForm($LSform,$idForm,$this)) {
201           $LSform -> can_validate = false;
202         }
203       }      
204     }
205     return $LSform;
206   }
207   
208   /**
209    * Construit un formulaire de l'objet
210    * 
211    * Cette méthode construit un formulaire LSform à partir de la configuration de l'objet
212    * et de chaque attribut.
213    *
214    * @param[in] $idForm [<b>required</b>] Identifiant du formulaire a créer
215    * @param[in] $config Configuration spécifique pour le formulaire
216    *
217    * @author Benjamin Renard <brenard@easter-eggs.com>
218    *
219    * @retval LSform Le formulaire crée
220    */ 
221   function getView() {
222     $GLOBALS['LSsession'] -> loadLSclass('LSform');
223     $this -> view = new LSform($this,'view');
224     foreach($this -> attrs as $attr_name => $attr) {
225       $this -> attrs[$attr_name] -> addToView($this -> view);
226     }
227     $this -> view -> can_validate = false;
228     return $this -> view;
229   }  
230   
231   /**
232    * Rafraichis le formulaire de l'objet
233    * 
234    * Cette méthode recharge les données d'un formulaire LSform.
235    *
236    * @param[in] $idForm [<b>required</b>] Identifiant du formulaire a créer
237    *
238    * @author Benjamin Renard <brenard@easter-eggs.com>
239    *
240    * @retval boolean true sile formulaire a été rafraichis, false sinon
241    */ 
242   function refreshForm($idForm) {
243     $LSform = $this -> forms[$idForm][0];
244     foreach($this -> attrs as $attr_name => $attr) {
245       if(!$this -> attrs[$attr_name] -> refreshForm($LSform,$idForm)) {
246         return;
247       }
248     }
249     return true;
250   }
251   
252   /**
253    * Met à jour les données de l'objet et de l'entré de l'annuaire
254    * 
255    * Met à jour les données de l'objet à partir d'un retour d'un formulaire.
256    *
257    * @param[in] $idForm Identifiant du formulaire d'origine
258    *
259    * @author Benjamin Renard <brenard@easter-eggs.com>
260    *
261    * @retval boolean true si la mise à jour a réussi, false sinon
262    *
263    * @see validateAttrsData()
264    * @see submitChange()
265    */ 
266   function updateData($idForm=NULL) {
267     if($idForm!=NULL) {
268       if(isset($this -> forms[$idForm]))
269         $LSform = $this -> forms[$idForm][0];
270       else {
271         $GLOBALS['LSerror'] -> addErrorCode(22,$this -> getType());
272         return;
273       }
274     }
275     else {
276       if(count($this -> forms) > 0) {
277         reset($this -> forms);
278         $idForm = key($this -> forms);
279         $LSform = current($this -> forms);
280         $config = $LSform[1];
281         $LSform = $LSform[0];
282       }
283       else {
284         $GLOBALS['LSerror'] -> addErrorCode(23,$this -> getType());
285         return;
286       }
287     }
288     $new_data = $LSform -> exportValues();
289     foreach($new_data as $attr_name => $attr_val) {
290       if(isset($this -> attrs[$attr_name])) {
291         $this -> attrs[$attr_name] -> setUpdateData($attr_val);
292       }
293     }
294     if($this -> validateAttrsData($idForm)) {
295       debug("les données sont validées");
296       if(isset($this -> config['before_save'])) {
297         if(function_exists($this -> config['before_save'])) {
298           if(!$this -> config['before_save']($this)) {
299             $GLOBALS['LSerror'] -> addErrorCode(28,$this -> config['before_save']);
300             return;
301           }
302         }
303         else {
304           $GLOBALS['LSerror'] -> addErrorCode(27,$this -> config['before_save']);
305           return;
306         }
307       }
308       if ($this -> submitChange($idForm)) {
309         debug('Les modifications sont submitées');
310         $this -> submitError = false;
311         $this -> reloadData();
312         $this -> refreshForm($idForm);
313       }
314       else {
315         return;
316       }
317       if((isset($this -> config['after_save']))&&(!$this -> submitError)) {
318         if(function_exists($this -> config['after_save'])) {
319           if(!$this -> config['after_save']($this)) {
320             $GLOBALS['LSerror'] -> addErrorCode(30,$this -> config['after_save']);
321             return;
322           }
323         }
324         else {
325           $GLOBALS['LSerror'] -> addErrorCode(29,$this -> config['after_save']);
326           return;
327         }
328       }
329       return true;
330     }
331     else {
332       return;
333     }
334   }
335   
336   /**
337    * Valide les données retournées par un formulaire
338    *
339    * @param[in] $idForm Identifiant du formulaire d'origine
340    *
341    * @author Benjamin Renard <brenard@easter-eggs.com>
342    *
343    * @retval boolean true si les données sont valides, false sinon
344    */ 
345   function validateAttrsData($idForm) {
346     $LSform=$this -> forms[$idForm][0];
347     foreach($this -> attrs as $attr) {
348       if (!$attr -> isValidate()) {
349         if($attr -> isUpdate()) {
350           if (!$this -> validateAttrData($LSform, $attr)) {
351             return;
352           }
353         }
354         else if( ($attr -> getValue() == '') && ($attr -> isRequired()) ) { 
355           if ( $attr -> canBeGenerated()) {
356             if ($attr -> generateValue()) {
357               if (!$this -> validateAttrData($LSform, $attr)) {
358                 $GLOBALS['LSerror'] -> addErrorCode(48,$attr -> getLabel());
359                 return;
360               }
361             }
362             else {
363               $GLOBALS['LSerror'] -> addErrorCode(47,$attr -> getLabel());
364               return;
365             }
366           }
367           else {
368             $GLOBALS['LSerror'] -> addErrorCode(46,$attr -> getLabel());
369             return;
370           }
371
372         }
373       }
374     }
375     return true;
376   }
377
378    /**
379    * Valide les données d'un attribut
380    *
381    * @param[in] $LSForm Formulaire d'origine
382    * @param[in] &$attr Attribut à valider
383    *
384    * @author Benjamin Renard <brenard@easter-eggs.com>
385    *
386    * @retval boolean true si les données sont valides, false sinon
387    */
388   function validateAttrData(&$LSform,&$attr) {
389     $vconfig=$attr -> getValidateConfig();
390
391     $data=$attr -> getUpdateData();
392     if(!is_array($data)) {
393       $data=array($data);
394     }
395
396     // Validation des valeurs de l'attribut
397     if(is_array($vconfig)) {
398       foreach($vconfig as $test) {
399         // Définition du basedn par défaut
400         if (!isset($test['basedn'])) {
401           $test['basedn']=$GLOBALS['LSsession']->topDn;
402         }
403
404         // Définition du message d'erreur
405         if (!empty($test['msg'])) {
406           $msg_error=getFData($test['msg'],$this,'getValue');
407         }
408         else {
409           $msg_error=getFData(_("L'attribut %{attr} n'est pas valide."),$attr -> getLabel());
410         }
411         foreach($data as $val) {
412           // validation par check LDAP
413           if((isset($test['filter'])||isset($test['basedn']))&&(isset($test['result']))) {
414             $sparams=(isset($test['scope']))?array('scope' => $test['scope']):array();
415             $this -> other_values['val']=$val;
416             $sfilter_user=(isset($test['basedn']))?getFData($test['filter'],$this,'getValue'):NULL;
417             if(isset($test['object_type'])) {
418               $test_obj = new $test['object_type']();
419               $sfilter=$test_obj->getObjectFilter();
420               $sfilter='(&'.$sfilter;
421               if($sfilter_user[0]=='(') {
422                 $sfilter=$sfilter.$sfilter_user.')';
423               }
424               else {
425                 $sfilter=$sfilter.'('.$sfilter_user.'))';
426               }
427             }
428             else {
429               $sfilter=$sfilter_user;
430             }
431             $sbasedn=(isset($test['basedn']))?getFData($test['basedn'],$this,'getValue'):NULL;
432             $ret=$GLOBALS['LSldap'] -> getNumberResult ($sfilter,$sbasedn,$sparams);
433             if($test['result']==0) {
434               if($ret!=0) {
435                 $LSform -> setElementError($attr,$msg_error);
436                 return;
437               }
438             }
439             else {
440               if($ret<=0) {
441                 $LSform -> setElementError($attr,$msg_error);
442                 return;
443               }
444             }
445           }
446           // Validation par fonction externe
447           else if(isset($test['function'])) {
448             if (function_exists($test['function'])) {
449               if(!$test['function']($this)) {
450                 $LSform -> setElementError($attr,$msg_error);
451               return;
452               }
453             }
454             else {
455               $GLOBALS['LSerror'] -> addErrorCode(24,array('attr' => $attr->name,'obj' => $this->getType(),'func' => $test['function']));
456               return;
457             }
458           }
459           else {
460             $GLOBALS['LSerror'] -> addErrorCode(25,array('attr' => $attr->name,'obj' => $this->getType()));
461             return;
462           }
463         }
464       }
465     }
466     // Génération des valeurs des attributs dépendants
467     $dependsAttrs=$attr->getDependsAttrs();
468     if (!empty($dependsAttrs)) {
469       foreach($dependsAttrs as $dependAttr) {
470         if(!isset($this -> attrs[$dependAttr])){
471           $GLOBALS['LSerror'] -> addErrorCode(34,array('attr_depend' => $dependAttr, 'attr' => $attr -> getLabel()));
472           continue;
473         }
474         if($this -> attrs[$dependAttr] -> canBeGenerated()) {
475           if (!$this -> attrs[$dependAttr] -> generateValue()) {
476             $GLOBALS['LSerror'] -> addErrorCode(47,$this -> attrs[$dependAttr] -> getLabel());
477             return;
478           }
479         }
480         else {
481           $GLOBALS['LSerror'] -> addErrorCode(46,$this -> attrs[$dependAttr] -> getLabel());
482           return;
483         }
484       }
485     }
486
487     $attr -> validate();
488     unset($this -> other_values['val']);
489     return true;
490   }
491
492   /**
493    * Met à jour les données modifiés dans l'annuaire
494    *
495    * @param[in] $idForm Identifiant du formulaire d'origine
496    *
497    * @author Benjamin Renard <brenard@easter-eggs.com>
498    *
499    * @retval boolean true si la mise à jour a réussi, false sinon
500    */ 
501   function submitChange($idForm) {
502     $submitData=array();
503     foreach($this -> attrs as $attr) {
504       if(($attr -> isUpdate())&&($attr -> isValidate())) {
505         $submitData[$attr -> name] = $attr -> getUpdateData();
506       }
507     }
508     if(!empty($submitData)) {
509       $dn=$this -> getDn();
510       if($dn) {
511         $this -> dn=$dn;
512         debug($submitData);
513         return $GLOBALS['LSldap'] -> update($this -> getType(),$dn, $submitData);
514       }
515       else {
516         $GLOBALS['LSerror'] -> addErrorCode(33);
517         return;
518       }
519     }
520     else {
521       return true;
522     }
523   }
524   
525   /**
526    * Retourne les informations issus d'un DN
527    *
528    * @param[in] $dn Un DN.
529    *
530    * @author Benjamin Renard <brenard@easter-eggs.com>
531    *
532    * @retval array Tableau : 
533    *                  - [0] : le premier paramètre
534    *                  - [1] : les paramètres suivants
535    */ 
536   function getDnInfos($dn) {
537     $infos=ldap_explode_dn($dn,0);
538     if(!$infos)
539       return;
540     $first=true;
541     for($i=1;$i<$infos['count'];$i++)
542       if($first) {
543         $basedn.=$infos[$i];
544         $first=false;
545       }
546       else
547         $basedn.=','.$infos[$i];
548     return array($infos[0],$basedn);
549   }
550   
551   /**
552    * Retourne le filtre correpondants aux objetcClass de l'objet
553    *
554    * @author Benjamin Renard <brenard@easter-eggs.com>
555    *
556    * @retval string le filtre ldap correspondant au type de l'objet
557    */ 
558   function getObjectFilter() {
559     if(!isset($this -> config['objectclass'])) return;
560     foreach ($this -> config['objectclass'] as $class)
561       $filter.='(objectClass='.$class.')';
562     return $filter;
563   }
564   
565   /**
566    * Retourne une liste d'objet du même type.
567    *
568    * Effectue une recherche en fonction des paramètres passé et retourne un
569    * tableau d'objet correspond au resultat de la recherche.
570    *
571    * @author Benjamin Renard <brenard@easter-eggs.com>
572    *
573    * @param[in] $filter array (ou string) Filtre de recherche Ldap / Tableau de filtres de recherche
574    * @param[in] $basedn string DN de base pour la recherche
575    * @param[in] $params array Paramètres de recherche au format Net_LDAP2::search()
576    *
577    * @retval array Tableau d'objet correspondant au resultat de la recherche
578    */ 
579   function listObjects($filter='',$basedn=NULL,$params=array()) {
580     $retInfos=array();
581     $attrs=false;
582     $check_final_dn=false;
583
584     if(!is_array($filter))
585       $filter=array(array('filter' => $filter));
586     
587     $nbFilter=count($filter);
588
589     for($i=0;$i<$nbFilter;$i++) {
590       $new_attrs=array();
591       // Défintion des paramètres de base pour la recherche
592       $sbasedn=$basedn;
593       $sparams=$params;
594       $ret=array();
595       if (isset($filter[$i]['scope']))
596         $sparams["scope"]=$filter[$i]['scope'];
597       
598       // Definition des critères de recherche correspondant au type d'objet à lister
599       if(($nbFilter==1)||(!isset($filter[$i]['attr']))) {
600         // Filtre sur l'objet souhaité
601         $sfilter='(&';
602         $sfilter.=$this -> getObjectFilter();
603         $sfilter_end=')';
604         $check_final_dn=true;
605       }
606       // Initialisation des critères d'une recherche intermédiaire
607       else {
608         if(isset($filter[$i]['object_type'])) {
609           $obj_tmp=new $filter[$i]['object_type']();
610           $obj_filter=$obj_tmp->getObjectFilter();
611           $sfilter='(&'.$obj_filter;
612           $sfilter_end=')';
613         }
614         else {
615           $sfilter='';
616           $sfilter_end='';
617         }
618         if(isset($filter[$i]['scope'])) {
619           $sparams['scope']=$filter[$i]['scope'];
620         }
621         if(isset($filter[$i]['basedn'])) {
622           $sbasedn=$filter[$i]['basedn'];
623         }
624       }
625       // Dans le cas d'une recherche intermédiaire ou finale
626       if($attrs!=false) {
627         // Initialisation des variables
628         $ret_gen=array();
629         $new_attrs=array();
630         
631         // Pour tout les attributs retournés
632         for($ii=0;$ii<count($attrs);$ii++) {
633           $sfilter_for='';
634           // Définition du filtre de recherche à partir des paramètres utilisateurs et
635           // des paramètres de recherche de l'objet à listé (dans le cas d'une recherche finale
636           if((isset($filter[$i]['filter']))&&(!empty($filter[$i]['filter']))) {
637             $sfilter_user=getFData($filter[$i]['filter'],$attrs[$ii]);
638             if($sfilter_user[0]=='(')
639               $sfilter_for=$sfilter.$sfilter_user;
640             else
641               $sfilter_for=$sfilter.'('.$sfilter_user.')';
642           }
643           else {
644             $sfilter_for=$sfilter;
645           }
646           
647           if(isset($filter[$i]['basedn'])) {
648             $sbasedn=getFData($filter[$i]['basedn'],$attrs[$ii]);
649             if ((!$this -> isCompatibleDNs($sbasedn,$basedn))&&($check_final_dn)) continue;
650           }
651         
652           // Vérification de la compatibilité du basedn de la recherche et du basedn générale
653           // Finalisation du filtre
654           $sfilter_for.=$sfilter_end;
655         
656         
657           // Execution de la recherche
658           $ret=$GLOBALS['LSldap'] -> search ($sfilter_for,$sbasedn,$sparams);
659           
660           // Si il y un retour
661           if(isset($ret[0])) {
662             // si il ya une suite (recherche intermédiaire)
663             if($filter[$i]['attr']){
664               for($iii=0;$iii<count($ret);$iii++) {
665                 if(isset($ret[$iii]['attrs'][$filter[$i]['attr']])) {
666                   // cas de valeur multiple
667                   if(is_array($ret[$iii]['attrs'][$filter[$i]['attr']])) {
668                     foreach($ret[$iii]['attrs'][$filter[$i]['attr']] as $val_attr) {
669                       $new_attrs[]=$val_attr;
670                     }
671                   }
672                   // cas de valeur unique
673                   else {
674                     $new_attrs[]=$ret[$iii]['attrs'][$filter[$i]['attr']];
675                   }
676                 }
677               }
678             }
679             else {
680               // vérification de la compatibilité de la compatibilité du DN resultant
681               // et du basedn de recherche 
682               if (!$this -> isCompatibleDNs($ret[0]['dn'],$basedn))
683                 continue;
684               // ajout du DN au resultat finale
685               $ret_gen[]=$ret[0]['dn'];
686             }
687           }
688         }
689         // cas du dernier filtre
690         if(!empty($ret_gen)) {
691           // on quitte la boucle des filtres de la conf
692           $ret=$ret_gen;
693           break;
694         }
695         // dans le cas d'une suite prévu mais d'un retour nul de la précédente recherche
696         else if(empty($new_attrs)) {
697             // retour vide et arrêt de la recherche
698             $ret=array();
699             break;
700         }
701         else {
702           $attrs=$new_attrs;
703         }
704       }
705       // Dans le cas de la recherche initiale
706       else {
707         // Déclaration du filtre de recherche
708         if((isset($filter[$i]['filter']))&&(!empty($filter[$i]['filter']))) {
709           if($filter[$i]['filter'][0]=='(') {
710             $sfilter.=$filter[$i]['filter'];
711           }
712           else {
713             $sfilter.='('.$filter[$i]['filter'].')';
714           }
715         }
716         // fermeture du filtre
717         $sfilter.=$sfilter_end;
718         
719         // Lancement de la recherche
720         $ret=$GLOBALS['LSldap'] -> search ($sfilter,$sbasedn,$sparams);
721         
722         //Si filtre multiple => on recupère une liste d'attributs
723         if(isset($filter[$i]['attr'])) {
724           for($ii=0;$ii<count($ret);$ii++) {
725             if(isset($ret[$ii]['attrs'][$filter[$i]['attr']])) {
726               // cas de valeur multiple
727               if(is_array($ret[$ii]['attrs'][$filter[$i]['attr']])) {
728                 foreach($ret[$ii]['attrs'][$filter[$i]['attr']] as $val_attr) {
729                   $attrs[]=$val_attr;
730                 }
731               }
732               // cas de valeur unique
733               else {
734                 $attrs[]=$ret[$ii]['attrs'][$filter[$i]['attr']];
735               }
736             }
737           }
738           
739           // Si aucunne valeur n'est retournées
740           if(empty($attrs)){
741             // arrêt et retour à zéro
742             $ret=array();
743             break;
744           }
745         }
746         // Si recherche unique
747         else {
748           // préparation du retour finale
749           $ret_final=array();
750           foreach($ret as $obj)
751             $ret_final[]=$obj['dn'];
752           $ret=$ret_final;
753           break;
754         }
755       }
756     }
757     
758     // Création d'un tableau d'objet correspondant au valeur retourné
759     for($i=0;$i<count($ret);$i++) {
760       $retInfos[$i] = new $this -> type_name($this -> config);
761       $retInfos[$i] -> loadData($ret[$i]);
762     }
763     
764     return $retInfos;
765   }
766  
767   function searchObject($name,$basedn=NULL) {
768     $filter = $this -> config['rdn'].'='.$name; 
769     return $this -> listObjects($filter,$basedn); 
770   }
771
772   /**
773    * Retourne une valeur de l'objet
774    *
775    * Retourne une valeur en fonction du paramètre. Si la valeur est inconnue, la valeur retourné est ' '.
776    * tableau d'objet correspond au resultat de la recherche.
777    *
778    * Valeurs possibles :
779    * - 'dn' ou '%{dn} : DN de l'objet
780    * - [nom d'un attribut] : valeur de l'attribut
781    * - [clef de $this -> other_values] : valeur de $this -> other_values
782    *
783    * @author Benjamin Renard <brenard@easter-eggs.com>
784    *
785    * @param[in] $val string Le nom de la valeur demandée
786    *
787    * @retval mixed la valeur demandé ou ' ' si celle-ci est inconnue.
788    */ 
789   function getValue($val) {
790     if(($val=='dn')||($val=='%{dn}')) {
791       return $this -> dn;
792     }
793     else if(($val=='rdn')||($val=='%{rdn}')) {
794       return $this -> attrs[ $this -> config['rdn'] ] -> getValue();
795     }
796     else if(isset($this ->  attrs[$val])){
797       if (method_exists($this ->  attrs[$val],'getValue'))
798         return $this -> attrs[$val] -> getValue();
799       else
800         return ' ';
801     }
802     else if(isset($this -> other_values[$val])){
803       return $this -> other_values[$val];
804     }
805     else {
806       return ' ';
807     }
808   }
809
810   /**
811    * Retourn un tableau pour un select d'un objet du même type
812    * 
813    * @author Benjamin Renard <brenard@easter-eggs.com>
814    *
815    * @retval array('dn' => 'display')
816    */
817   function getSelectArray($topDn=NULL) {
818     $list = $this -> listObjects(NULL,$topDn);
819     $return=array();
820     foreach($list as $object) {
821       $return[$object -> getDn()] = $object -> getDisplayValue(); 
822     }
823     return $return;
824   }
825
826   /**
827    * Retourne le DN de l'objet
828    *
829    * Cette methode retourne le DN de l'objet. Si celui-ci n'existe pas, il le construit à partir de la 
830    * configuration de l'objet et la valeur de son attribut rdn.
831    *
832    * @author Benjamin Renard <brenard@easter-eggs.com>
833    *
834    * @retval string Le DN de l'objet
835    */   
836   function getDn() {
837     if($this -> dn) {
838       return $this -> dn;
839     }
840     else {
841       $rdn_attr=$this -> config['rdn'];
842       if( (isset($this -> config['rdn'])) && (isset($this -> attrs[$rdn_attr])) && (isset($this -> config['container_dn'])) && (isset($GLOBALS['LSsession']->topDn)) ) {
843         $rdn_val=$this -> attrs[$rdn_attr] -> getUpdateData();
844         if (!empty($rdn_val)) {
845           return $rdn_attr.'='.$rdn_val[0].','.$this -> config['container_dn'].','.$GLOBALS['LSsession']->topDn;
846         }
847         else {
848           $GLOBALS['LSerror'] -> addErrorCode(32,$this -> config['rdn']);
849           return;
850         }
851       }
852       else {
853         $GLOBALS['LSerror'] -> addErrorCode(31,$this -> getType());
854         return;
855       }
856     }
857   }
858
859   /**
860    * Retourne le type de l'objet
861    *
862    * @retval string Le type de l'objet ($this -> type_name)
863    */
864   function getType() {
865     return $this -> type_name;
866   }
867   
868   /**
869    * Retourne qui est l'utilisateur par rapport à cet object
870    *
871    * @retval string 'admin'/'self'/'user' pour Admin , l'utilisateur lui même ou un simple utilisateur
872    */
873   function whoami() {
874     if (!$this -> _whoami)
875       $this -> _whoami = $GLOBALS['LSsession'] -> whoami($this -> dn);
876     return $this -> _whoami;
877   }
878   
879   /**
880    * Retourne le label de l'objet
881    *
882    * @retval string Le label de l'objet ($this -> config['label'])
883    */
884   function getLabel() {
885     return $this -> config['label'];
886   }
887   
888   
889   /**
890    * Supprime l'objet dans l'annuaire
891    *
892    * @retval boolean True si l'objet à été supprimé, false sinon
893    */
894   function remove() {
895     return $GLOBALS['LSldap'] -> remove($this -> getDn());
896   }
897 }
898
899 ?>