Code

Group Application
[gosa.git] / gosa-plugins / goto / admin / groups / apps / class_groupApplication.inc
1 <?php
2 class appgroup extends plugin
3 {
4   /* CLI vars */
5   var $cli_summary= "Manage application groups";
6   var $cli_description= "Some longer text\nfor help";
7   var $cli_parameters= array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
10   var $config;
11   var $curbase;
13   /* Contains the menu structure in an array.
14    */
15   var $a_Structure= array();
16   var $a_Structure_on_load = array();
17   var $Releases;
18   var $FAIrelease = 0;
19   var $apps = array();
20   var $_cache = array();
22   var $app_parameter = array();
23   var $edit_entry    = array();
24   var $enableReleaseManagement = FALSE;
25   
27   public function __construct(&$config, $dn= NULL, $parent= NULL)
28   {
29     plugin::plugin($config,$dn,$parent);
30     $this->dn = $dn; 
31     $this->_load_menu_structure();
32     $this->a_Structure_on_load = $this->a_Structure;
34     /* Check if we have relase mangement enabled and prepare group application for release management */
35     $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
36     if(!empty($tmp)){
37       $this->enableReleaseManagement = true;
38     }
40     $this->Releases   = $this->getReleases();
41     $this->FAIrelease = "/";
42     $this->curbase = $this->config->current['BASE'];
43     $this->reload();
44   
45     $this->is_account = FALSE;
46     if(count($this->_get_all_entries()) > 1){
47       $this->is_account= TRUE;
48     }   
49     $this->initially_was_account = $this->is_account;
50   }
53   /*! \brief Reload the list of applications for the currently selected release 
54    */
55   function reload()
56   {
57     $ret = array();
58     $release_info = $this->Releases[$this->FAIrelease];
60     if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
62       $ldap = $this->config->get_ldap_link();
63       $ldap->cd($this->config->current['BASE']);
64       $ldap->search("ou=apps",array("dn"));
65       $app_deps = array();
66       while($attrs = $ldap->fetch()){
67         $app_deps[] = $attrs['dn'];
68       }
70       foreach($app_deps as $dep){
71         $ldap->cd($dep);
72         $ldap->search("objectClass=FAIbranch",array("dn"));
73         while($attrs = $ldap->fetch()){
74           $app_deps[] = $attrs['dn'];
75         }
76       }
78       foreach($app_deps as $dep){
79         if(preg_match("/^".normalizePreg($release_info['suffix'])."/",$dep)){
80           $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
81         }
82       }
83       $this->_cache['ReleaseApps'][$release_info['suffix']] = $ret;
84     } 
85     $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
86   }
88   
89   
90   
91   /*! \brief generate a list of available releases
92       @return return an array with all available releases.
93     */
94   function getReleases()
95   {
96     $ret =array("/" => array("name" => "/" , "parts" => array(),"suffix" => get_ou('applicationou')));
97     if($this->enableReleaseManagement){
99       /* Only display those releases that we are able to read */
100       $dn     = $this->config->current['BASE'];
101       $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
102       $res    = get_list($filter,"application", $dn, array("ou","FAIstate"), GL_SUBSEARCH);
104       foreach($res as $attrs){
105         if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
106           $bb     = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
107           $parts  = array_reverse(split("ou=",$bb));
109           $str ="";
110           foreach($parts as $key => $part){
111             if(empty($part)) {
112               unset($parts[$key]);
113               continue;
114             }
115             $part = str_replace(",","",$part);
116             $str .= $part."/";
117             $parts[$key] = $part;
118           }
119           $name = preg_replace("/\/$/","",$str);
120           if(empty($name)) {
121             $name ="/";
122           }
123           $FAIstate = "";
124           if(isset($attrs['FAIstate'])){
125             $FAIstate = $attrs['FAIstate'][0];
126           }
128           $ret[$name] = array("name"     => $name, 
129               "FAIstate" => $FAIstate,
130               "dn"       => $attrs['dn'], 
131               "parts"    => $parts,"suffix" => $bb.get_ou('applicationou'));
132         }
133       }
134     }
135     ksort($ret);
136     return($ret);
137   }
140   /*! \brief Load the menu structure from ldap and create a multi dimensional array
141    */
142   function _load_menu_structure()
143   {
144     $this->a_Structure  = array();
145     $ldap = $this->config->get_ldap_link();
146     $ldap->cd($this->dn);
147     $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
149     $base =  array();
150     $base['UNIQID'] = uniqid();
151     $base['PARENT'] = 0; 
152     $base['NAME']   = "";
153     $base['TYPE']   = "BASE";
154     $base['ENTRIES']= array();
155     $base['STATUS'] = "LOADED";
156     
157     $this->a_Structure[0] = $base;
159     while($attrs = $ldap->fetch()){
160       $cur = &$this->a_Structure[0]['ENTRIES'];
161       $parent_id    = $base['UNIQID'];
162       $sub_dn       = preg_replace("/,".normalizePreg($this->dn)."$/","",$attrs['dn']);
163       $sub_dn_array = split("\,",$sub_dn);
166       for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
167         $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
168         if($i > 0){
169           foreach($cur as $key => $entry){
170             if($entry['NAME'] == $name){
171               $cur = &$cur[$key]['ENTRIES'];
172               $parent_id = $entry['UNIQID'];
173             }
174           }
175         }else{
177           $priority = 1;
178           if(isset($attrs['gosaApplicationPriority'])){
179             $priority= $attrs['gosaApplicationPriority'][0];
180           }
181           while(isset($cur[$priority])){
182             $priority ++;
183           }
185           $data = array();
186           if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
187             $type = "FOLDER";
189             $data['ICON'] = "";
190             if(isset($attrs['gosaApplicationIcon'])){
191               $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
192             }
194           }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
195             $type = "ENTRY";
196             $data['INFO'] = "";
197             $data['PARAMETER'] = array();
198             if(isset($attrs['gosaApplicationParameter'])){
199               for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
200                 $tmp = split(":",$attrs['gosaApplicationParameter'][$p]);
201                 $data['PARAMETER'][$tmp[0]] = $tmp[1];
202               }
203             }
204           }elseif(in_array("FAIbranch",$attrs['objectClass'])){
206             $type = "RELEASE";
207             if(isset($attrs['FAIstate'][0])){
208               $data['FAIstate'] = $attrs['FAIstate'][0];
209             }else{
210               $data['FAIstate'] = "";
211             }
212           }
214           $data['DN']       = $attrs['dn'];
215           $data['NAME']     = $name;
216           $data['TYPE']     = $type;
217           $data['PRIORITY'] = $priority;
218           $data['ENTRIES']  = array();
219           $data['UNIQID']   = uniqid();
220           $data['PARENT']   = $parent_id;
221           $data['STATUS']   = "LOADED";
222           $cur[$priority]   = $data;
223           ksort($cur);
224         }
225       }
226     }
227   } 
230   function execute()
231   {
232     /* Call parent execute */
233     plugin::execute();
235     if (isset($_POST['modify_state'])){
236       $this->is_account = !$this->is_account;
237     }
239     /* Do we represent a valid account? */
240     if (!$this->is_account){
241       $display= $this->show_enable_header(_("Add application extension"),
242           _("Application extension disabled. You can enable it by clicking below."));
243       return ($display);
244     }
246     $display =  $this->show_enable_header(_("Remove application extension"),
247           _("Application extension enabled. You can disable it by clicking below."));
250     if(isset($_GET['send'])){
251       $id = $_GET['send'];
252       $all = $this->_get_all_entries();
253       if(isset($all[$id])){
254         send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
255         exit;
256       }
257     }
259     if(isset($_GET['r']))
260     $this->__construct($this->config,$this->dn);
262     if(count($this->edit_entry)){
263       if($this->edit_entry['TYPE'] == "ENTRY"){
264         $smarty = get_smarty();
265         $smarty->assign("type", "ENTRY");
266         $smarty->assign("entry",$this->edit_entry);
267         $smarty->assign("paras",$this->app_parameter);
268         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
269         return($display);
270       }
271       if($this->edit_entry['TYPE'] == "FOLDER"){
272         $smarty = get_smarty();
274         session::set("binarytype" , "image/jpeg");
275         session::set("binary" , $this->edit_entry['ICON']);
276   
277         $smarty->assign("rand", microtime(TRUE));
278         $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0); 
279         $smarty->assign("type", "FOLDER");
280         $smarty->assign("entry",$this->edit_entry);
281         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
282         return($display);
283       }
284     }
286     $smarty = get_smarty();
287     $smarty->assign("plug_id" , $_GET['plug']);
289     /* Create application list */
290     $div = new divSelectBox("appgroup");
291     $div->SetHeight(300);
292     $departments = array();
293     $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
294     foreach($res as $value){
295       $fdn = $value['dn'];
296       $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
297       $fdn= @LDAP::fix($fdn);
298       if($value["description"][0]!=".."){
299         $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
300       }else{
301         $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
302       }
303     }
305     $linkopen = "<a href='?plug=".$_GET['plug']."&amp;act=depopen&amp;depid=%s'>%s</a>";
307     /* Create base back entry */
308     $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
309     if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
310       $div->AddEntry(array(
311             array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
312               "attach"=>"style='border:0px;'")
313             ));
314     }
316     /* Append departments for current base */
317     foreach($departments as $key => $app){
318       $div->AddEntry(array(
319             array("string"=>"<img class='center' src='images/folder.png' alt='"._("department")."'>&nbsp;".sprintf($linkopen,
320                 base64_encode($key),$app),
321               "attach"=>"style='border:0px;'")
322             ));
323     }
325   
326     /* Add applications found on this base */
327     $used_apps = $this->_get_used_entry_name();
328     foreach($this->apps as $key => $app){
329       if(in_array($app['cn'][0],$used_apps)){
330         continue;
331       }
332       if(!preg_match("/".get_ou('applicationou').normalizePreg($this->curbase)."$/",$app['dn'])){
333         continue;
334       }
336       $name = $app['cn'][0];
337       if(isset($app['description'])){
338         $name .= "&nbsp;[".$app['description'][0]."]";
339       }
340       $div->AddEntry(array(
341             array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
342               "<img class='center' src='images/select_application.png' alt='"._("application")."'>&nbsp;".$name,
343               "attach"=>"style='border:0px;'")
344             ));
345     }
347     
348     $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
349     $smarty->assign("FAIrelease",$this->FAIrelease);
350     $smarty->assign("app_list",$div->DrawList());
351     $smarty->assign("releases",$this->Releases);
352     $smarty->assign("folders" , $this->_get_folder_names());
353     $entries = $this->_get_entries_for_release($this->FAIrelease);
354     $smarty->assign("entries",$entries);
355     $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
356     return($display);
357   }
359    
360   /*! \brief Returns all used folder names 
361       @return Array  All used folder names.
362    */ 
363   function _get_folder_names()
364   {
365     $data = $this->_get_entries_for_release($this->FAIrelease);
366     $ret = array("BASE" => ".");
367     foreach($data as $entry){
368       if($entry['TYPE'] == "FOLDER"){
369         $ret[$entry['UNIQID']] = $entry['NAME'];
370       }
371     }
372     return($ret);
373   }
376   /*! \brief return all used applications 
377       @return Array  All used applications.
378    */ 
379   function _get_used_entry_name()
380   {
381     $data = $this->_get_entries_for_release($this->FAIrelease);
382     $ret = array();
383     foreach($data as $entry){
384       if($entry['TYPE'] == "ENTRY"){
385         $ret[] = $entry['NAME'];
386       }
387     }
388     return($ret);
389   }
392   /*! \brief Returns all folder an entries for the selected release 
393       @return Array  Returns the complete menu structure for the given array.
394    */ 
395   function _get_entries_for_release($release,$cur = NULL)
396   {
397     $all = $this->_get_all_entries();
398     $key = $this->_get_release_key($release);
399     if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
400       $res = $this->_get_all_entries(TRUE,TRUE,&$all[$key]['ENTRIES']);
401       return($res);
402     } 
403     return(array());
404   }
407   /*! \brief Save the currently edited entry */
408   function _save_entry_edit()
409   {
410     $all    = $this->_get_all_entries();
411     $entry  = $this->edit_entry;
412     $r_entry= &$all[$entry['UNIQID']];
414     if($entry['TYPE'] == "ENTRY"){
415       $r_entry['PARAMETER'] = $this->app_parameter;
416       $r_entry['STATUS'] = "EDITED";
417     }
418     if($entry['TYPE'] == "FOLDER"){
419       $r_entry['ICON']   = $this->edit_entry['ICON'];
420       $r_entry['STATUS'] = "EDITED";
421     }
422     $this->dialog = FALSE;
423     $this->edit_entry = array();
424   }
427   /*! \brief prepare the entry with the given ID, to be edited.
428    */
429   function _edit_entry_edit($id)
430   {
431     $all   = $this->_get_all_entries();
432     $entry = $all[$id];
434     $this->app_parameter = array();
435     if($entry['TYPE'] == "ENTRY"){
436       $found = FALSE;
437       foreach($this->apps as $id => $app){
439         if($app['cn'][0] == $entry['NAME']){
440           $found = TRUE;
441           break;
442         }
443       }
444       if($found){
445       
446         /* Create a list of editable parameter */
447         if(isset($app['gosaApplicationParameter'])){
448           for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
449             $para = $app['gosaApplicationParameter'][$i];
450             $tmp  = split(":",$para);
451             $this->app_parameter[$tmp[0]] = $tmp[1];
452           }
453         }
455         /* Overwrite parameters with entry parameters */
456         foreach($entry['PARAMETER'] as $name => $value){
457           $this->app_parameter[$name] = $value;
458         }
459         
460         $this->dialog = TRUE;
461         $this->edit_entry = $entry;
462       }
463     }
465     if($entry['TYPE'] == "FOLDER"){
466       $this->dialog = TRUE;
467       $this->edit_entry = $entry;
468     }
469   }
472   function remove_from_parent()
473   {
474     $ldap = $this->config->get_ldap_link();
475     $ldap->cd($this->dn);
476     $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
477     $a_remove = array();
478     while($attrs = $ldap->fetch()){
479       $a_remove[] = $attrs['dn'];
480     }
481     foreach($a_remove as $remove){
482       $ldap->rmdir_recursive($remove);
483       show_ldap_error($ldap->get_error(),
484           sprintf(_("Removing of group/application account with dn '%s' failed, could not remove '%s'."),
485             $this->dn,$remove));
486     }
487     $this->_load_menu_structure();
488   }
491   function check()
492   {
493   }
496   /*! \brief Create missing releases, if there is a release selected \
497               that is currently not part of the menu structure \
498               then create this entry
499    */
500   function _check_missing_release($release)
501   {
502     $release_info = $this->Releases[$release];
504     $parent_id = $this->a_Structure[0]['UNIQID'];
505     $cur = &$this->a_Structure[0]['ENTRIES'];
506     for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
507       $part = $release_info['parts'][$i];
508       $found = FALSE;
509       foreach($cur as $key => $name){
510         if($name['NAME'] == $part){
511           $parent_id = $cur[$key]['UNIQID'];
512           $cur = &$cur[$key]['ENTRIES'];
513           
514           $found =TRUE;
515           break;
516         }
517       }
518       if(!$found){
519         $release           =  array();
520         $release['UNIQID'] = uniqid();
521         $release['PARENT'] = $parent_id;
522         $release['NAME']   = $part;
523         $release['TYPE']   = "RELEASE";
524         $release['ENTRIES']= array();
525         $release['STATUS']   = "ADDED";
526         $release['FAIstate'] =  $release_info['FAIstate'];
527         $cur[] = $release;
528         $i --;
529       }
530     }
531   }
535   function _move_entry($id,$dir)
536   {
537     $all   = $this->_get_all_entries();
538     if($dir == "down"){
539       $to = $this->_get_next($id);
540     } 
541     if($dir == "up"){
542       $to = $this->_get_last($id);
543     }
545     if(!$to){
546       return;
547     }
549     $o_to   = $all[$to];
550     $o_from = $all[$id];
552     if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
553       $to    = $this->_get_next($to,$o_from['PARENT']); 
554       $o_to  = $all[$to]; 
555     }
556  
557  
558     /* Target is ENTRY && same BASE, just switch */
559     if($o_to['PARENT'] == $o_from['PARENT'] ){
560       $parent = $all[$o_to['PARENT']];
561       $pos = 0;
562       foreach($parent['ENTRIES'] as $entry){
563         $pos ++;
564         if($entry['UNIQID'] == $to){
565           break;
566         }
567       }
568       if($dir == "up" && $pos > 0){
569         $pos --;
570       }
571       $this->_add_entry($parent['UNIQID'],$o_from,$pos);
572       $this->_remove_entry_id($id);
573       return(TRUE);
574     }
575     return(FALSE);
576   }
579  
580   function _get_last($id)
581   {
582     $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
583     for($i = 0 ; $i < count($all_l) ; $i ++){
584       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
585         $i++;
586         break;
587       }
588     }
589     while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
590       $i++;
591     }
593     if(!isset($all_l[$i])){
594       return(FALSE);
595     }
597     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
598       return($all_l[$i]['PARENT']);
599     }     
601     return($all_l[$i]['UNIQID']);
602   }
604  
605   function _get_next($id,$parent = 0)
606   {
607     $all_l = $this->_get_entries_for_release($this->FAIrelease);
608     for($i = 0 ; $i < count($all_l) ; $i ++){
609       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
610         $i++;
611         break;
612       }
613     }
614     if($parent != 0){
615       while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
616         $i++;
617       }
618     }else{
619       while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
620         $i++;
621       }
622     }
623     if(!isset($all_l[$i])){
624       return(FALSE);
625     }
626     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
627       return($all_l[$i]['PARENT']);
628     }
629     return($all_l[$i]['UNIQID']);
630   }
635   /* !\brief Handle ui POSTS, like sort up/down/delete
636    */ 
637   function save_object()
638   {
639     foreach($_POST as $name => $value){
640       if(preg_match("/del_/",$name)){
641         $id = preg_replace("/^del_/","",$name);
642         $id = preg_replace("/_(x|y)$/","",$id);
643         $this->_remove_entry_id($id);
644         break;
645       }
646       if(preg_match("/app_entry_edit/",$name)){
647         $id = preg_replace("/^app_entry_edit/","",$name);
648         $id = preg_replace("/_(x|y)$/","",$id);
649         $this->_edit_entry_edit($id);
650         break;
651       }
652       if(preg_match("/up_/",$name)){
653         $id = preg_replace("/^up_/","",$name);
654         $id = preg_replace("/_(x|y)$/","",$id);
655         $this->_move_entry($id,"up");
656         break;
657       }
658       if(preg_match("/down_/",$name)){
659         $id = preg_replace("/^down_/","",$name);
660         $id = preg_replace("/_(x|y)$/","",$id);
661         $this->_move_entry($id,"down");
662         break;
663       }
664       if(preg_match("/^parameter_/",$name) && 
665         count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
666         $name = preg_replace("/^parameter_/","",$name);
667         $this->app_parameter[$name] = $value;
668       }
669     }
670     if(isset($_POST['FAIrelease'])){
671       $this->FAIrelease = $_POST['FAIrelease'];
672       $this->_check_missing_release($this->FAIrelease);
673     }
674     if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
675       $this->curbase = base64_decode($_GET['depid']);
676     }
677     if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
678       $folder = $_POST['folder'];
679       foreach($_POST as $name => $value){
680         if(preg_match("/^AddApp_[0-9]*$/",$name)){
681           $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));   
682         }
683       }
684     }
685     if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
686       $folder = $_POST['menu_folder'];
687       $name = $_POST['menu_folder_name'];
688       if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
689         $this->_add_sub_folder($folder,$name);
690       }
691     }
692     if(isset($_POST['app_entry_save'])){ 
693       $this->_save_entry_edit();
694     }
696     if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
697       if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
698         $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
699       }
700     }
702     if(isset($_POST['edit_reset_image'])){
703       $this->edit_entry['ICON'] = "";
704     }
706     if(isset($_POST['app_entry_cancel'])){
707       $this->edit_entry = array();
708       $this->dialog = FALSE;
709     }
710     $this->reload();
711   }
713  
714   /*! \brief Returns the UNIQID of the currently selected release 
715    */ 
716   function _get_release_key($release,$add_if_missing = FALSE)
717   {
718     $release_info = $this->Releases[$release];
720     if($release_info['name'] == "/"){
721       return($this->a_Structure['0']['UNIQID']);
722     }
724     $cur = &$this->a_Structure[0]['ENTRIES'];
725     $s_key = "";
726     $found = FALSE;
727     foreach($release_info['parts'] as $name){
728       foreach($cur as $key => $obj){
729         if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
730           $s_key = $cur[$key]['UNIQID'];
731           $cur = &$cur[$key]['ENTRIES'];
732           $found = TRUE;
733           break;
734         }
735         $found = FALSE;
736       }
737     }
738     if($found){
739       return($s_key);  
740     }  
741     return(FALSE);
742   }
744  
745   /*! \brief Add a new folder folder to the specified folder id
746       @param  String $folder The folder id in where we want to add the new folder.
747       @param  String $name   The name of the new folder.
748    */ 
749   function _add_sub_folder($folder,$name)
750   {
751     $all = $this->_get_all_entries();
752     if($folder == "BASE"){
753       $folder = $this->_get_release_key($this->FAIrelease,TRUE);
754     }
755     
756     if(isset($all[$folder])){
757       $a_folder = array();
758       $a_folder['STATUS'] = "ADDED";
759       $a_folder['NAME']   = $name;
760       $a_folder['UNIQID'] = uniqid();
761       $a_folder['ENTRIES']= array();
762       $a_folder['PARENT'] = $folder;      
763       $a_folder['TYPE']   = "FOLDER";
764       $a_folder['ICON']   = "";
765       $all[$folder]['ENTRIES'][] = $a_folder;
766     }
767   }
770   /* !\brief Remove the given id from the menu structure.
771       @param  String  ID to of the entry we want to remove.
772       @return Boolean TRUE on success
773    */
774   function _remove_entry_id($id)
775   {
776     $all = $this->_get_all_entries();
777     if(isset($all[$id])){
778       $all[$id]['STATUS'] = "REMOVED";
779       return(TRUE);
780     }
781     return(FALSE);
782   }
784   
785   /* !\brief Remove the given id from the menu structure.
786       @param  String  ID to of the entry we want to remove.
787       @return Boolean TRUE on success
788    */
789   function _add_entry($folder_id,$entry,$pos = 0)
790   {
791     $all = $this->_get_all_entries();
793     /* Do not add removed */
794     if($entry['STATUS'] == "REMOVED"){
795       return;
796     }
798     if(isset($all[$folder_id])){
800       $folder  = &$all[$folder_id];
801       $entries = $entry['ENTRIES'];
803       $entry['UNIQID'] = uniqid();     
804       $entry['PARENT'] = $folder_id;
805       $entry['ENTRIES']= array();
806       $entry['STATUS'] = "ADDED";
807       
808       $cnt = 0; 
809       $new = array();
810       $added =FALSE;
811       foreach($folder['ENTRIES'] as $key => $obj){
812         if($obj['STATUS'] == "LOADED"){
813           $obj['STATUS'] = "EDITED";
814         }
815         if($pos == $cnt){
816           $new[] = $entry;
817           $added = TRUE;
818         }
819         $cnt ++;
820         $new[] = $obj;
821       }
822       if(!$added){
823         $new[] = $entry;
824       }
825   
826       $all[$folder_id]['ENTRIES'] = $new;
827       foreach($entries as $sub){
828         $this->_add_entry($entry['UNIQID'],$sub,-1);
829       }
830       return(TRUE);
831     }
832     return(FALSE);
833   }
835  
836   /*! \brief Add the application identified by $app_id to folder $folder_id 
837       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
838       @param  Integer app_id    The ID of the application which should be added.
839    */ 
840   function _add_app_id($folder_id,$app_id)
841   {
842     $all = $this->_get_all_entries();
843     if($folder_id == "BASE"){
844       $folder_id = $this->_get_release_key($this->FAIrelease);
845     }
846     if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
848       $new = array();
849       $new['TYPE']  = "ENTRY";
850       $new['NAME']  = $this->apps[$app_id]['cn'][0];
851       $new['UNIQID']= uniqid(); 
852       $new['PARENT']= $folder_id;
853       $new['PARAMETER']= array();
854       if(isset($this->apps[$app_id]['description'][0])){
855         $new['INFO']  = $this->apps[$app_id]['description'][0];
856       }else{
857         $new['INFO']  = "";
858       }
859       $new['STATUS']= "ADDED";
860       $all[$folder_id]['ENTRIES'][] = $new;
861     }
862   }
865   /*! \brief  Return all entries linear. 
866       @param  Boolean   $add_tags  If TRUE, OPEN/CLOSE Tags will be appended.
867       @param  &Array    Start here, Pointer to an array.
868    */ 
869   function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, $cur = NULL)
870   {
871     $ret = array();
872     if($cur == NULL){
873       $cur = &$this->a_Structure;
874     }
875     foreach($cur as $key => $entry){
877       if($skip_release && $entry['TYPE'] == "RELEASE"){
878         continue;
879       }    
880       if($entry['TYPE'] == "ENTRY"){
881         $found = FALSE;
882         foreach($this->apps as $app){
883           if($app['cn'][0] == $entry['NAME']){
884             $found = TRUE;
885             if(isset($app['description'][0])){
886               $entry['INFO'] = "[".$app['description'][0]."]";
887             }
888             break;
889           }
890         } 
891         if(!$found){
892           $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
893         }
894       }
895       
897       $tmp = $entry;
898       if(!$add_tags){
899         $ret[$tmp['UNIQID']] = &$cur[$key];
900         if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
901           $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
902         }
903       }else{
904       
905         if(isset($tmp['ENTRIES'])){
906           unset($tmp['ENTRIES']);
907         }
908         if($tmp['STATUS'] != "REMOVED"){
909           $ret[] = $tmp;
910           if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
911             $add = false;
912             foreach($entry['ENTRIES'] as $entry){
913               if($entry['STATUS'] != "REMOVED"){
914                 $add = TRUE;
915                 break;
916               }
917             }
919             if($add){
920               $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
921               $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
922               $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
923             }
924           }
925         }
926       }
927     }
928     return($ret);
929   }
932   function save()
933   {
934     $ldap = $this->config->get_ldap_link();
935     $all = $this->_get_all_entries();
936     $prio = 0;
937     $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
939     foreach($all as $entry){
940       $prio ++;
941       $cur = $entry;
942       $dn = "";
944       do{  
945         if($cur['TYPE'] == "ENTRY"){
946           $dn.= "cn=".$cur['NAME'].",";
947         }elseif($cur['TYPE'] == "FOLDER"){
948           $dn.= "cn=".$cur['NAME'].",";
949         }elseif($cur['TYPE'] == "RELEASE"){
950           $dn.= "ou=".$cur['NAME'].",";
951         }elseif($cur['TYPE'] == "BASE"){
952         }
953         if(!isset($all[$cur['PARENT']])){
954           $cur = NULL;
955         }else{
956           $cur = $all[$cur['PARENT']];
957         }
958       }while(is_array($cur));
960       $cur_dn = $dn.$this->dn;
962       $attrs = array();
963       switch($entry['TYPE']){
964         case "ENTRY"    :
965         { 
966           $attrs['objectClass'] = "gotoMenuEntry";
967           $attrs['cn']          = $entry['NAME'];
968           $attrs['gosaApplicationPriority'] = $prio;
969           $attrs['gosaApplicationParameter'] = array(); 
970           
971           
972           foreach($entry['PARAMETER'] as $name => $value){
973             $attrs['gosaApplicationParameter'][] = $name.":".$value; 
974           }
975           if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
976             unset($attrs['gosaApplicationParameter']);
977           } 
978         }
979         break;
980         case "FOLDER"   : 
981         { 
982           $attrs['objectClass'] = "gotoSubmenuEntry";
983           $attrs['cn']          = $entry['NAME'];
984           $attrs['gosaApplicationPriority'] = $prio;
985           if($entry['STATUS'] != "ADDED"){
986             $attrs['gosaApplicationIcon'] = array();
987           }
988           
989           if(!empty($entry['ICON'])){
990             $attrs['gosaApplicationIcon']     = $entry['ICON'];
991           }
992         }
993         break;
994         case "RELEASE"  : 
995         { 
996           $attrs['ou']            = $entry['NAME'];
997           $attrs['objectClass']   = array();
998           $attrs['objectClass'][] = "top";
999           $attrs['objectClass'][] = "organizationalUnit";
1000           $attrs['objectClass'][] = "FAIbranch";
1001           if(!empty($entry['FAIstate'])){
1002             $attrs['FAIstate']      = $entry['FAIstate'];
1003           }
1004         }
1005         break;
1006       }
1007   
1008       if($entry['STATUS'] == "LOADED"){
1009         continue;
1010       }
1011       if($entry['STATUS'] == "REMOVED"){
1012         $Actions['Remove'][$cur_dn] = $cur_dn;
1013       }
1014       if($entry['STATUS'] == "EDITED"){
1015         $Actions['Edit'][$cur_dn] = $attrs;
1016       }
1017       if($entry['STATUS'] == "ADDED"){
1018         $Actions['Add'][$cur_dn] = $attrs;
1019       }
1020     }
1022     $ldap = $this->config->get_ldap_link();
1023     $ldap->cd($this->config->current['BASE']);
1024     foreach($Actions['Remove'] as $dn){
1025       $ldap->cd($dn);
1026       $ldap->cat($dn);
1027       if($ldap->count()){
1028         $ldap->rmdir_recursive($dn);
1029         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1030       }
1031     }
1032     foreach($Actions['Add'] as $dn => $data){
1033       $ldap->cd($dn);
1034       $ldap->cat($dn);
1035       if(!$ldap->count()){
1036         $ldap->add($data);
1037         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1038       }
1039     }
1040     foreach($Actions['Edit'] as $dn => $data){
1041       $ldap->cd($dn);
1042       $ldap->cat($dn);
1043       if($ldap->count()){
1044         $ldap->modify($data);
1045         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1046       }
1047     }
1048     $this->_load_menu_structure();
1049   }
1052   /* Return plugin informations for acl handling  */ 
1053   static function plInfo()
1054   {
1055     return (array(
1056           "plShortName"   => _("Applications"),
1057           "plDescription" => _("Group applications"),
1058           "plSelfModify"  => FALSE,
1059           "plDepends"     => array(),
1060           "plPriority"    => 0,
1061           "plSection"     => array("admin"),
1062           "plCategory"    => array("groups"),
1063           "plProvidedAcls"=> array(
1064             "gosaMemberApplication"     => _("Application"),
1065             "FAIrelease"                => _("Release"),
1066             "gosaApplicationParameter"  => _("Application parameter"))
1067           ));
1068   }
1071   function PrepareForCopyPaste($source)
1072   {
1073   }
1076   function multiple_save_object()
1077   {
1078     if(isset($_POST['group_apps_multi'])){
1079       $this->save_object(); 
1080       plugin::multiple_save_object();    
1081   
1082       /* Get posts */
1083       foreach(array("apps") as $attr){
1084         if(isset($_POST['use_'.$attr])) {
1085           $this->multi_boxes[] = $attr;
1086         }
1087       }
1088     }
1089   }
1090   
1092   function get_multi_edit_values()
1093   {
1094     $ret = plugin::get_multi_edit_values();
1096     if(in_array("apps",$this->multi_boxes)){
1097       $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1098       $ret['Categories']               = $this->Categories;
1099       $ret['gosaMemberApplication']    = $this->gosaMemberApplication;
1100       $ret['FAIrelease']               = $this->FAIrelease;
1101       $ret['appoption']                = $this->appoption;
1102     }
1103     return($ret);
1104   }
1106 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1107 ?>