Code

8f2da4d290e13f0ea74571095dc5f5ea43e7d2a3
[gosa.git] / trunk / gosa-plugins / goto / admin / groups / apps / class_groupApplication.inc
1 <?php
2 class appgroup extends plugin
3 {
4   var $config;
5   var $curbase;
7   /* Contains the menu structure in an array.
8    */
9   var $a_Structure= array();
10   var $a_Structure_on_load = array();
11   var $Releases;
12   var $FAIrelease = 0;
13   var $apps = array();
14   var $_cache = array();
16   var $app_parameter = array();
17   var $edit_entry    = array();
18   var $enableReleaseManagement = FALSE;
20   var $copied_release = ""; 
21   var $gosaApplicationFlags;
22   var $app_flags = array(
23                     "placeOnDesktop" => "D",
24                     "placeOnKicker" => "L",
25                     "placeInStartmenu" => "M",
26                    );
27    
29   public function __construct(&$config, $dn= NULL, $parent= NULL)
30   {
31     plugin::plugin($config,$dn,$parent);
32     $this->dn = $dn; 
33     $this->_load_menu_structure();
34     $this->a_Structure_on_load = $this->a_Structure;
36     /* Check if we have relase mangement enabled and prepare group application for release management */
37     $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
38     if(!empty($tmp)){
39       $this->enableReleaseManagement = true;
40     }
42     $this->Releases   = $this->getReleases();
44     /* Set intial release */
45     $this->FAIrelease = $config->search("faiManagement","DEFAULTFAIRELEASE",array("menu"));
46     if(empty($this->FAIrelease) || !isset($this->Releases[$this->FAIrelease])){
47       $this->FAIrelease = "/";
48     }
50     $this->curbase    = $this->config->current['BASE'];
51     $this->reload();
52  
53     /* If we have at least one assigned application-
54        Enable this account.
55      */ 
56     $this->is_account = FALSE;
57     if(count($this->_get_all_entries()) > 1){
58       $this->is_account= TRUE;
59     }   
60     $this->initially_was_account = $this->is_account;
61   }
64   /*! \brief Reload the list of applications for the currently selected release.
65              If necessary, maybe the list is already cached.
66    */
67   function reload()
68   {
69     $ret = array();
70     $release_info = $this->Releases[$this->FAIrelease];
72     /* Check if the available application were already been fetched.
73        If not, build up a list of available applications.
74      */  
75     if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
77       /* First of all, get all application departments to search in.
78        */  
79       $ldap = $this->config->get_ldap_link();
80       $ldap->cd($this->config->current['BASE']);
81       $ldap->search("ou=apps",array("dn"));
82       $app_deps = array();
83       while($attrs = $ldap->fetch()){
84         $app_deps[] = $attrs['dn'];
85       }
87       /* Search all release departments for the above fetched application departments
88        */
89       foreach($app_deps as $dep){
90         $ldap->cd($dep);
91         $ldap->search("objectClass=FAIbranch",array("dn"));
92         while($attrs = $ldap->fetch()){
93           $app_deps[] = $attrs['dn'];
94         }
95       }
97       /* Filter out those releases that match the currently selected release, 
98           and fetch all applications from those departments.
99        */
100       foreach($app_deps as $dep){
101         if(preg_match("/^".preg_quote($release_info['suffix'], '/')."/",$dep)){
102           $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
103         }
104       }
106       /* Create a new array containing all fetch apps for the currently selected release,
107           sort it and store results in cache. 
108        */ 
109       $tmp = array();
110       foreach($ret as $key => $app){
111         $tmp[$key] = $app['cn'][0];
112       }
113       natcasesort($tmp);
114       $res = array();
115       foreach($tmp as $key => $app){
116         $res[] = $ret[$key];
117       }
119       $this->_cache['ReleaseApps'][$release_info['suffix']] = $res;
120     } 
121     $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
122   }
124   
125   
126   /*! \brief generate a list of available releases
127       @return return an array with all available releases.
129       e.g.
131       /     "name"    /
132             "found"   1
133             "parts"   Array (empty)
134             "suffix"  ou=apps,
136       halut "name"    halut
137             "found"   1
138             "FAIstate"  
139             "dn"      ou=halut,ou=apps,ou=Direktorium,o=Landeshauptstadt München,c=de
140             "parts"   0 halut
141             "suffix"  ou=halut,ou=apps,
143       This will be used as base for the application menu structure.
144       If there is a menu assigned for a release, this menu will be 
145        appended with the index 'ENTRIES';
146     */
147   function getReleases()
148   {
149     $ret =array("/" => array("name" => "/", "found" => TRUE , "parts" => array(),"suffix" => get_ou('applicationRDN')));
150     if($this->enableReleaseManagement){
152       /* Only display those releases that we are able to read 
153        */
154       $dn     = get_ou("applicationRDN").$this->config->current['BASE'];
155       $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
156       $res    = get_sub_list($filter,array("application","fai"), 
157           array(get_ou("applicationRDN"),get_ou("faiBaseRDN")),$dn, array("ou","FAIstate"), GL_SUBSEARCH);
159       /* Go through all departments and check which department is a valid 
160           department release.
161        */
162       foreach($res as $attrs){
163         if(preg_match("/".get_ou('applicationRDN')."/",$attrs['dn'])){
165           /* Parse all returned departments dns into a useable type.
166              (ou=1.0.0,ou=halut,ou=apps  ==> halue/1.0.0)
167            */
168           $bb     = preg_replace("/".get_ou('applicationRDN').".*/","",$attrs['dn']);
169           $parts  = array_reverse(split("ou=",$bb));
171           $str ="";
172           foreach($parts as $key => $part){
173             if(empty($part)) {
174               unset($parts[$key]);
175               continue;
176             }
177             $part = str_replace(",","",$part);
178             $str .= $part."/";
179             $parts[$key] = $part;
180           }
181           $name = preg_replace("/\/$/","",$str);
182           if(empty($name)) {
183             $name ="/";
184           }
186           $FAIstate = "";
187           if(isset($attrs['FAIstate'])){
188             $FAIstate = $attrs['FAIstate'][0];
189           }
191           /* Check if this department has a menu structure assigned 
192            */
193           $all = $this->_get_all_entries();
194           $found = FALSE;
195           foreach($all as $entry){
196             if(isset($entry['DN']) && preg_match("/^".preg_quote($bb, '/')."/",$entry['DN'])){
197               $found =TRUE;
198               break;
199             }
200           }
202           $ret[$name] = array("name"     => $name, 
203               "found"    => $found,
204               "FAIstate" => $FAIstate,
205               "dn"       => $attrs['dn'], 
206               "parts"    => $parts,"suffix" => $bb.get_ou('applicationRDN'));
207         }
208       }
209     }
210     ksort($ret);
211     return($ret);
212   }
215   /*! \brief Load the menu structure from ldap and create a multi dimensional array.
217       This will create a multidimensional array.
218       e.g.:
220       $this->a_Structure =
221   
222       [0]['TYPE']   = "BASE"
223       [0]['ENTRIES']  [0]['TYPE']   = "RELEASE"
224                       [0]['NAME']   = "halut"
225                       [0]['ENTRIES']= array()
226                       ...
227       [0]['ENTRIES']  [1]['TYPE']   = "RELEASE"
228                       [1]['NAME']   = "halut/1.0.0"
229                       [1]['ENTRIES']  [0]['TYPE']   = "TYPE"
230                                       [0]['NAME']   = "Programme"
231                                       [0]['ENTRIES'][0]['TYPE'] = "ENTRY"
232                                                     [0]['NAME'] = "konqueror"
233                                                     [1]['TYPE'] = "ENTRY"
234                                                     [1]['NAME'] = "firefox"
235    */
236   function _load_menu_structure()
237   {
238     /* Create the base object
239      */
240     $base =  array();
241     $base['UNIQID'] = uniqid();
242     $base['PARENT'] = 0; 
243     $base['NAME']   = "";
244     $base['TYPE']   = "BASE";
245     $base['ENTRIES']= array();
246     $base['STATUS'] = "LOADED";
247     
248     $this->a_Structure  = array();
249     $this->a_Structure[0] = $base;
251     /* Search for all Releases/Menu Folders and Menu Entries,
252         to append them to our structure array.
253      */
254     $ldap = $this->config->get_ldap_link();
255     $ldap->cd($this->dn);
256     $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
257     while($attrs = $ldap->fetch()){
259       /* Find the correct position where to add this entry.
260           e.g. If we have cn=firefox,cn=Programme,ou=halut...
262           1. get a pointer to the halut array ($this->a_Structure['0'][ENTRIES''][]['halut'])
263           2. then get a pointer to the halut['ENTRIES'][]['Programme'] array. 
264           3. append 'firefox' to the 'ENTRIES' of our "Programme" pointer.
265        */
266       $cur          = &$this->a_Structure[0]['ENTRIES'];
267       $parent_id    = $base['UNIQID'];
268       $sub_dn       = preg_replace("/,".preg_quote($this->dn, '/')."$/","",$attrs['dn']);
269       $sub_dn_array = split("\,",$sub_dn);
271       /* Walk through our menu structure array while we have found 
272           the correct position where to add this object. 
273        */
274       $found = true;
275       for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
276         $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
277         
278         /* We haven't found the end node where this object has to be added
279          */
280         if($i > 0){
281           $found =FALSE;
282           foreach($cur as $key => $entry){
283             if($entry['NAME'] == $name){
284               $cur = &$cur[$key]['ENTRIES'];
285               $parent_id = $entry['UNIQID'];
286               $found =true;
287               break;
288             }
289           }
290         }else{
291           
292           if(!$found){
293             break;
294           }
296           /* Get application priority.
297              And ensure that each priority exists once.
298            */
299           $priority = 1;
300           if(isset($attrs['gosaApplicationPriority'])){
301             $priority= $attrs['gosaApplicationPriority'][0];
302           }
303           while(isset($cur[$priority])){
304             $priority ++;
305           }
307           /* Create the data object that should be added 
308              * Folder
309              * Entry
310              * Release
311            */
312           $data = array();
313     
314           /* Add a menu folder 
315            */
316           if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
317             $type = "FOLDER";
319             $data['ICON'] = "";
320             if(isset($attrs['gosaApplicationIcon'])){
321               $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
322             }
324           /* Add a menu entry 
325            */
326           }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
328             $type = "ENTRY";
329             $data['INFO'] = "";
330             $data['PARAMETER'] = array();
331             if(isset($attrs['gosaApplicationParameter'])){
332               for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
333                 if(preg_match("/:/",$attrs['gosaApplicationParameter'][$p])){
334                   list($key, $value) = split(":",$attrs['gosaApplicationParameter'][$p]);
335                   if ($key == "gosaApplicationFlags") {
336                     $data['FLAGS'] = $value;
337                   }
338                   else {
339                     $data['PARAMETER'][$key] = $value;
340                   }
341                 }elseif($attrs['gosaApplicationParameter'][$p] == "*separator*"){
342                   $type = "SEPERATOR";
343                   $data['PARAMETER'] = array();
344                   break;
345                 }
346               }
347             }
349           /* Add a release
350            */
351           }elseif(in_array("FAIbranch",$attrs['objectClass'])){
352             $type = "RELEASE";
353             if(isset($attrs['FAIstate'][0])){
354               $data['FAIstate'] = $attrs['FAIstate'][0];
355             }else{
356               $data['FAIstate'] = "";
357             }
358           }
360           /* Create object and append it to the current structure pointer 
361            */
362           $data['LDAP_ATTRS'] = $attrs;
363           $data['DN']       = $attrs['dn'];
364           $data['NAME']     = $name;
365           $data['TYPE']     = $type;
366           $data['PRIORITY'] = $priority;
367           $data['ENTRIES']  = array();
368           $data['UNIQID']   = uniqid();
369           $data['PARENT']   = $parent_id;
370           $data['STATUS']   = "LOADED";
371           $cur[$priority]   = $data;
372           ksort($cur);
373         }
374       }
375     }
376   } 
379   function execute()
380   {
381     /* Call parent execute */
382     plugin::execute();
384     if(isset($_GET['r'])) $this->__construct($this->config,$this->dn);
386     if (isset($_POST['modify_state'])){
387       $this->is_account = !$this->is_account;
388     }
390     /* Do we represent a valid account? */
391     if (!$this->is_account){
392       $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Menu")), msgPool::featuresDisabled(_("Menu")));
393       return ($display);
394     }
396     $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Menu")), msgPool::featuresEnabled(_("Menu")));
398     if(isset($_GET['send'])){
399       $id = $_GET['send'];
400       $all = $this->_get_all_entries();
401       if(isset($all[$id])){
402         send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
403         exit;
404       }
405     }
407     if(isset($_GET['r']))
408     $this->__construct($this->config,$this->dn);
410     if(count($this->edit_entry)){
411       $smarty = get_smarty();
412       /* Checkboxes */
413       foreach ($this->app_flags as $name => $flag){
414         if (preg_match("/$flag/", $this->gosaApplicationFlags) && $this->acl_is_readable("$name")){
416           $smarty->assign("$name", "checked");
417         } else {
418           $smarty->assign("$name", "");
419         }
420        }
421       
422       $tmp = $this->plInfo();
423       foreach($tmp['plProvidedAcls'] as $name => $translation){
424           $smarty->assign($name."ACL",$this->getacl($name));
425       }
427       if($this->edit_entry['TYPE'] == "ENTRY"){
428         $smarty->assign("type", "ENTRY");
429         $smarty->assign("entry",$this->edit_entry);
430         $smarty->assign("paras",$this->app_parameter);
431         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
432         return($display);
433       }
434       if($this->edit_entry['TYPE'] == "FOLDER"){
436         session::set("binarytype" , "image/jpeg");
437         session::set("binary" , $this->edit_entry['ICON']);
438   
439         $smarty->assign("rand", microtime(TRUE));
440         $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0); 
441         $smarty->assign("type", "FOLDER");
442         $smarty->assign("entry",$this->edit_entry);
443         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
444         return($display);
445       }
446     }
448     $smarty = get_smarty();
449     $smarty->assign("plug_id" , $_GET['plug']);
451     /* Create application list */
452     $div = new divSelectBox("appgroup");
453     $div->SetHeight(300);
454     $departments = array();
455     if(!$this->enableReleaseManagement){
456       $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
457       foreach($res as $value){
458         $fdn = $value['dn'];
459         $fdn = preg_replace("/".preg_quote($this->curbase, '/')."/","",$fdn);
460         $fdn= LDAP::fix($fdn);
461         if($value["description"][0]!=".."){
462           $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
463         }else{
464           $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
465         }
466       }
467     }
469     $linkopen = "<a href='?plug=".$_GET['plug']."&amp;act=depopen&amp;depid=%s'>%s</a>";
471     /* Create base back entry */
472     $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
473     if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
474       $div->AddEntry(array(
475             array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
476               "attach"=>"style='border:0px;'")
477             ));
478     }
480     /* Append departments for current base */
481     foreach($departments as $key => $app){
482       $div->AddEntry(array(
483             array("string"=>"<img class='center' src='images/lists/folder.png' alt='"._("department")."'>&nbsp;".sprintf($linkopen,
484                 base64_encode($key),$app),
485               "attach"=>"style='border:0px;'")
486             ));
487     }
489   
490     /* Add applications found on this base */
491     $used_apps = $this->_get_used_entry_name();
492     foreach($this->apps as $key => $app){
493       if(in_array($app['cn'][0],$used_apps)){
494         continue;
495       }
496       if(!preg_match("/".get_ou('applicationRDN').preg_quote($this->curbase, '/')."$/",$app['dn'])){
497         continue;
498       }
500       $name = $app['cn'][0];
501       if(isset($app['description'])){
502         $name .= "&nbsp;[".$app['description'][0]."]";
503       }
504       $div->AddEntry(array(
505             array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
506               "<img class='center' src='plugins/goto/images/select_application.png' alt='"._("application")."'>&nbsp;".$name,
507               "attach"=>"style='border:0px;'")
508             ));
509     }
511     /* Assign copy / paste values 
512      */
513     if(!empty($this->copied_release)){
514       $smarty->assign("copied", TRUE);
515       $smarty->assign("copy_source", $this->copied_release);
516     }else{
517       $smarty->assign("copied", FALSE);
518     }
519     $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
520     $smarty->assign("FAIrelease",$this->FAIrelease);
521     $smarty->assign("app_list",$div->DrawList());
522     $smarty->assign("i",0);
523     $smarty->assign("releases",$this->Releases);
524     $smarty->assign("folders" , $this->_get_folder_names());
525     $entries = $this->_get_entries_for_release($this->FAIrelease);
526     $smarty->assign("entries",$entries);
527     $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
528     return($display);
529   }
531    
532   /*! \brief Returns all used folder names 
533       @return Array  All used folder names.
534    */ 
535   function _get_folder_names()
536   {
537     $data = $this->_get_entries_for_release($this->FAIrelease);
538     $all    = $this->_get_all_entries();
539     $ret = array("BASE" => ".");
540     foreach($data as $entry){
542       if($entry['TYPE'] == "FOLDER"){
543         $str = $entry['NAME'];
544         $parent = $entry['PARENT'];
545         $i = 10;
546         while(isset($all[$parent]) && $i){  
547           $i --;
548           $parent_o = $all[$parent];
549           $str      = $parent_o['NAME']."/".$str;
550           $parent   = $all[$parent_o['UNIQID']]['PARENT'];
551         }        
552         $ret[$entry['UNIQID']] = $str;
553       }
554     }
555     return($ret);
556   }
559   /*! \brief return all used applications 
560       @return Array  All used applications.
561    */ 
562   function _get_used_entry_name()
563   {
564     $data = $this->_get_entries_for_release($this->FAIrelease);
565     $ret = array();
566     foreach($data as $entry){
567       if($entry['TYPE'] == "ENTRY"){
568         $ret[] = $entry['NAME'];
569       }
570     }
571     return($ret);
572   }
575   /*! \brief Returns all folder an entries for the selected release 
576       @return Array  Returns the complete menu structure for the given array.
577    */ 
578   function _get_entries_for_release($release,$cur = NULL)
579   {
580     $all = $this->_get_all_entries();
581     $key = $this->_get_release_key($release);
582     if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
583       $res = $this->_get_all_entries(TRUE,TRUE,$all[$key]['ENTRIES']);
584       return($res);
585     } 
586     return(array());
587   }
590   /*! \brief Save the currently edited entry 
591     */
592   function _save_entry_edit()
593   {
594     $all    = $this->_get_all_entries();
595     $entry  = $this->edit_entry;
596     $r_entry= &$all[$entry['UNIQID']];
599     if($entry['TYPE'] == "ENTRY"){
600       $r_entry['PARAMETER'] = $this->app_parameter;
601       $r_entry['FLAGS'] = $this->gosaApplicationFlags;
602       if($r_entry['STATUS'] != "ADDED"){
603         $r_entry['STATUS'] = "EDITED";
604       } 
605     }
606     if($entry['TYPE'] == "FOLDER"){
607       $r_entry['ICON']   = $this->edit_entry['ICON'];
608       $r_entry['STATUS'] = "EDITED";
609     }
610     $this->dialog = FALSE;
611     $this->edit_entry = array();
612   }
615   /*! \brief prepare the entry with the given ID, to be edited.
616               Read application Parameter from ldap.
617    */
618   function _edit_entry_edit($id)
619   {
620     $all   = $this->_get_all_entries();
621     $entry = $all[$id];
623     $this->app_parameter = array();
624     if($entry['TYPE'] == "ENTRY"){
625       $found = FALSE;
626       foreach($this->apps as $id => $app){
628         if($app['cn'][0] == $entry['NAME']){
629           $found = TRUE;
630           break;
631         }
632       }
633       if($found){
634         /* Create a list of editable parameter */
635         if(isset($app['gosaApplicationParameter'])){
636           for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
637             $para = $app['gosaApplicationParameter'][$i];
638             $tmp  = split(":",$para);
639             $this->app_parameter[$tmp[0]] = $tmp[1];
640           }
641         }
643         if(isset($app['gosaApplicationFlags'])) {
644           $this->gosaApplicationFlags = $app['gosaApplicationFlags'][0];
645         }
647         /* Overwrite parameters with entry parameters */
648         foreach($entry['PARAMETER'] as $name => $value){
649           $this->app_parameter[$name] = $value;
650         }
652         if (isset($entry['FLAGS'])) {
653           $this->gosaApplicationFlags = $entry['FLAGS'];
654         }
655         
656         $this->dialog = TRUE;
657         $this->edit_entry = $entry;
658       }
659     }
661     if($entry['TYPE'] == "FOLDER"){
662       $this->dialog = TRUE;
663       $this->edit_entry = $entry;
664     }
665   }
668   /*! \brief Removes the menu structure from ldap 
669    */
670   function remove_from_parent()
671   {
672     $ldap = $this->config->get_ldap_link();
673     $ldap->cd($this->dn);
674     $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
675     $a_remove = array();
676     while($attrs = $ldap->fetch()){
677       $a_remove[] = $attrs['dn'];
678     }
679     foreach($a_remove as $remove){
680       $ldap->rmdir_recursive($remove);
681       if (!$ldap->success()){
682         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
683       }
684     }
685     $this->_load_menu_structure();
686   }
689   function check()
690   {
691     $message = plugin::check();
692     return($message);
693   }
696   /*! \brief Create missing releases, if there is a release selected \
697               that is currently not part of the menu structure \
698               then create this entry
699    */
700   function _check_missing_release($release)
701   {
702     $release_info = $this->Releases[$release];
704     $parent_id = $this->a_Structure[0]['UNIQID'];
705     $cur = &$this->a_Structure[0]['ENTRIES'];
706     for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
707       $part = $release_info['parts'][$i];
708       $found = FALSE;
709       foreach($cur as $key => $name){
710         if($name['NAME'] == $part){
711           $parent_id = $cur[$key]['UNIQID'];
712           $cur = &$cur[$key]['ENTRIES'];
713           
714           $found =TRUE;
715           break;
716         }
717       }
718       if(!$found){
719         $release           =  array();
720         $release['UNIQID'] = uniqid();
721         $release['PARENT'] = $parent_id;
722         $release['NAME']   = $part;
723         $release['TYPE']   = "RELEASE";
724         $release['ENTRIES']= array();
725         $release['STATUS']   = "ADDED";
726         $release['FAIstate'] =  $release_info['FAIstate'];
727         $cur[] = $release;
728         $i --;
729       }
730     }
731   }
735   /*! \brief Moves a given object ($id) in a specified direction ($dir).
736       @param  String The object ID of the object we want to move
737       @dir    String Move "up" or "down"
738    */
739   function _move_entry($id,$dir)
740   {
741     $all   = $this->_get_all_entries();
742     if($dir == "down"){
743       $to = $this->_get_next($id);
744     } 
745     if($dir == "up"){
746       $to = $this->_get_last($id);
747     }
749     if(!$to){
750       return;
751     }
753     $o_to   = $all[$to];
754     $o_from = $all[$id];
756     if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
757       $to    = $this->_get_next($to,$o_from['PARENT']); 
758       $o_to  = $all[$to]; 
759     }
761     /* Target is ENTRY && same BASE, just switch */
762     if($o_to['PARENT'] == $o_from['PARENT'] ){
763       $parent = $all[$o_to['PARENT']];
764       $pos = 0;
765       foreach($parent['ENTRIES'] as $entry){
766         $pos ++;
767         if($entry['UNIQID'] == $to){
768           break;
769         }
770       }
771       if($dir == "up" && $pos > 0){
772         $pos --;
773       }
774       $this->_add_entry($parent['UNIQID'],$o_from,$pos);
775       $this->_remove_entry_id($id);
776       return(TRUE);
777     }
778     return(FALSE);
779   }
782    
783   /*! \brief  Returns the railing object ID of the given object.
784       @return String  The id of the trailing object.
785    */ 
786   function _get_last($id)
787   {
788     $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
789     for($i = 0 ; $i < count($all_l) ; $i ++){
790       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
791         $i++;
792         break;
793       }
794     }
795     while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("SEPERATOR","ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
796       $i++;
797     }
799     if(!isset($all_l[$i])){
800       return(FALSE);
801     }
803     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
804       return($all_l[$i]['PARENT']);
805     }     
807     return($all_l[$i]['UNIQID']);
808   }
811   /*! \brief  Returns the following object ID of the given object.
812       @return String  The id of the following object.
813    */ 
814   function _get_next($id,$parent = 0)
815   {
816     $all_l = $this->_get_entries_for_release($this->FAIrelease);
817     for($i = 0 ; $i < count($all_l) ; $i ++){
818       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
819         $i++;
820         break;
821       }
822     }
823     if($parent != 0){
824       while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
825         $i++;
826       }
827     }else{
828       while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("SEPERATOR","ENTRY","FOLDER")) && $i < count($all_l)){
829         $i++;
830       }
831     }
832     if(!isset($all_l[$i])){
833       return(FALSE);
834     }
835     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
836       return($all_l[$i]['PARENT']);
837     }
838     return($all_l[$i]['UNIQID']);
839   }
841   /* !\brief Handle ui POSTS, like sort up/down/delete
842    */ 
843   function save_object()
844   {
845     foreach($_POST as $name => $value){
847       if(preg_match("/^menu_copy_/",$name)){
848         $this->copied_release = $this->FAIrelease;
849         break;
850       }
851       if(preg_match("/^menu_delete/",$name)){
852         $current_rel  = $this->_get_release_key($this->FAIrelease); 
853         $this->_remove_entry_id($current_rel);
854         break;
855       }
856       if(preg_match("/^menu_paste_/",$name)){
857         $source_rel   = $this->_get_release_key($this->copied_release); 
858         $current_rel  = $this->_get_release_key($this->FAIrelease);
860         $all = $this->_get_all_entries();
861         $menu = $all[$source_rel]['ENTRIES'];
862     
863         foreach($menu as $entry){
864           if(in_array($entry['TYPE'],array("FOLDER","ENTRY","SEPERATOR"))){
865             $this->_add_entry($current_rel,$entry,-1);
866           }
867         }
868         $this->copied_release = "";
869         break;
870       }
872       if(preg_match("/del_/",$name)){
873         $id = preg_replace("/^del_/","",$name);
874         $id = preg_replace("/_(x|y)$/","",$id);
875         $this->_remove_entry_id($id);
876         break;
877       }
878       if(preg_match("/app_entry_edit/",$name)){
879         $id = preg_replace("/^app_entry_edit/","",$name);
880         $id = preg_replace("/_(x|y)$/","",$id);
881         $this->_edit_entry_edit($id);
882         break;
883       }
884       if(preg_match("/up_/",$name)){
885         $id = preg_replace("/^up_/","",$name);
886         $id = preg_replace("/_(x|y)$/","",$id);
887         $this->_move_entry($id,"up");
888         break;
889       }
890       if(preg_match("/down_/",$name)){
891         $id = preg_replace("/^down_/","",$name);
892         $id = preg_replace("/_(x|y)$/","",$id);
893         $this->_move_entry($id,"down");
894         break;
895       }
896       if(preg_match("/^parameter_/",$name) && 
897         count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
898         $name = preg_replace("/^parameter_/","",$name);
899         $this->app_parameter[$name] = $value;
900       }
901     }
903     if(isset($_POST['FAIrelease'])){
904       $this->FAIrelease = $_POST['FAIrelease'];
905       $this->_check_missing_release($this->FAIrelease);
906     }
907     if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
908       $this->curbase = base64_decode($_GET['depid']);
909     }
910     if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
911       $folder = $_POST['folder'];
912       foreach($_POST as $name => $value){
913         if(preg_match("/^AddApp_[0-9]*$/",$name)){
914           $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));   
915         }
916       }
917     }
919     /* Add seperator */
920     if(isset($_POST['add_seperator']) && isset($_POST['menu_folder'])){
921       $folder = $_POST['menu_folder'];
922       $this->_add_seperator($folder);
923     }
925     if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
926       $folder = $_POST['menu_folder'];
927       $name = $_POST['menu_folder_name'];
928       if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
929         $this->_add_sub_folder($folder,$name);
930       }
931     }
932     if(isset($_POST['app_entry_save'])){ 
933       foreach($this->app_flags as $name => $flag) {
934         if($this->acl_is_writeable($name)) {
935           if(!isset($_POST[$name]) && strstr($this->gosaApplicationFlags,$flag)){
936             $this->gosaApplicationFlags = str_replace($flag,"",$this->gosaApplicationFlags);
937           }elseif(isset($_POST[$name]) && !strstr($this->gosaApplicationFlags,$flag)){
938             $this->gosaApplicationFlags = str_replace("]", "$flag]", $this->gosaApplicationFlags);
939           }
940         }
941       }
943       $this->_save_entry_edit();
944     }
946     if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
947       if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
948         $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
949       }
950     }
952     if(isset($_POST['edit_reset_image'])){
953       $this->edit_entry['ICON'] = "";
954     }
956     if(isset($_POST['app_entry_cancel'])){
957       $this->edit_entry = array();
958       $this->dialog = FALSE;
959     }
960     $this->reload();
961   }
963  
964   /*! \brief Returns the UNIQID of the currently selected release 
965    */ 
966   function _get_release_key($release,$add_if_missing = FALSE)
967   {
968     $release_info = $this->Releases[$release];
970     if($release_info['name'] == "/"){
971       return($this->a_Structure['0']['UNIQID']);
972     }
974     $cur = &$this->a_Structure[0]['ENTRIES'];
975     $s_key = "";
976     $found = FALSE;
977     foreach($release_info['parts'] as $name){
978       foreach($cur as $key => $obj){
979         if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
980           $s_key = $cur[$key]['UNIQID'];
981           $cur = &$cur[$key]['ENTRIES'];
982           $found = TRUE;
983           break;
984         }
985         $found = FALSE;
986       }
987     }
988     if($found){
989       return($s_key);  
990     }  
991     return(FALSE);
992   }
994  
995   /*! \brief Add a new folder folder to the specified folder id
996       @param  String $folder The folder id in where we want to add the new folder.
997       @param  String $name   The name of the new folder.
998    */ 
999   function _add_sub_folder($folder,$name)
1000   {
1001     $all = $this->_get_all_entries();
1002     if($folder == "BASE"){
1003       $folder = $this->_get_release_key($this->FAIrelease,TRUE);
1004     }
1005     
1006     if(isset($all[$folder])){
1007       $a_folder = array();
1008       $a_folder['STATUS'] = "ADDED";
1009       $a_folder['NAME']   = $name;
1010       $a_folder['UNIQID'] = uniqid();
1011       $a_folder['ENTRIES']= array();
1012       $a_folder['PARENT'] = $folder;      
1013       $a_folder['TYPE']   = "FOLDER";
1014       $a_folder['ICON']   = "";
1015       $all[$folder]['ENTRIES'][] = $a_folder;
1016     }
1017   }
1020   /* !\brief  Remove the given id from the menu structure.
1021       @param  String  ID to of the entry we want to remove.
1022       @return Boolean TRUE on success
1023    */
1024   function _remove_entry_id($id)
1025   {
1026     $all = $this->_get_all_entries();
1027     if(isset($all[$id])){
1028       $all[$id]['STATUS'] = "REMOVED";
1029       $all[$id]['ENTRIES'] = array();
1030       return(TRUE);
1031     }
1032     return(FALSE);
1033   }
1035   
1036   /* !\brief  Adds an object to a given folder.
1037       @param  String  The folder where we should add the entry
1038       @param  Array   The entry we want to add.
1039       @param  Array   The position in the destination entry array.
1040    */
1041   function _add_entry($folder_id,$entry,$pos = 0)
1042   {
1043     $all = $this->_get_all_entries();
1045     /* Do not add removed */
1046     if($entry['STATUS'] == "REMOVED"){
1047       return;
1048     }
1050     /* Check if the folder exists 
1051      */
1052     if(isset($all[$folder_id])){
1054       /* Check if the entry we want to add, 
1055           contains su objects.
1056        */
1057       if(!isset($entry['ENTRIES'])){
1058         $entries = array();
1059       }else{
1060         $entries = $entry['ENTRIES'];
1061       }
1062       $folder  = &$all[$folder_id];
1064       /* Prepare the entry to be added.
1065        */
1066       $entry['UNIQID'] = uniqid();     
1067       $entry['PARENT'] = $folder_id;
1068       $entry['ENTRIES']= array();
1069       $entry['STATUS'] = "ADDED";
1070      
1071       /* Append the ebtry to the given folder 
1072           and to the given position \$pos
1073        */ 
1074       $cnt = 0; 
1075       $new = array();
1076       $added =FALSE;
1077       foreach($folder['ENTRIES'] as $key => $obj){
1078         if($obj['STATUS'] == "LOADED"){
1079           $obj['STATUS'] = "EDITED";
1080         }
1081         if($pos == $cnt){
1082           $new[] = $entry;
1083           $added = TRUE;
1084         }
1085         $cnt ++;
1086         $new[] = $obj;
1087       }
1088       if(!$added){
1089         $new[] = $entry;
1090       }
1091       $all[$folder_id]['ENTRIES'] = &$new;
1092  
1093       /* Add sub entries too.
1094        */ 
1095       foreach($entries as $sub){
1096         $this->_add_entry($entry['UNIQID'],$sub,-1);
1097       }
1098       return(TRUE);
1099     }
1100     return(FALSE);
1101   }
1103  
1104   /*! \brief Add the application identified by $app_id to folder $folder_id 
1105       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
1106       @param  Integer app_id    The ID of the application which should be added.
1107    */ 
1108   function _add_app_id($folder_id,$app_id)
1109   {
1110     $all = $this->_get_all_entries();
1111     if($folder_id == "BASE"){
1112       $folder_id = $this->_get_release_key($this->FAIrelease);
1113     }
1114     if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
1116       $new = array();
1117       $new['TYPE']  = "ENTRY";
1118       $new['NAME']  = $this->apps[$app_id]['cn'][0];
1119       $new['UNIQID']= uniqid(); 
1120       $new['PARENT']= $folder_id;
1121       $new['PARAMETER']= array();
1122       if(isset($this->apps[$app_id]['description'][0])){
1123         $new['INFO']  = $this->apps[$app_id]['description'][0];
1124       }else{
1125         $new['INFO']  = "";
1126       }
1127       $new['STATUS']= "ADDED";
1128       $all[$folder_id]['ENTRIES'][] = $new;
1129     }
1130   }
1133   /*! \brief Add the application identified by $app_id to folder $folder_id 
1134       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
1135       @param  Integer app_id    The ID of the application which should be added.
1136    */ 
1137   function _add_seperator($folder_id)
1138   {
1139     $all = $this->_get_all_entries();
1140     if($folder_id == "BASE"){
1141       $folder_id = $this->_get_release_key($this->FAIrelease);
1142     }
1144     if(isset($all[$folder_id])){
1145       $new = array();
1146       $new['TYPE']  = "SEPERATOR";
1147       $new['NAME']  = "SEPERATOR";
1148       $new['UNIQID']= uniqid(); 
1149       $new['PARENT']= $folder_id;
1150       $new['PARAMETER']= array();
1151       $new['STATUS']= "ADDED";
1152       $all[$folder_id]['ENTRIES'][] = $new;
1153     }
1154   }
1157   /*! \brief  Return all entries linear. ($this->a_Structure is a multidimensional array) 
1158       @param  Boolean   $add_tags  If TRUE, OPEN/CLOSE Tags will be appended.
1159                         Used in the smarty template to display logical sperations.
1160       @param  &Array    Start here, Pointer to an array.
1161    */ 
1162   function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, &$cur = NULL)
1163   {
1164     $ret = array();
1165     if($cur == NULL){
1166       $cur = &$this->a_Structure;
1167     }
1169     /* Walk through all entries and append them to our return array 
1170      */
1171     foreach($cur as $key => $entry){
1172       if($skip_release && $entry['TYPE'] == "RELEASE"){
1173         continue;
1174       }    
1175       if($entry['TYPE'] == "ENTRY"){
1176         $found = FALSE;
1177         foreach($this->apps as $app){
1178           if($app['cn'][0] == $entry['NAME']){
1179             $found = TRUE;
1180             if(isset($app['description'][0])){
1181               $entry['INFO'] = "[".$app['description'][0]."]";
1182             }
1183             break;
1184           }
1185         } 
1186         if(!$found){
1187           $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
1188         }
1189       }
1191       $tmp = $entry;
1192   
1193       /* Recursive resolution of the subentries  
1194          There are two methods.
1195             - Just add sub entries  
1196             - Add sub entries and additionaly add OPEN / CLOSE tags to be able 
1197                 to display logical seperators in the smarty template.
1198        */ 
1199       if(!$add_tags){
1200         $ret[$tmp['UNIQID']] = &$cur[$key];
1201         if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
1202           $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1203         }
1204       }else{
1205       
1206         if(isset($tmp['ENTRIES'])){
1207           unset($tmp['ENTRIES']);
1208         }
1209         if($tmp['STATUS'] != "REMOVED"){
1210           $ret[] = $tmp;
1211           if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
1212             $add = false;
1213             foreach($entry['ENTRIES'] as $entry){
1214               if($entry['STATUS'] != "REMOVED"){
1215                 $add = TRUE;
1216                 break;
1217               }
1218             }
1220             if($add){
1221               $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
1222               $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1223               $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
1224             }
1225           }
1226         }
1227       }
1228     }
1229     return($ret);
1230   }
1233   /*! \brief Save this plugin data to ldap.
1234              Save the current menu structure to ldap.
1235    */
1236   function save()
1237   {
1238     $ldap = $this->config->get_ldap_link();
1239     $all = $this->_get_all_entries();
1240     $prio = 0;
1241     $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
1243     /* Walk through the menu structure and build up the ldap data object, 
1244         the entry dn and the entry priority.
1245      */
1246     $sep_id = 0;
1247     foreach($all as $entry){
1248       $prio ++;
1249       $cur = $entry;
1250       $dn = "";
1252       /* Build entry dn
1253        */
1254       do{  
1255         if($cur['TYPE'] == "SEPERATOR"){
1256           $sep_id ++;
1257           $dn.= "cn=seperator_".$sep_id.",";
1258         }elseif($cur['TYPE'] == "ENTRY"){
1259           $dn.= "cn=".$cur['NAME'].",";
1260         }elseif($cur['TYPE'] == "FOLDER"){
1261           $dn.= "cn=".$cur['NAME'].",";
1262         }elseif($cur['TYPE'] == "RELEASE"){
1263           $dn.= "ou=".$cur['NAME'].",";
1264         }elseif($cur['TYPE'] == "BASE"){
1265         }
1266         if(!isset($all[$cur['PARENT']])){
1267           $cur = NULL;
1268         }else{
1269           $cur = $all[$cur['PARENT']];
1270         }
1271       }while(is_array($cur));
1273       $cur_dn = $dn.$this->dn;
1274       $attrs = array();
1276       /* Build entry data object.
1277        */
1278       switch($entry['TYPE']){
1279         case "SEPERATOR"    :
1280         { 
1281           $attrs['objectClass'] = array("gotoMenuEntry");
1282           $attrs['cn']          = "seperator_".$sep_id;
1283           $attrs['gosaApplicationPriority'] = $prio;
1284           $attrs['gosaApplicationParameter'] = "*separator*";
1285         }
1286         break;
1287         case "ENTRY"    :
1288         { 
1289           $attrs['objectClass'] = array("gotoMenuEntry");
1290           $attrs['cn']          = $entry['NAME'];
1291           $attrs['gosaApplicationPriority'] = $prio;
1292           $attrs['gosaApplicationParameter'] = array(); 
1294           if (isset($entry['FLAGS'])) {
1295             /* Check if the flags changed at all */
1296             $diff = FALSE;
1297             foreach($this->apps as $id => $app) {
1298               if($app['cn'][0] == $entry['NAME']){
1299                 $orig_flags = $app['gosaApplicationFlags'][0];
1300                 foreach($this->app_flags as $name => $flag) {
1301                   if((strstr($orig_flags, $flag) && !strstr($entry['FLAGS'],$flag)) || !strstr($orig_flags, $flag) && strstr($entry['FLAGS'], $flag)) {
1302                     $diff = TRUE;
1303                     break;
1304                   }
1305                 }
1306               }
1307             }
1308             /* Only store appflags into LDAP if its different from the original app */
1309             if ($diff) {
1310                 $attrs['gosaApplicationParameter'][] = "gosaApplicationFlags:".$entry['FLAGS'];
1311             }
1312           }
1313            
1314           foreach($entry['PARAMETER'] as $name => $value){
1315             $attrs['gosaApplicationParameter'][] = $name.":".$value; 
1316           }
1317           if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1318             unset($attrs['gosaApplicationParameter']);
1319           } 
1320         }
1321         break;
1322         case "FOLDER"   : 
1323         { 
1324           $attrs['objectClass'] = array("gotoSubmenuEntry");
1325           $attrs['cn']          = $entry['NAME'];
1326           $attrs['gosaApplicationPriority'] = $prio;
1327           if($entry['STATUS'] != "ADDED"){
1328             $attrs['gosaApplicationIcon'] = array();
1329           }
1330           
1331           if(!empty($entry['ICON'])){
1332             $attrs['gosaApplicationIcon']     = $entry['ICON'];
1333           }
1334         }
1335         break;
1336         case "RELEASE"  : 
1337         {
1338           $attrs['ou']            = $entry['NAME'];
1339           $attrs['objectClass']   = array();
1340           $attrs['objectClass'][] = "top";
1341           $attrs['objectClass'][] = "organizationalUnit";
1342           $attrs['objectClass'][] = "FAIbranch";
1343           if(!empty($entry['FAIstate'])){
1344             $attrs['FAIstate']      = $entry['FAIstate'];
1345           }
1346         }
1347         break;
1348       }
1349  
1350       /* Append missing ObjectClasses,  ...  Tagging 
1351        */
1352       if(isset($entry['LDAP_ATTRS'])){
1353         for($i = 0 ; $i < $entry['LDAP_ATTRS']['objectClass']['count']; $i ++){
1354           $oc = $entry['LDAP_ATTRS']['objectClass'][$i];
1355           if(!in_array($oc,$attrs['objectClass'])){
1356             $attrs['objectClass'][] = $oc;
1357           }
1358         }
1359       }
1360   
1361       /* Create an array containing all operations sorted by type. (add,remove...)
1362        */
1363       if($entry['STATUS'] == "LOADED"){
1364         continue;
1365       }
1366       if($entry['STATUS'] == "REMOVED"){
1367         if(isset($entry['DN'])){
1368           $Actions['Remove'][$entry['DN']] = $entry['DN'];
1369         }else{
1370           $Actions['Remove'][$cur_dn] = $cur_dn;
1371         }
1372       }
1373       if($entry['STATUS'] == "EDITED"){
1374         $Actions['Edit'][$cur_dn] = $attrs;
1375       }
1376       if($entry['STATUS'] == "ADDED"){
1377         $Actions['Add'][$cur_dn] = $attrs;
1378       }
1379     }
1381     /* First remove entries
1382      */
1383     $ldap = $this->config->get_ldap_link();
1384     $ldap->cd($this->config->current['BASE']);
1385     foreach($Actions['Remove'] as $dn){
1386       $ldap->cd($dn);
1387       $ldap->cat($dn);
1388       if($ldap->count()){
1389         $ldap->rmdir_recursive($dn);
1390         if (!$ldap->success()){
1391           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1392         }
1393       }
1394     }
1395     
1396     /* Add new entries
1397      */
1398     foreach($Actions['Add'] as $dn => $data){
1399       $this->tag_attrs($data,$dn,$this->gosaUnitTag);
1400       $ldap->cd($dn);
1401       $ldap->cat($dn);
1402       if(!$ldap->count()){
1403         $ldap->add($data);
1404         if (!$ldap->success()){
1405           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
1406         }
1407       }
1408     }
1410     /* Modify entries
1411      */
1412     foreach($Actions['Edit'] as $dn => $data){
1413       $this->tag_attrs($data,$dn,$this->gosaUnitTag);
1414       $ldap->cd($dn);
1415       $ldap->cat($dn);
1416       if($ldap->count()){
1417         $ldap->modify($data);
1418         if (!$ldap->success()){
1419           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
1420         }
1421       }
1422     }
1424     $this->_load_menu_structure();
1425   }
1428   /*! \brief  Return plugin informations for acl handling  
1429       @return Array containing all plugin ACL informations
1430    */ 
1431   static function plInfo()
1432   {
1433     return (array(
1434           "plShortName"   => _("Applications"),
1435           "plDescription" => _("Group applications"),
1436           "plSelfModify"  => FALSE,
1437           "plDepends"     => array(),
1438           "plPriority"    => 7,
1439           "plSection"     => array("administration"),
1440           "plCategory"    => array("groups"),
1441           "plProvidedAcls"=> array(
1442             "gosaMemberApplication"     => _("Application"),
1443             "FAIrelease"                => _("Release"),
1444             "gosaApplicationParameter"  => _("Application parameter"),
1445             "placeOnDesktop"      => _("Place icon on members desktop"),            // D
1446             "placeOnKicker"       => _("Place entry in members launch bar"),        // L
1447             "placeInStartmenu"    => _("Place entry in members startmenu")         // M
1448           )));
1449   }
1452   /* \brief   Prepare this plugin to be copied.
1453               Adapt all required attributes from the source object.
1454               In this case, update the menu structure too, mark all elements
1455                as newly added, so they will be saved in save();
1456    */
1457   function PrepareForCopyPaste($source)
1458   {
1459     plugin::PrepareForCopyPaste($source);
1460    
1461     $tmp = new appgroup($this->config,$source['dn']);
1462     $this->is_account = TRUE;
1463     $this->a_Structure = $tmp->a_Structure;
1464     $all = $this->_get_all_entries();
1465     foreach($all as &$entry){
1466       if(isset($entry['STATUS'])){
1467         $entry['STATUS'] = "ADDED";
1468       }
1469     }
1470   }
1473   /*! \brief  Save HTML posts in multiple edit mode
1474    */
1475   function multiple_save_object()
1476   {
1477     if(isset($_POST['group_apps_multi'])){
1478       $this->save_object(); 
1479       plugin::multiple_save_object();    
1480   
1481       /* Get posts */
1482       foreach(array("apps") as $attr){
1483         if(isset($_POST['use_'.$attr])) {
1484           $this->multi_boxes[] = $attr;
1485         }
1486       }
1487     }
1488   }
1489   
1491   /*! \brief  Return values used in multiple edit mode.
1492               Some values can be modified for multiple 
1493               groups at the same time.
1494       @return Array  All values that support multiple edit.
1495    */
1496   function get_multi_edit_values()
1497   {
1498     $ret = plugin::get_multi_edit_values();
1500     if(in_array("apps",$this->multi_boxes)){
1501       $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1502       $ret['Categories']               = $this->Categories;
1503       $ret['gosaMemberApplication']    = $this->gosaMemberApplication;
1504       $ret['FAIrelease']               = $this->FAIrelease;
1505       $ret['appoption']                = $this->appoption;
1506     }
1507     return($ret);
1508   }
1510 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1511 ?>