Code

Apply fix for #2994
[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) = explode(":",$attrs['gosaApplicationParameter'][$p], 2);
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  = explode(":",$para, 2);
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             $attrs['gosaApplicationParameter'][] = "gosaApplicationFlags:".$entry['FLAGS'];
1296           }
1297            
1298           foreach($entry['PARAMETER'] as $name => $value){
1299             $attrs['gosaApplicationParameter'][] = $name.":".$value; 
1300           }
1301           if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1302             unset($attrs['gosaApplicationParameter']);
1303           } 
1304         }
1305         break;
1306         case "FOLDER"   : 
1307         { 
1308           $attrs['objectClass'] = array("gotoSubmenuEntry");
1309           $attrs['cn']          = $entry['NAME'];
1310           $attrs['gosaApplicationPriority'] = $prio;
1311           if($entry['STATUS'] != "ADDED"){
1312             $attrs['gosaApplicationIcon'] = array();
1313           }
1314           
1315           if(!empty($entry['ICON'])){
1316             $attrs['gosaApplicationIcon']     = $entry['ICON'];
1317           }
1318         }
1319         break;
1320         case "RELEASE"  : 
1321         {
1322           $attrs['ou']            = $entry['NAME'];
1323           $attrs['objectClass']   = array();
1324           $attrs['objectClass'][] = "top";
1325           $attrs['objectClass'][] = "organizationalUnit";
1326           $attrs['objectClass'][] = "FAIbranch";
1327           if(!empty($entry['FAIstate'])){
1328             $attrs['FAIstate']      = $entry['FAIstate'];
1329           }
1330         }
1331         break;
1332       }
1333  
1334       /* Append missing ObjectClasses,  ...  Tagging 
1335        */
1336       if(isset($entry['LDAP_ATTRS'])){
1337         for($i = 0 ; $i < $entry['LDAP_ATTRS']['objectClass']['count']; $i ++){
1338           $oc = $entry['LDAP_ATTRS']['objectClass'][$i];
1339           if(!in_array($oc,$attrs['objectClass'])){
1340             $attrs['objectClass'][] = $oc;
1341           }
1342         }
1343       }
1344   
1345       /* Create an array containing all operations sorted by type. (add,remove...)
1346        */
1347       if($entry['STATUS'] == "LOADED"){
1348         continue;
1349       }
1350       if($entry['STATUS'] == "REMOVED"){
1351         if(isset($entry['DN'])){
1352           $Actions['Remove'][$entry['DN']] = $entry['DN'];
1353         }else{
1354           $Actions['Remove'][$cur_dn] = $cur_dn;
1355         }
1356       }
1357       if($entry['STATUS'] == "EDITED"){
1358         $Actions['Edit'][$cur_dn] = $attrs;
1359       }
1360       if($entry['STATUS'] == "ADDED"){
1361         $Actions['Add'][$cur_dn] = $attrs;
1362       }
1363     }
1365     /* First remove entries
1366      */
1367     $ldap = $this->config->get_ldap_link();
1368     $ldap->cd($this->config->current['BASE']);
1369     foreach($Actions['Remove'] as $dn){
1370       $ldap->cd($dn);
1371       $ldap->cat($dn);
1372       if($ldap->count()){
1373         $ldap->rmdir_recursive($dn);
1374         if (!$ldap->success()){
1375           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1376         }
1377       }
1378     }
1379     
1380     /* Add new entries
1381      */
1382     foreach($Actions['Add'] as $dn => $data){
1383       $this->tag_attrs($data,$dn,$this->gosaUnitTag);
1384       $ldap->cd($dn);
1385       $ldap->cat($dn);
1386       if(!$ldap->count()){
1387         $ldap->add($data);
1388         if (!$ldap->success()){
1389           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
1390         }
1391       }
1392     }
1394     /* Modify entries
1395      */
1396     foreach($Actions['Edit'] as $dn => $data){
1397       $this->tag_attrs($data,$dn,$this->gosaUnitTag);
1398       $ldap->cd($dn);
1399       $ldap->cat($dn);
1400       if($ldap->count()){
1401         $ldap->modify($data);
1402         if (!$ldap->success()){
1403           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
1404         }
1405       }
1406     }
1408     $this->_load_menu_structure();
1409   }
1412   /*! \brief  Return plugin informations for acl handling  
1413       @return Array containing all plugin ACL informations
1414    */ 
1415   static function plInfo()
1416   {
1417     return (array(
1418           "plShortName"   => _("Applications"),
1419           "plDescription" => _("Group applications"),
1420           "plSelfModify"  => FALSE,
1421           "plDepends"     => array(),
1422           "plPriority"    => 7,
1423           "plSection"     => array("administration"),
1424           "plCategory"    => array("groups"),
1425           "plProvidedAcls"=> array(
1426             "gosaMemberApplication"     => _("Application"),
1427             "FAIrelease"                => _("Release"),
1428             "gosaApplicationParameter"  => _("Application parameter"),
1429             "placeOnDesktop"      => _("Place icon on members desktop"),            // D
1430             "placeOnKicker"       => _("Place entry in members launch bar"),        // L
1431             "placeInStartmenu"    => _("Place entry in members startmenu")         // M
1432           )));
1433   }
1436   /* \brief   Prepare this plugin to be copied.
1437               Adapt all required attributes from the source object.
1438               In this case, update the menu structure too, mark all elements
1439                as newly added, so they will be saved in save();
1440    */
1441   function PrepareForCopyPaste($source)
1442   {
1443     plugin::PrepareForCopyPaste($source);
1444    
1445     $tmp = new appgroup($this->config,$source['dn']);
1446     $this->is_account = TRUE;
1447     $this->a_Structure = $tmp->a_Structure;
1448     $all = $this->_get_all_entries();
1449     foreach($all as &$entry){
1450       if(isset($entry['STATUS'])){
1451         $entry['STATUS'] = "ADDED";
1452       }
1453     }
1454   }
1457   /*! \brief  Save HTML posts in multiple edit mode
1458    */
1459   function multiple_save_object()
1460   {
1461     if(isset($_POST['group_apps_multi'])){
1462       $this->save_object(); 
1463       plugin::multiple_save_object();    
1464   
1465       /* Get posts */
1466       foreach(array("apps") as $attr){
1467         if(isset($_POST['use_'.$attr])) {
1468           $this->multi_boxes[] = $attr;
1469         }
1470       }
1471     }
1472   }
1473   
1475   /*! \brief  Return values used in multiple edit mode.
1476               Some values can be modified for multiple 
1477               groups at the same time.
1478       @return Array  All values that support multiple edit.
1479    */
1480   function get_multi_edit_values()
1481   {
1482     $ret = plugin::get_multi_edit_values();
1484     if(in_array("apps",$this->multi_boxes)){
1485       $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1486       $ret['Categories']               = $this->Categories;
1487       $ret['gosaMemberApplication']    = $this->gosaMemberApplication;
1488       $ret['FAIrelease']               = $this->FAIrelease;
1489       $ret['appoption']                = $this->appoption;
1490     }
1491     return($ret);
1492   }
1494 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1495 ?>