Code

Applied in_array strict patches from trunk
[gosa.git] / gosa-core / plugins / admin / departments / class_department.inc
1 <?php
2 /*
3  * This code is part of GOsa (http://www.gosa-project.org)
4  * Copyright (C) 2003-2008 GONICUS GmbH
5  *
6  * ID: $$Id$$
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
23 class department extends plugin
24 {
25     /* department attributes */
26     var $ou= "";
27     var $description= "";
28     var $base= "";
29     var $st= "";
30     var $l= "";
31     var $postalAddress= "";
32     var $businessCategory= "";
33     var $telephoneNumber= "";
34     var $facsimileTelephoneNumber= "";
35     var $is_administrational_unit= false;
36     var $gosaUnitTag= "";
37     var $view_logged = FALSE;
39     var $type ="organizationalUnit";
40     var $namingAttr = "ou";
42     /* Headpage attributes */
43     var $last_dep_sorting= "invalid";
44     var $departments= array();
45     var $must_be_tagged = false;
47     /* attribute list for save action */
48     var $attributes= array("ou", "description", "businessCategory", "st", "l", "postalAddress",
49             "telephoneNumber", "facsimileTelephoneNumber", "gosaUnitTag", "manager");
51     /* Do not append the structural object classes here, they are added dynamically in the constructor */
52     var $objectclasses= array("top", "gosaDepartment");
53     var $structuralOC = array("organizationalUnit");
55     var $initially_was_tagged = false;
56     var $orig_base = "";
57     var $orig_ou = "";
58     var $orig_dn = "";
59     var $baseSelector;
61     var $manager_enabled = FALSE;
62     var $manager_name ="";
63     var $manager ="";
65     var $is_root_dse = FALSE;
67     function department (&$config, $dn)
68     {
69         /* Add the default structural obejct class 'locality' if this is a new entry
70          */
71         $ldap = $config->get_ldap_link();
72         $ldap->cd($config->current['BASE']);
73         if($dn == "" || $dn == "new" || !$ldap->dn_exists($dn)){
74             $this->objectclasses = array_merge($this->structuralOC,$this->objectclasses);
75         }else{
76             $ldap->cat($dn, array("structuralObjectClass"));
77             $attrs= $ldap->fetch();
78             if(isset($attrs['structuralObjectClass']['count'])){
79                 for($i = 0 ; $i < $attrs['structuralObjectClass']['count'] ; $i++){
80                     $this->objectclasses[] = $attrs['structuralObjectClass'][$i];
81                 }
82             }else{
84                 /* Could not detect structural object class for this object, fall back to the default 'locality'
85                  */
86                 $this->objectclasses = array_merge($this->structuralOC,$this->objectclasses);
87             }
88         }
89         $this->objectclasses = array_unique($this->objectclasses);
91         plugin::plugin($config, $dn);
92         $this->is_account= TRUE;
93         $this->ui= get_userinfo();
94         $this->dn= $dn;
95         $this->orig_dn= $dn;
97         /* Save current naming attribuet 
98          */
99         $nA      = $this->namingAttr;
100         $orig_nA = "orig_".$nA;
101         $this->$orig_nA = $this->$nA;
103         $this->config= $config;
105         /* Set base */
106         if ($this->dn == "new"){
107             $ui= get_userinfo();
108             if(session::is_set('CurrentMainBase')){
109                 $this->base = session::get('CurrentMainBase');
110             }else{
111                 $this->base= dn2base($ui->dn);
112             }
113         } else {
114             $this->base= preg_replace ("/^[^,]+,/", "", $this->dn);
115         }
117         // Special handling for the rootDSE
118         if($this->dn == $this->config->current['BASE']){
119             $this->base = $this->dn;
120             $this->is_root_dse = TRUE;
121         }
123         $this->orig_base = $this->base;
125         /* Is administrational Unit? */
126         if ($dn != "new" && in_array_ics('gosaAdministrativeUnit', $this->attrs['objectClass'])){
127             $this->is_administrational_unit= true;
128             $this->initially_was_tagged = true;
129         }
131         /* Instanciate base selector */
132         $this->baseSelector= new baseSelector($this->get_allowed_bases(), $this->base);
133         $this->baseSelector->setSubmitButton(false);
134         $this->baseSelector->setHeight(300);
135         $this->baseSelector->update(true);
137         // If the 'manager' attribute is present in gosaDepartment allow to manage it.
138         $ldap = $this->config->get_ldap_link();
139         $ocs = $ldap->get_objectclasses();
140         if(isset($ocs['gosaDepartment']['MAY']) && in_array_strict('manager', $ocs['gosaDepartment']['MAY'])){
141             $this->manager_enabled = TRUE;
143             // Detect the managers name
144             $this->manager_name = "";
145             $ldap = $this->config->get_ldap_link();
146             if(!empty($this->manager)){
147                 $ldap->cat($this->manager, array('cn'));
148                 if($ldap->count()){
149                     $attrs = $ldap->fetch();
150                     $this->manager_name = $attrs['cn'][0];
151                 }else{
152                     $this->manager_name = "("._("Unknown")."!): ".$this->manager;
153                 }
154             }
155         }
156     }
158     function execute()
159     {
160         /* Call parent execute */
161         plugin::execute();
163         /* Log view */
164         if($this->is_account && !$this->view_logged){
165             $this->view_logged = TRUE;
166             new log("view","department/".get_class($this),$this->dn);
167         }
169         /* Reload departments */
170         $this->config->get_departments();
171         $this->config->make_idepartments();
172         $smarty= get_smarty();
174         // Clear manager attribute if requested
175         if(preg_match("/ removeManager/i", " ".implode(array_keys($_POST),' ')." ")){
176             $this->manager = "";
177             $this->manager_name = "";
178         }
180         // Allow to manager manager attribute
181         if($this->manager_enabled){
183             // Allow to select a new inetOrgPersion:manager
184             if(preg_match("/ editManager/i", " ".implode(array_keys($_POST),' ')." ")){
185                 $this->dialog = new singleUserSelect($this->config, get_userinfo());
186             }
187             if($this->dialog && count($this->dialog->detectPostActions())){
188                 $users = $this->dialog->detectPostActions();
189                 if(isset($users['action']) && $users['action'] =='userSelected' && isset($users['targets']) && count($users['targets'])){
191                     $headpage = $this->dialog->getHeadpage();
192                     $dn = $users['targets'][0];
193                     $attrs = $headpage->getEntry($dn);
194                     $this->manager = $dn;
195                     $this->manager_name = $attrs['cn'][0];
196                     $this->dialog = NULL;
197                 }
198             }
199             if(isset($_POST['add_users_cancel'])){
200                 $this->dialog = NULL;
201             }
202             if($this->dialog) return($this->dialog->execute());
203         }
204         $smarty->assign("manager",$this->manager);
205         $smarty->assign("manager_name", set_post($this->manager_name));
206         $smarty->assign("manager_enabled",$this->manager_enabled);
209         $tmp = $this->plInfo();
210         foreach($tmp['plProvidedAcls'] as $name => $translation){
211             $smarty->assign($name."ACL",$this->getacl($name));
212         }
214         /* Hide base selector, if this object represents the base itself 
215          */
216         $smarty->assign("is_root_dse", $this->is_root_dse);
217         if($this->is_root_dse){
218             $nA = $this->namingAttr."ACL";
219             $smarty->assign($nA,$this->getacl($this->namingAttr,TRUE));
220         }
222         /* Hide all departments, that are subtrees of this department */
223         $bases = $this->get_allowed_bases();
224         if(($this->dn == "new")||($this->dn == "")){
225             $tmp = $bases;
226         }else{
227             $tmp        = array();      
228             foreach($bases as $dn=>$base){
229                 /* Only attach departments which are not a subtree of this one */
230                 if(!preg_match("/".preg_quote($this->dn)."/",$dn)){
231                     $tmp[$dn]=$base;
232                 }
233             }
234         }
235         $this->baseSelector->setBases($tmp);
236         $this->baseSelector->update(TRUE);
238         foreach ($this->attributes as $val){
239             $smarty->assign("$val", set_post($this->$val));
240         }
241         $smarty->assign("base", $this->baseSelector->render());
243         /* Set admin unit flag */
244         if ($this->is_administrational_unit) {
245             $smarty->assign("gosaUnitTag", "checked");
246         } else {
247             $smarty->assign("gosaUnitTag", "");
248         }
250         $smarty->assign("dep_type",$this->type);
253         $dep_types = departmentManagement::get_support_departments();
254         $tpl ="";
255         foreach($dep_types as $key => $data){
256             if($data['OC'] == $this->type){
257                 $tpl = $data['TPL'];
258                 break;
259             }
260         }
261         if($tpl == "") {
262             trigger_error("No template specified for container type '".$this->type."', please update epartmentManagement::get_support_departments().");
263             $tpl = "generic.tpl";
264         }
265         return($smarty->fetch (get_template_path($tpl, TRUE)));
266     }
268     function clear_fields()
269     {
270         $this->dn   = "";
271         $this->base = "";
273         foreach ($this->attributes as $val){
274             $this->$val= "";
275         }
276     }
278     function remove_from_parent()
279     {
280         $ldap= $this->config->get_ldap_link();
281         $ldap->cd ($this->dn);
282         $ldap->rmdir_recursive($this->dn);
283         new log("remove","department/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
284         if (!$ldap->success()){
285             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
286         }
288         /* Optionally execute a command after we're done */
289         $this->handle_post_events('remove');
290     }
292     function must_be_tagged()
293     {
294         return $this->must_be_tagged;
295     }
297     /* Save data to object */
298     function save_object()
299     {   
300         if (isset($_POST['dep_generic_posted'])){
302             $nA = $this->namingAttr;
303             $old_nA = $this->$nA;
307             /* Create a base backup and reset the
308                base directly after calling plugin::save_object();
309                Base will be set seperatly a few lines below */
310             $base_tmp = $this->base;
311             plugin::save_object();
312             $this->base = $base_tmp;
314             /* Refresh base */
315             if ($this->acl_is_moveable($this->base)){
316                 if (!$this->baseSelector->update()) {
317                     msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
318                 }
319                 if ($this->base != $this->baseSelector->getBase()) {
320                     $this->base= $this->baseSelector->getBase();
321                     $this->is_modified= TRUE;
322                 }
323             }
326             /* Save tagging flag */
327             if ($this->acl_is_writeable("gosaUnitTag")){
328                 if (isset($_POST['is_administrational_unit'])){
329                     $this->is_administrational_unit= true;
330                 } else {
331                     $this->is_administrational_unit= false;
332                 }
333             }
335             /* If this is the root directory service entry then avoid
336                changing the naming attribute of this entry.
337              */
338             if($this->dn == $this->config->current['BASE']){
339                 $this->$nA = $old_nA;
340             }
341         }
342     }
345     /* Check values */
346     function check()
347     {
348         /* Call common method to give check the hook */
349         $message= plugin::check();
351         /* Check for presence of this department */
352         $ldap= $this->config->get_ldap_link();
353         $ldap->ls ("(&(ou=".$this->ou.")(objectClass=organizationalUnit))", $this->base, array('dn'));
354         if ($this->orig_dn == "new" && $ldap->count()){
355             $message[]= msgPool::duplicated(_("Name"));
356         } elseif ($this->orig_dn != $this->dn && $ldap->count()){
357             $message[]= msgPool::duplicated(_("Name"));
358         }
360         /* All required fields are set? */
361         if ($this->ou == ""){
362             $message[]= msgPool::required(_("Name"));
363         }
364         if ($this->description == ""){
365             $message[]= msgPool::required(_("Description"));
366         }
368         if(tests::is_department_name_reserved($this->ou,$this->base)){
369             $message[]= msgPool::reserved(_("Name"));
370         }
372         if (preg_match ('/[#+:=>\\\\\/]/', $this->ou)){
373             $message[]= msgPool::invalid(_("Name"), $this->ou, "/[^#+:=>\\\\\/]/");
374         }
375         if (!tests::is_phone_nr($this->telephoneNumber)){
376             $message[]= msgPool::invalid(_("Phone"), $this->telephoneNumber, "/[\/0-9 ()+*-]/");
377         }
378         if (!tests::is_phone_nr($this->facsimileTelephoneNumber)){
379             $message[]= msgPool::invalid(_("Fax"), $this->facsimileTelephoneNumber, "/[\/0-9 ()+*-]/");
380         }
382         // Check if a wrong base was supplied
383         if(!$this->baseSelector->checkLastBaseUpdate()){
384             $message[]= msgPool::check_base();;
385         }
387         /* Check if we are allowed to create or move this object
388          */
389         if($this->orig_dn == "new" && !$this->acl_is_createable($this->base)){
390             $message[] = msgPool::permCreate();
391         }elseif($this->orig_dn != "new" && $this->base != $this->orig_base && !$this->acl_is_moveable($this->base)){
392             $message[] = msgPool::permMove();
393         }
395         return $message;
396     }
399     /* Save to LDAP */
400     function save()
401     {
402         $ldap= $this->config->get_ldap_link();
404         /* Ensure that ou is saved too, it is required by objectClass gosaDepartment 
405          */
406         $nA = $this->namingAttr;
407         $this->ou = $this->$nA;
409         /* Add tag objects if needed */
410         if ($this->is_administrational_unit){
412             /* If this wasn't tagged before add oc an reset unit tag */
413             if(!$this->initially_was_tagged){
414                 $this->objectclasses[]= "gosaAdministrativeUnit";
415                 $this->gosaUnitTag= "";
417                 /* It seams that this method is called twice, 
418                    set this to true. to avoid adding this oc twice */
419                 $this->initially_was_tagged = true;
420             }
422             if ($this->gosaUnitTag == ""){
424                 /* It's unlikely, but check if already used... */
425                 $try= 5;
426                 $ldap->cd($this->config->current['BASE']);
427                 while ($try--){
429                     /* Generate microtime stamp as tag */
430                     list($usec, $sec)= explode(" ", microtime());
431                     $time_stamp= preg_replace("/\./", "", $sec.$usec);
433                     $ldap->search("(&(objectClass=gosaAdministrativeUnit)(gosaUnitTag=$time_stamp))",array("gosaUnitTag"));
434                     if ($ldap->count() == 0){
435                         break;
436                     }
437                 }
438                 if($try == 0) {
439                     msg_dialog::display(_("Fatal error"), _("Cannot find an unused tag for this administrative unit!"), WARNING_DIALOG);
440                     return;
441                 }
442                 $this->gosaUnitTag= preg_replace("/\./", "", $sec.$usec);
443             }
444         }
445         $this->skipTagging = TRUE;
446         plugin::save();
448         /* Remove tag information if needed */
449         if (!$this->is_administrational_unit && $this->initially_was_tagged){
450             $tmp= array();
452             /* Remove gosaAdministrativeUnit from this plugin */
453             foreach($this->attrs['objectClass'] as $oc){
454                 if (preg_match("/^gosaAdministrativeUnitTag$/i", $oc)){
455                     continue;
456                 }
457                 if (!preg_match("/^gosaAdministrativeUnit$/i", $oc)){
458                     $tmp[]= $oc;
459                 }
460             }
461             $this->attrs['objectClass']= $tmp;
462             $this->attrs['gosaUnitTag']= array();
463             $this->gosaUnitTag = "";
464         }
467         /* Write back to ldap */
468         $ldap->cat($this->dn, array('dn'));
469         $ldap->cd($this->dn);
471         if ($ldap->count()){
472             $this->cleanup();
473             $ldap->modify ($this->attrs); 
474             new log("modify","department/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
475             $this->handle_post_events('modify');
476         } else {
477             $ldap->add($this->attrs);
478             $this->handle_post_events('add');
479             new log("create","department/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
480         }
481         if (!$ldap->success()){
482             msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, 0, get_class()));
483         }
485         /* The parameter forces only to set must_be_tagged, and don't touch any objects 
486            This will be done later */
487         $this->tag_objects(true);
488         return(false);
489     }
492     /* Tag objects to have the gosaAdministrativeUnitTag */
493     function tag_objects($OnlySetTagFlag = false)
494     {
495         if(!$OnlySetTagFlag){
496             $smarty= get_smarty();
497             /* Print out html introduction */
498             echo '  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
499                 <html>
500                 <head>
501                 <title></title>
502                 <style type="text/css">@import url("themes/default/style.css");</style>
503                 <script language="javascript" src="include/focus.js" type="text/javascript"></script>
504                 </head>
505                 <body style="background: none; margin:4px;" id="body" >
506                 ';
507             echo "<h3>".sprintf(_("Tagging '%s'."),"<i>".LDAP::fix($this->dn)."</i>")."</h3>";
508         }
510         $add= $this->is_administrational_unit;
511         $len= strlen($this->dn);
512         $ldap= $this->config->get_ldap_link();
513         $ldap->cd($this->dn);
514         if ($add){
515             $ldap->search('(!(&(objectClass=gosaAdministrativeUnitTag)(gosaUnitTag='.
516                                 $this->gosaUnitTag.')))', array('dn'));
517         } else {
518             $ldap->search('objectClass=gosaAdministrativeUnitTag', array('dn'));
519         }
521         $objects = array();
522         while ($attrs= $ldap->fetch()){
523             $objects[] = $attrs;
524         }
525         foreach($objects as $attrs){
527             /* Skip self */
528             if ($attrs['dn'] == $this->dn){
529                 continue;
530             }
532             /* Check for confilicting administrative units */
533             $fix= true;
534             foreach ($this->config->adepartments as $key => $tag){
535                 /* This one is shorter than our dn, its not relevant... */
536                 if ($len >= strlen($key)){
537                     continue;
538                 }
540                 /* This one matches with the latter part. Break and don't fix this entry */
541                 if (preg_match('/(^|,)'.preg_quote($key, '/').'$/', $attrs['dn'])){
542                     $fix= false;
543                     break;
544                 }
545             }
547             /* Fix entry if needed */
548             if ($fix){
549                 if($OnlySetTagFlag){
550                     $this->must_be_tagged =true;
551                     return;
552                 }
553                 $this->handle_object_tagging($attrs['dn'], $this->gosaUnitTag, TRUE );
554                 echo "<script language=\"javascript\" type=\"text/javascript\">scrollDown2();</script>" ;
555             }
556         }
558         if(!$OnlySetTagFlag){
559             $this->must_be_tagged = FALSE;
560             echo '<hr>';
561             echo "<div style='width:100%;text-align:right;'>".
562                 "<form name='form' method='post' action='?plug=".$_GET['plug']."' target='_parent'>".
563                 "<br>".
564                 "<input type='submit' name='back' value='"._("Continue")."'>".
565                 "<input type='hidden' name='php_c_check' value='1'>".
566                 "</form>".
567                 "</div>";
568             echo "<script language=\"javascript\" type=\"text/javascript\">scrollDown2();</script>" ;
569         }
570     }
573     /* Move/Rename complete trees */
574     function recursive_move($src_dn, $dst_dn,$force = false)
575     {
576         /* Print header to have styles included */
577         $smarty= get_smarty();
579         echo '  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
580             <html>
581             <head>
582             <title></title>
583             <style type="text/css">@import url("themes/default/style.css");</style>
584             <script language="javascript" src="include/focus.js" type="text/javascript"></script>
585             </head>
586             <body style="background: none; margin:4px;" id="body" >
587             ';
588         echo "<h3>".sprintf(_("Moving '%s' to '%s'"),"<i>".LDAP::fix($src_dn)."</i>","<i>".LDAP::fix($dst_dn)."</i>")."</h3>";
591         /* Check if the destination entry exists */
592         $ldap= $this->config->get_ldap_link();
594         /* Check if destination exists - abort */
595         $ldap->cat($dst_dn, array('dn'));
596         if ($ldap->fetch()){
597             trigger_error("Recursive_move ".LDAP::fix($dst_dn)." already exists.",
598                     E_USER_WARNING);
599             echo sprintf("Recursive_move: '%s' already exists", LDAP::fix($dst_dn))."<br>"; 
600             return (FALSE);
601         }
603         /* Perform a search for all objects to be moved */
604         $objects= array();
605         $ldap->cd($src_dn);
606         $ldap->search("(objectClass=*)", array("dn"));
607         while($attrs= $ldap->fetch()){
608             $dn= $attrs['dn'];
609             $objects[$dn]= strlen($dn);
610         }
612         /* Sort objects by indent level */
613         asort($objects);
614         reset($objects);
616         /* Copy objects from small to big indent levels by replacing src_dn by dst_dn */
617         foreach ($objects as $object => $len){
620             $src= str_replace("\\","\\\\",$object);
621             $dst= preg_replace("/".str_replace("\\","\\\\",$src_dn)."$/", "$dst_dn", $object);
622             $dst= str_replace($src_dn,$dst_dn,$object);
624             echo "<b>"._("Object").":</b> ".LDAP::fix($src)."<br>";
626             $this->update_acls($object, $dst,TRUE);
628             if (!$this->copy($src, $dst)){
629                 echo "<font color='#FF0000'><br>".sprintf(_("FAILED to copy %s, aborting operation"),LDAP::fix($src))."</font>";
630                 return (FALSE);
631             }
632             echo "<script language=\"javascript\" type=\"text/javascript\">scrollDown2();</script>" ;
633             flush();
634         }
636         /* Remove src_dn */
637         $ldap->cd($src_dn);
638         $ldap->recursive_remove();
639         $this->orig_dn  = $this->dn = $dst_dn;
640         $this->orig_base= $this->base;     
641         $this->entryCSN = getEntryCSN($this->dn);
643         echo '<hr>';
645         echo "<div style='width:100%;text-align:right;'><form name='form' method='post' action='?plug=".$_GET['plug']."' target='_parent'>
646             <br><input type='submit' name='back' value='"._("Continue")."'>
647             </form></div>";
649         echo "<script language=\"javascript\" type=\"text/javascript\">scrollDown2();</script>" ;
650         echo "</body></html>";
652         return (TRUE);
653     }
656     /* Return plugin informations for acl handling */ 
657     static function plInfo()
658     {
659         return (array("plShortName"   => _("Generic"),
660                     "plDescription" => _("Departments"),
661                     "plSelfModify"  => FALSE,
662                     "plPriority"    => 0,
663                     "plDepends"     => array(),
664                     "plSection"     => array("administration"),
665                     "plRequirements"=> array(
666                         'ldapSchema' => array('gosaDepartment' => '>=2.7'),
667                         'onFailureDisablePlugin' => array(get_class(),'departmentManagement',
668                             'country','dcObject','domain','locality','organization')
669                         ),
671                     "plCategory"    => array("department" => array("objectClass" => "gosaDepartment", "description" => _("Departments"))),
673                     "plProvidedAcls" => array(
674                         "ou"                => _("Department name"),
675                         "description"       => _("Description"),
676                         "businessCategory"  => _("Category"),
677                         "base"              => _("Base"),
679                         "st"                => _("State"),
680                         "l"                 => _("Location"),
681                         "postalAddress"     => _("Address"),
682                         "telephoneNumber"   => _("Telephone"),
683                         "facsimileTelephoneNumber" => _("Fax"),
684                         "manager" => _("Manager"),
686                         "gosaUnitTag"       => _("Administrative settings"))
687                         ));
688     }
690     function handle_object_tagging($dn= "", $tag= "", $show= false)
691     {
692         /* No dn? Self-operation... */
693         if ($dn == ""){
694             $dn= $this->dn;
696             /* No tag? Find it yourself... */
697             if ($tag == ""){
698                 $len= strlen($dn);
700                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "No tag for $dn - looking for one...", "Tagging");
701                 $relevant= array();
702                 foreach ($this->config->adepartments as $key => $ntag){
704                     /* This one is bigger than our dn, its not relevant... */
705                     if ($len <= strlen($key)){
706                         continue;
707                     }
709                     /* This one matches with the latter part. Break and don't fix this entry */
710                     if (preg_match('/(^|,)'.preg_quote($key, '/').'$/', $dn)){
711                         @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "DEBUG: Possibly relevant: $key", "Tagging");
712                         $relevant[strlen($key)]= $ntag;
713                         continue;
714                     }
716                 }
718                 /* If we've some relevant tags to set, just get the longest one */
719                 if (count($relevant)){
720                     ksort($relevant);
721                     $tmp= array_keys($relevant);
722                     $idx= end($tmp);
723                     $tag= $relevant[$idx];
724                     $this->gosaUnitTag= $tag;
725                 }
726             }
727         }
729         /* Set tag? */
730         if ($tag != ""){
731             /* Set objectclass and attribute */
732             $ldap= $this->config->get_ldap_link();
733             $ldap->cat($dn, array('gosaUnitTag', 'objectClass'));
734             $attrs= $ldap->fetch();
735             if(isset($attrs['gosaUnitTag'][0]) && $attrs['gosaUnitTag'][0] == $tag){
736                 if ($show) {
737                     echo sprintf(_("Object '%s' is already tagged"), LDAP::fix($dn))."<br>";
738                     flush();
739                 }
740                 return;
741             }
742             if (count($attrs)){
743                 if ($show){
744                     echo sprintf(_("Adding tag (%s) to object '%s'"), $tag, LDAP::fix($dn))."<br>";
745                     flush();
746                 }
747                 $nattrs= array("gosaUnitTag" => $tag);
748                 $nattrs['objectClass']= array();
749                 for ($i= 0; $i<$attrs['objectClass']['count']; $i++){
750                     $oc= $attrs['objectClass'][$i];
751                     if ($oc != "gosaAdministrativeUnitTag"){
752                         $nattrs['objectClass'][]= $oc;
753                     }
754                 }
755                 $nattrs['objectClass'][]= "gosaAdministrativeUnitTag";
756                 $ldap->cd($dn);
757                 $ldap->modify($nattrs);
758                 if (!$ldap->success()){
759                     msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
760                 }
761             } else {
762                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "Not tagging ($tag) $dn - seems to have moved away", "Tagging");
763             }
765         } else {
766             /* Remove objectclass and attribute */
767             $ldap= $this->config->get_ldap_link();
768             $ldap->cat($dn, array('gosaUnitTag', 'objectClass'));
769             $attrs= $ldap->fetch();
770             if (isset($attrs['objectClass']) && !in_array_ics("gosaAdministrativeUnitTag", $attrs['objectClass'])){
771                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "$dn is not tagged", "Tagging");
772                 return;
773             }
774             if (count($attrs)){
775                 if ($show){
776                     echo sprintf(_("Removing tag from object '%s'"), LDAP::fix($dn))."<br>";
777                     flush();
778                 }
779                 $nattrs= array("gosaUnitTag" => array());
780                 $nattrs['objectClass']= array();
781                 for ($i= 0; $i<$attrs['objectClass']['count']; $i++){
782                     $oc= $attrs['objectClass'][$i];
783                     if ($oc != "gosaAdministrativeUnitTag"){
784                         $nattrs['objectClass'][]= $oc;
785                     }
786                 }
787                 $ldap->cd($dn);
788                 $ldap->modify($nattrs);
789                 if (!$ldap->success()){
790                     msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
791                 }
792             } else {
793                 @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "Not removing tag ($tag) $dn - seems to have moved away", "Tagging");
794             }
795         }
796     }
800 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
801 ?>