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