LSldapObject : fix foreach error in getObjectKeyValueInRelation() if attribute is...
[ldapsaisie.git] / public_html / includes / class / class.LSrelation.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 class LSrelation {
24
25   private $obj = null;
26   private $relationName = null;
27   private $config = null;
28
29   public function LSrelation(&$obj,$relationName) {
30     $this -> obj =& $obj;
31     $this -> relationName = $relationName;
32     if (isset($obj->config['LSrelation'][$relationName]) && is_array($obj->config['LSrelation'][$relationName])) {
33       $this -> config = $obj->config['LSrelation'][$relationName];
34     }
35     else {
36       LSerror :: addErrorCode('LSrelations_02',array('relation' => $relationName,'LSobject' => $obj -> getType()));
37     }
38   }
39
40   public function exists(&$obj=null,$relationName=null) {
41     if ($obj && $relationName) {
42       return (isset($obj->config['LSrelation'][$relationName]) && is_array($obj->config['LSrelation'][$relationName]));
43     }
44     else {
45       return is_array($this -> config);
46     }
47   }
48
49   public function getName() {
50     return $this -> relationName;
51   }
52
53   public function canEdit() {
54     return LSsession :: relationCanEdit($this -> obj -> getValue('dn'),$this -> obj -> getType(),$this -> relationName);
55   }
56
57   public function canCreate() {
58     return LSsession :: canCreate($this -> config['LSobject']);
59   }
60
61
62   public function listRelatedObjects() {
63     if (LSsession :: loadLSobject($this -> config['LSobject'])) {
64       $objRel = new $this -> config['LSobject']();
65       if (isset($this -> config['list_function'])) {
66         if (method_exists($this -> config['LSobject'],$this -> config['list_function'])) {
67           return call_user_func_array(array($objRel, $this -> config['list_function']), array(&$this -> obj));
68         }
69         LSerror :: addErrorCode('LSrelations_01',array('function' => $this -> config['list_function'], 'action' =>  _('listing related objects'), 'relation' => $this -> relationName));
70         return False;
71       }
72       elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) {
73         return $objRel -> listObjectsInRelation($this -> obj, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> getLinkAttributeValues());
74       }
75       else {
76         LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('listing related objects')));
77       }
78     }
79     else {
80       LSerror :: addErrorCode('LSrelations_04',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject']));
81     }
82     return;
83   }
84
85   public function getLinkAttributeValues() {
86     if (isset($this -> config['linkAttributeOtherValues'])) {
87       $linkAttributeValues=$this -> config['linkAttributeOtherValues'];
88       $linkAttributeValues[]=$this -> config['linkAttributeValue'];
89       return $linkAttributeValues;
90     }
91     else {
92       return $this -> config['linkAttributeValue'];
93     }
94   }
95
96   public function getRelatedKeyValue() {
97     if (LSsession :: loadLSobject($this -> config['LSobject'])) {
98       $objRel = new $this -> config['LSobject']();
99       if (isset($this -> config['getkeyvalue_function'])) {
100         if (method_exists($this -> config['LSobject'],$this -> config['getkeyvalue_function'])) {
101           return call_user_func_array(array($objRel, $this -> config['getkeyvalue_function']), array(&$this -> obj));
102         }
103         LSerror :: addErrorCode('LSrelations_01',array('function' => $this -> config['getkeyvalue_function'], 'action' =>  _('getting key value'), 'relation' => $this -> relationName));
104       }
105       elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) {
106         return $objRel -> getObjectKeyValueInRelation($this -> obj, $this -> obj -> getType(), $this -> config['linkAttributeValue']);
107       }
108       else {
109         LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('getting key value')));
110       }
111     }
112     else {
113       LSerror :: addErrorCode('LSrelations_04',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject']));
114     }
115     return;
116   }
117
118   public function getRelatedEditableAttribute() {
119     if (isset($this -> config['canEdit_attribute'])) {
120       return $this -> config['canEdit_attribute'];
121     }
122     elseif (isset($this -> config['linkAttribute'])) {
123       return $this -> config['linkAttribute'];
124     }
125     return False;
126   }
127
128   public function canEditRelationWithObject($objRel) {
129     if (!$this -> canEdit()) return;
130     if (isset($this -> config['canEdit_function'])) {
131       if (method_exists($objRel,$this -> config['canEdit_function'])) {
132         return call_user_func(array($objRel, $this -> config['canEdit_function']));
133       }
134       LSerror :: addErrorCode('LSrelations_01',array('function' => $this -> config['canEdit_function'], 'action' =>  _('checking right on relation with specific object'), 'relation' => $this -> relationName));
135       return False;
136     }
137     elseif ($this -> getRelatedEditableAttribute()) {
138       return LSsession :: canEdit($objRel -> getType(),$objRel -> getDn(),$this -> getRelatedEditableAttribute());
139     }
140     else {
141       LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('checking right on relation with specific object')));
142     }
143   }
144
145   public function removeRelationWithObject($objRel) {
146     if (isset($this -> config['remove_function'])) {
147       if (method_exists($this -> config['LSobject'],$this -> config['remove_function'])) {
148         return call_user_func_array(array($objRel, $this -> config['remove_function']),array(&$this -> obj));
149       }
150       LSerror :: addErrorCode('LSrelations_01',array('function' => $this -> config['remove_function'], 'action' =>  _('deleting'), 'relation' => $this -> relationName));
151       return False;
152     }
153     elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) {
154       return $objRel -> deleteOneObjectInRelation($this -> obj, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> config['linkAttributeValue'], null, $this -> getLinkAttributeValues());
155     }
156     else {
157       LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('removing relation with specific object')));
158     }
159     return;
160   }
161
162   public function renameRelationWithObject($objRel,$oldKeyValue) {
163     if (isset($this -> config['rename_function'])) {
164       if (method_exists($objRel,$this -> config['rename_function'])) {
165         return call_user_func_array(array($objRel, $this -> config['rename_function']), array(&$this -> obj, $oldKeyValue));
166       }
167       LSerror :: addErrorCode('LSrelations_01',array('function' => $this -> config['rename_function'], 'action' =>  _('renaming'), 'relation' => $this -> relationName));
168       return False;
169     }
170     elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) {
171       return $objRel -> renameOneObjectInRelation($this -> obj, $oldKeyValue, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> config['linkAttributeValue']);
172     }
173     else {
174       LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('checking right on relation with specific object')));
175     }
176     return;
177   }
178
179   public function updateRelations($listDns) {
180     if (LSsession :: loadLSobject($this -> config['LSobject'])) {
181       $objRel = new $this -> config['LSobject']();
182       if (isset($this -> config['update_function'])) {
183         if (method_exists($objRel,$this -> config['update_function'])) {
184           return call_user_func_array(array($objRel, $this -> config['update_function']), array(&$this -> obj, $listDns));
185         }
186         LSerror :: addErrorCode('LSrelations_01',array('function' => $this -> config['update_function'], 'action' =>  _('updating'), 'relation' => $this -> relationName));
187       }
188       elseif (isset($this -> config['linkAttribute']) && isset($this -> config['linkAttributeValue'])) {
189         return $objRel -> updateObjectsInRelation($this -> obj, $listDns, $this -> config['linkAttribute'], $this -> obj -> getType(), $this -> config['linkAttributeValue'],null,$this -> getLinkAttributeValues());
190       }
191       else {
192         LSerror :: addErrorCode('LSrelations_05',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject'],'action' => _('updating relations')));
193       }
194     }
195     else {
196       LSerror :: addErrorCode('LSrelations_04',array('relation' => $this -> relationName,'LSobject' => $this -> config['LSobject']));
197     }
198     return;
199   }
200
201  /*
202   * Méthode chargeant les dépendances d'affichage
203   * 
204   * @retval void
205   */
206   public static function loadDependenciesDisplay() {
207     if (LSsession :: loadLSclass('LSselect')) {
208       LSselect :: loadDependenciesDisplay();
209     }
210     LSsession :: addJSscript('LSrelation.js');
211     LSsession :: addCssFile('LSrelation.css');
212     
213     LSsession :: addJSconfigParam('LSrelation_labels', array(
214       'close_confirm_text'      => _('Do you really want to delete'),
215       'close_confirm_title'     => _('Warning'), 
216       'close_confirm_validate'  => _('Delete')
217     ));
218   }
219   
220  /*
221   * Méthode chargeant les informations des LSrelations d'un objet et définissant
222   * les variables templates pour l'affichage dans une LSview.
223   * 
224   * @param[in] LSldapObject L'objet dont on cherche les LSrelations
225   * 
226   * @retval void
227   */ 
228   public static function displayInLSview($object) {
229     if (($object instanceof LSldapObject) && (is_array($object -> config['LSrelation']))) {
230       $LSrelations=array();
231       $LSrelations_JSparams=array();
232       foreach($object -> config['LSrelation'] as $relationName => $relationConf) {
233         if (LSsession :: relationCanAccess($object -> getValue('dn'),$object->getType(),$relationName)) {
234           $return=array(
235             'label' => __($relationConf['label']),
236             'LSobject' => $relationConf['LSobject']
237           );
238           
239           if (isset($relationConf['emptyText'])) {
240             $return['emptyText'] = __($relationConf['emptyText']);
241           }
242           else {
243             $return['emptyText'] = _('No object.');
244           }
245           
246           $id=rand();
247           $return['id']=$id;
248           $LSrelations_JSparams[$id]=array(
249             'emptyText' => $return['emptyText']
250           );
251           $_SESSION['LSrelation'][$id] = array(
252             'relationName' => $relationName,
253             'objectType' => $object -> getType(),
254             'objectDn' => $object -> getDn(),
255           );
256           $relation = new LSrelation($object, $relationName);
257
258           if ($relation -> canEdit()) {
259             $return['actions'][] = array(
260               'label' => _('Modify'),
261               'url' => 'select.php?LSobject='.$relationConf['LSobject'].'&amp;multiple=1'.($relation -> getRelatedEditableAttribute()?'&amp;editableAttr='.$relation -> getRelatedEditableAttribute():''),
262               'action' => 'modify'
263             );
264           }
265           if ($relation -> canCreate()) {
266              $return['actions'][] = array(
267               'label' => _('New'),
268               'url' => 'create.php?LSobject='.$relationConf['LSobject'].'&amp;LSrelation='.$relationName.'&amp;relatedLSobject='.$object->getType().'&amp;relatedLSobjectDN='.urlencode($object -> getValue('dn')),
269               'action' => 'create'
270             );
271           }
272
273           $list = $relation -> listRelatedObjects();
274           if (is_array($list)) {
275             foreach($list as $o) {
276               $return['objectList'][] = array(
277                 'text' => $o -> getDisplayName(NULL,true),
278                 'dn' => $o -> getDn(),
279                 'canEdit' => $relation -> canEditRelationWithObject($o)
280               );
281             }
282           }
283           else {
284             $return['objectList']=array();
285           }
286           $LSrelations[]=$return;
287         }
288       }
289       
290       self :: loadDependenciesDisplay();
291       LStemplate :: assign('LSrelations',$LSrelations);
292       LSsession :: addJSconfigParam('LSrelations',$LSrelations_JSparams);
293     }
294   }
295   
296   public static function ajax_refreshSession(&$return) {
297     if ((isset($_REQUEST['id'])) && (isset($_REQUEST['href'])) ) {
298       if (isset($_SESSION['LSrelation'][$_REQUEST['id']])) {
299         $conf = $_SESSION['LSrelation'][$_REQUEST['id']];
300         if (LSsession ::loadLSobject($conf['objectType'])) {
301           $object = new $conf['objectType']();
302           if (($object -> loadData($conf['objectDn'])) && (isset($object->config['LSrelation'][$conf['relationName']]))) {
303             $relation = new LSrelation($object, $conf['relationName']);
304             $LSobjectInRelation = $object->config['LSrelation'][$conf['relationName']]['LSobject'];
305             if ($relation -> canEdit()) {
306               $list = $relation -> listRelatedObjects();
307               $_SESSION['LSselect'][$LSobjectInRelation]=array();
308               if (is_array($list)) {
309                 foreach($list as $o) {
310                   $_SESSION['LSselect'][$LSobjectInRelation][] = $o -> getDn();
311                 }
312               }
313               $return = array(
314                 'href' => $_REQUEST['href'],
315                 'id' => $_REQUEST['id']
316               );
317             }
318             else {
319               LSerror :: addErrorCode('LSsession_11');
320             }
321           }
322           else {
323             LSerror :: addErrorCode('LSsession_12');
324           }
325         }
326         else {
327           LSerror :: addErrorCode('LSsession_12');
328         }
329       }
330       else {
331         LSerror :: addErrorCode('LSsession_12');
332       }
333     }
334   }
335   
336   public static function ajax_refreshList(&$data) {
337     if (isset($_REQUEST['id'])) {
338       if (isset($_SESSION['LSrelation'][$_REQUEST['id']])) {
339         $conf = $_SESSION['LSrelation'][$_REQUEST['id']];
340         if (LSsession ::loadLSobject($conf['objectType'])) {
341           $object = new $conf['objectType']();
342           if (($object -> loadData($conf['objectDn'])) && (isset($object->config['LSrelation'][$conf['relationName']]))) {
343             $relation = new LSrelation($object, $conf['relationName']);
344             $LSobjectInRelation = $object->config['LSrelation'][$conf['relationName']]['LSobject'];
345             $relationConf = $object->config['LSrelation'][$conf['relationName']];
346             if($relation -> updateRelations($_SESSION['LSselect'][$LSobjectInRelation])) {
347               $list = $relation -> listRelatedObjects();
348               if (is_array($list)&&(!empty($list))) {
349                 $data['html']="";
350                 foreach($list as $o) {
351                   if ($relation -> canEditRelationWithObject($o)) {
352                     $class=' LSrelation_editable';
353                   }
354                   else {
355                     $class='';
356                   }
357                   $data['html'].= "<li class='LSrelation'><a href='view.php?LSobject=$LSobjectInRelation&amp;dn=".urlencode($o -> getDn())."' class='LSrelation$class' id='LSrelation_".$_REQUEST['id']."_".$o -> getDn()."'>".$o -> getDisplayName(NULL,true)."</a></li>\n";
358                 }
359               }
360               else {
361                 if (isset($relationConf['emptyText'])) {
362                   $data['html'] = "<li>".__($relationConf['emptyText'])."</li>\n";
363                 }
364                 else {
365                   $data['html'] = "<li>"._('No object.')."</li>\n";
366                 }
367               }
368               $data['id'] = $_REQUEST['id'];
369             }
370             else {
371               LSerror :: addErrorCode('LSrelations_03',$relationName);
372             }
373           }
374           else {
375             LSerror :: addErrorCode('LSsession_12');
376           }
377         }
378         else {
379           LSerror :: addErrorCode('LSsession_12');
380         }
381       }
382       else {
383         LSerror :: addErrorCode('LSsession_12');
384       }
385     }
386   }
387   
388   public static function ajax_deleteByDn(&$data) {
389     if ((isset($_REQUEST['id'])) && (isset($_REQUEST['dn']))) {
390       if (isset($_SESSION['LSrelation'][$_REQUEST['id']])) {
391         $conf = $_SESSION['LSrelation'][$_REQUEST['id']];
392         if (LSsession ::loadLSobject($conf['objectType'])) {
393           $object = new $conf['objectType']();
394           if (($object -> loadData($conf['objectDn'])) && (isset($object->config['LSrelation'][$conf['relationName']]))) {
395             $relation = new LSrelation($object, $conf['relationName']);
396             if ($relation -> canEdit()) {
397               $list = $relation -> listRelatedObjects();
398               if (is_array($list)) {
399                 $ok=false;
400                 foreach($list as $o) {
401                   if($o -> getDn() == $_REQUEST['dn']) {
402                     if (!$relation -> canEditRelationWithObject($o)) {
403                       LSerror :: addErrorCode('LSsession_11');
404                       return;
405                     }
406                     if (!$relation -> removeRelationWithObject($o)) {
407                       LSerror :: addErrorCode('LSrelations_03',$conf['relationName']);
408                     }
409                     else {
410                       $ok = true;
411                     }
412                     break;
413                   }
414                 }
415                 if (!$ok) {
416                   LSdebug($_REQUEST['value']." introuvé parmi la liste");
417                   LSerror :: addErrorCode('LSrelations_03',$conf['relationName']);
418                 }
419                 else {
420                   $data=array(
421                     'dn' => $_REQUEST['dn'],
422                     'id' => $_REQUEST['id']
423                   );
424                 }
425               }
426               else {
427                 LSerror :: addErrorCode('LSrelations_03',$conf['relationName']);
428               }
429             }
430             else {
431               LSerror :: addErrorCode('LSsession_11');
432             }
433           }
434           else {
435             LSerror :: addErrorCode('LSsession_12');
436           }
437         }
438         else {
439           LSerror :: addErrorCode('LSsession_12');
440         }
441       }
442       else {
443         LSerror :: addErrorCode('LSsession_12');
444       }
445     }
446   }
447 }
448
449 /**
450  * Error Codes
451  **/
452 LSerror :: defineError('LSrelations_01',
453 _("LSrelation : The function %{function} for action '%{action}' on the relation %{relation} is unknown.")
454 );
455 LSerror :: defineError('LSrelations_02',
456 _("LSrelation : Relation %{relation} of object type %{LSobject} unknown.")
457 );
458 LSerror :: defineError('LSrelations_03',
459 _("LSrelation : Error during relation update of the relation %{relation}.")
460 );
461 LSerror :: defineError('LSrelations_04',
462 _("LSrelation : Object type %{LSobject} unknown (Relation : %{relation}).")
463 );
464 LSerror :: defineError('LSrelations_05',
465 _("LSrelation : Incomplete configuration for LSrelation %{relation} of object type %{LSobject} for action : %{action}.")
466 );
467 LSerror :: defineError('LSrelations_06',
468 _("LSrelation : Invalid editable attribute for LSrelation %{relation} with LSobject %{LSobject}.")
469 );