Code

Updated group Applications.
[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       }
84       $tmp = array();
85       foreach($ret as $key => $app){
86         $tmp[$key] = $app['cn'][0];
87       }
88       natcasesort($tmp);
89       $res = array();
90       foreach($tmp as $key => $app){
91         $res[] = $ret[$key];
92       }
94       $this->_cache['ReleaseApps'][$release_info['suffix']] = $res;
95     } 
96     $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
97   }
99   
100   
101   
102   /*! \brief generate a list of available releases
103       @return return an array with all available releases.
104     */
105   function getReleases()
106   {
107     $ret =array("/" => array("name" => "/", "found" => TRUE , "parts" => array(),"suffix" => get_ou('applicationou')));
108     if($this->enableReleaseManagement){
110       /* Only display those releases that we are able to read */
111       $dn     = $this->config->current['BASE'];
112       $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
113       $res    = get_list($filter,"application", $dn, array("ou","FAIstate"), GL_SUBSEARCH);
115       foreach($res as $attrs){
116         if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
117           $bb     = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
118           $parts  = array_reverse(split("ou=",$bb));
120           $str ="";
121           foreach($parts as $key => $part){
122             if(empty($part)) {
123               unset($parts[$key]);
124               continue;
125             }
126             $part = str_replace(",","",$part);
127             $str .= $part."/";
128             $parts[$key] = $part;
129           }
130           $name = preg_replace("/\/$/","",$str);
131           if(empty($name)) {
132             $name ="/";
133           }
134           $FAIstate = "";
135           if(isset($attrs['FAIstate'])){
136             $FAIstate = $attrs['FAIstate'][0];
137           }
139           $all = $this->_get_all_entries();
140           $found = FALSE;
141           foreach($all as $entry){
142             if(isset($entry['DN']) && preg_match("/^".normalizePreg($bb)."/",$entry['DN'])){
143               $found =TRUE;
144               break;
145             }
146           }
148           $cnt = 0;
149           $ret[$name] = array("name"     => $name, 
150               "found"    => $found,
151               "FAIstate" => $FAIstate,
152               "dn"       => $attrs['dn'], 
153               "parts"    => $parts,"suffix" => $bb.get_ou('applicationou'));
154         }
155       }
156     }
157     ksort($ret);
158     return($ret);
159   }
162   /*! \brief Load the menu structure from ldap and create a multi dimensional array
163    */
164   function _load_menu_structure()
165   {
166     $this->a_Structure  = array();
167     $ldap = $this->config->get_ldap_link();
168     $ldap->cd($this->dn);
169     $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
171     $base =  array();
172     $base['UNIQID'] = uniqid();
173     $base['PARENT'] = 0; 
174     $base['NAME']   = "";
175     $base['TYPE']   = "BASE";
176     $base['ENTRIES']= array();
177     $base['STATUS'] = "LOADED";
178     
179     $this->a_Structure[0] = $base;
181     while($attrs = $ldap->fetch()){
182       $cur = &$this->a_Structure[0]['ENTRIES'];
183       $parent_id    = $base['UNIQID'];
184       $sub_dn       = preg_replace("/,".normalizePreg($this->dn)."$/","",$attrs['dn']);
185       $sub_dn_array = split("\,",$sub_dn);
187       $found = true;
188       for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
189         $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
190         
191         if($i > 0){
192           $found =FALSE;
193           foreach($cur as $key => $entry){
194             if($entry['NAME'] == $name){
195               $cur = &$cur[$key]['ENTRIES'];
196               $parent_id = $entry['UNIQID'];
197               $found =true;
198               break;
199             }
200           }
201         }else{
202           
203           if(!$found){
204             break;
205           }
206           $priority = 1;
207           if(isset($attrs['gosaApplicationPriority'])){
208             $priority= $attrs['gosaApplicationPriority'][0];
209           }
210           while(isset($cur[$priority])){
211             $priority ++;
212           }
214           $data = array();
215           if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
216             $type = "FOLDER";
218             $data['ICON'] = "";
219             if(isset($attrs['gosaApplicationIcon'])){
220               $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
221             }
223           }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
224             $type = "ENTRY";
225             $data['INFO'] = "";
226             $data['PARAMETER'] = array();
227             if(isset($attrs['gosaApplicationParameter'])){
228               for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
229                 $tmp = split(":",$attrs['gosaApplicationParameter'][$p]);
230                 $data['PARAMETER'][$tmp[0]] = $tmp[1];
231               }
232             }
233           }elseif(in_array("FAIbranch",$attrs['objectClass'])){
235             $type = "RELEASE";
236             if(isset($attrs['FAIstate'][0])){
237               $data['FAIstate'] = $attrs['FAIstate'][0];
238             }else{
239               $data['FAIstate'] = "";
240             }
241           }
243           $data['DN']       = $attrs['dn'];
244           $data['NAME']     = $name;
245           $data['TYPE']     = $type;
246           $data['PRIORITY'] = $priority;
247           $data['ENTRIES']  = array();
248           $data['UNIQID']   = uniqid();
249           $data['PARENT']   = $parent_id;
250           $data['STATUS']   = "LOADED";
251           $cur[$priority]   = $data;
252           ksort($cur);
253         }
254       }
255     }
256   } 
259   function execute()
260   {
261     /* Call parent execute */
262     plugin::execute();
264     if (isset($_POST['modify_state'])){
265       $this->is_account = !$this->is_account;
266     }
268     /* Do we represent a valid account? */
269     if (!$this->is_account){
270       $display= $this->show_enable_header(_("Add application extension"),
271           _("Application extension disabled. You can enable it by clicking below."));
272       return ($display);
273     }
275     $display =  $this->show_enable_header(_("Remove application extension"),
276           _("Application extension enabled. You can disable it by clicking below."));
279     if(isset($_GET['send'])){
280       $id = $_GET['send'];
281       $all = $this->_get_all_entries();
282       if(isset($all[$id])){
283         send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
284         exit;
285       }
286     }
288     if(isset($_GET['r']))
289     $this->__construct($this->config,$this->dn);
291     if(count($this->edit_entry)){
292       if($this->edit_entry['TYPE'] == "ENTRY"){
293         $smarty = get_smarty();
294         $smarty->assign("type", "ENTRY");
295         $smarty->assign("entry",$this->edit_entry);
296         $smarty->assign("paras",$this->app_parameter);
297         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
298         return($display);
299       }
300       if($this->edit_entry['TYPE'] == "FOLDER"){
301         $smarty = get_smarty();
303         session::set("binarytype" , "image/jpeg");
304         session::set("binary" , $this->edit_entry['ICON']);
305   
306         $smarty->assign("rand", microtime(TRUE));
307         $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0); 
308         $smarty->assign("type", "FOLDER");
309         $smarty->assign("entry",$this->edit_entry);
310         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
311         return($display);
312       }
313     }
315     $smarty = get_smarty();
316     $smarty->assign("plug_id" , $_GET['plug']);
318     /* Create application list */
319     $div = new divSelectBox("appgroup");
320     $div->SetHeight(300);
321     $departments = array();
322     $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
323     foreach($res as $value){
324       $fdn = $value['dn'];
325       $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
326       $fdn= @LDAP::fix($fdn);
327       if($value["description"][0]!=".."){
328         $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
329       }else{
330         $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
331       }
332     }
334     $linkopen = "<a href='?plug=".$_GET['plug']."&amp;act=depopen&amp;depid=%s'>%s</a>";
336     /* Create base back entry */
337     $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
338     if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
339       $div->AddEntry(array(
340             array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
341               "attach"=>"style='border:0px;'")
342             ));
343     }
345     /* Append departments for current base */
346     foreach($departments as $key => $app){
347       $div->AddEntry(array(
348             array("string"=>"<img class='center' src='images/folder.png' alt='"._("department")."'>&nbsp;".sprintf($linkopen,
349                 base64_encode($key),$app),
350               "attach"=>"style='border:0px;'")
351             ));
352     }
354   
355     /* Add applications found on this base */
356     $used_apps = $this->_get_used_entry_name();
357     foreach($this->apps as $key => $app){
358       if(in_array($app['cn'][0],$used_apps)){
359         continue;
360       }
361       if(!preg_match("/".get_ou('applicationou').normalizePreg($this->curbase)."$/",$app['dn'])){
362         continue;
363       }
365       $name = $app['cn'][0];
366       if(isset($app['description'])){
367         $name .= "&nbsp;[".$app['description'][0]."]";
368       }
369       $div->AddEntry(array(
370             array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
371               "<img class='center' src='images/select_application.png' alt='"._("application")."'>&nbsp;".$name,
372               "attach"=>"style='border:0px;'")
373             ));
374     }
376     
377     $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
378     $smarty->assign("FAIrelease",$this->FAIrelease);
379     $smarty->assign("app_list",$div->DrawList());
380     $smarty->assign("i",0);
381     $smarty->assign("releases",$this->Releases);
382     $smarty->assign("folders" , $this->_get_folder_names());
383     $entries = $this->_get_entries_for_release($this->FAIrelease);
384     $smarty->assign("entries",$entries);
385     $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
386     return($display);
387   }
389    
390   /*! \brief Returns all used folder names 
391       @return Array  All used folder names.
392    */ 
393   function _get_folder_names()
394   {
395     $data = $this->_get_entries_for_release($this->FAIrelease);
396     $all    = $this->_get_all_entries();
397     $ret = array("BASE" => ".");
398     foreach($data as $entry){
400       if($entry['TYPE'] == "FOLDER"){
401         $str = $entry['NAME'];
402         $parent = $entry['PARENT'];
403         $i = 10;
404         while(isset($all[$parent]) && $i){  
405           $i --;
406           $parent_o = $all[$parent];
407           $str      = $parent_o['NAME']."/".$str;
408           $parent   = $all[$parent_o['UNIQID']]['PARENT'];
409         }        
410         $ret[$entry['UNIQID']] = $str;
411       }
412     }
413     return($ret);
414   }
417   /*! \brief return all used applications 
418       @return Array  All used applications.
419    */ 
420   function _get_used_entry_name()
421   {
422     $data = $this->_get_entries_for_release($this->FAIrelease);
423     $ret = array();
424     foreach($data as $entry){
425       if($entry['TYPE'] == "ENTRY"){
426         $ret[] = $entry['NAME'];
427       }
428     }
429     return($ret);
430   }
433   /*! \brief Returns all folder an entries for the selected release 
434       @return Array  Returns the complete menu structure for the given array.
435    */ 
436   function _get_entries_for_release($release,$cur = NULL)
437   {
438     $all = $this->_get_all_entries();
439     $key = $this->_get_release_key($release);
440     if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
441       $res = $this->_get_all_entries(TRUE,TRUE,&$all[$key]['ENTRIES']);
442       return($res);
443     } 
444     return(array());
445   }
448   /*! \brief Save the currently edited entry */
449   function _save_entry_edit()
450   {
451     $all    = $this->_get_all_entries();
452     $entry  = $this->edit_entry;
453     $r_entry= &$all[$entry['UNIQID']];
455     if($entry['TYPE'] == "ENTRY"){
456       $r_entry['PARAMETER'] = $this->app_parameter;
457       $r_entry['STATUS'] = "EDITED";
458     }
459     if($entry['TYPE'] == "FOLDER"){
460       $r_entry['ICON']   = $this->edit_entry['ICON'];
461       $r_entry['STATUS'] = "EDITED";
462     }
463     $this->dialog = FALSE;
464     $this->edit_entry = array();
465   }
468   /*! \brief prepare the entry with the given ID, to be edited.
469    */
470   function _edit_entry_edit($id)
471   {
472     $all   = $this->_get_all_entries();
473     $entry = $all[$id];
475     $this->app_parameter = array();
476     if($entry['TYPE'] == "ENTRY"){
477       $found = FALSE;
478       foreach($this->apps as $id => $app){
480         if($app['cn'][0] == $entry['NAME']){
481           $found = TRUE;
482           break;
483         }
484       }
485       if($found){
486       
487         /* Create a list of editable parameter */
488         if(isset($app['gosaApplicationParameter'])){
489           for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
490             $para = $app['gosaApplicationParameter'][$i];
491             $tmp  = split(":",$para);
492             $this->app_parameter[$tmp[0]] = $tmp[1];
493           }
494         }
496         /* Overwrite parameters with entry parameters */
497         foreach($entry['PARAMETER'] as $name => $value){
498           $this->app_parameter[$name] = $value;
499         }
500         
501         $this->dialog = TRUE;
502         $this->edit_entry = $entry;
503       }
504     }
506     if($entry['TYPE'] == "FOLDER"){
507       $this->dialog = TRUE;
508       $this->edit_entry = $entry;
509     }
510   }
513   function remove_from_parent()
514   {
515     $ldap = $this->config->get_ldap_link();
516     $ldap->cd($this->dn);
517     $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
518     $a_remove = array();
519     while($attrs = $ldap->fetch()){
520       $a_remove[] = $attrs['dn'];
521     }
522     foreach($a_remove as $remove){
523       $ldap->rmdir_recursive($remove);
524       show_ldap_error($ldap->get_error(),
525           sprintf(_("Removing of group/application account with dn '%s' failed, could not remove '%s'."),
526             $this->dn,$remove));
527     }
528     $this->_load_menu_structure();
529   }
532   function check()
533   {
534   }
537   /*! \brief Create missing releases, if there is a release selected \
538               that is currently not part of the menu structure \
539               then create this entry
540    */
541   function _check_missing_release($release)
542   {
543     $release_info = $this->Releases[$release];
545     $parent_id = $this->a_Structure[0]['UNIQID'];
546     $cur = &$this->a_Structure[0]['ENTRIES'];
547     for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
548       $part = $release_info['parts'][$i];
549       $found = FALSE;
550       foreach($cur as $key => $name){
551         if($name['NAME'] == $part){
552           $parent_id = $cur[$key]['UNIQID'];
553           $cur = &$cur[$key]['ENTRIES'];
554           
555           $found =TRUE;
556           break;
557         }
558       }
559       if(!$found){
560         $release           =  array();
561         $release['UNIQID'] = uniqid();
562         $release['PARENT'] = $parent_id;
563         $release['NAME']   = $part;
564         $release['TYPE']   = "RELEASE";
565         $release['ENTRIES']= array();
566         $release['STATUS']   = "ADDED";
567         $release['FAIstate'] =  $release_info['FAIstate'];
568         $cur[] = $release;
569         $i --;
570       }
571     }
572   }
576   function _move_entry($id,$dir)
577   {
578     $all   = $this->_get_all_entries();
579     if($dir == "down"){
580       $to = $this->_get_next($id);
581     } 
582     if($dir == "up"){
583       $to = $this->_get_last($id);
584     }
586     if(!$to){
587       return;
588     }
590     $o_to   = $all[$to];
591     $o_from = $all[$id];
593     if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
594       $to    = $this->_get_next($to,$o_from['PARENT']); 
595       $o_to  = $all[$to]; 
596     }
597  
598  
599     /* Target is ENTRY && same BASE, just switch */
600     if($o_to['PARENT'] == $o_from['PARENT'] ){
601       $parent = $all[$o_to['PARENT']];
602       $pos = 0;
603       foreach($parent['ENTRIES'] as $entry){
604         $pos ++;
605         if($entry['UNIQID'] == $to){
606           break;
607         }
608       }
609       if($dir == "up" && $pos > 0){
610         $pos --;
611       }
612       $this->_add_entry($parent['UNIQID'],$o_from,$pos);
613       $this->_remove_entry_id($id);
614       return(TRUE);
615     }
616     return(FALSE);
617   }
620  
621   function _get_last($id)
622   {
623     $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
624     for($i = 0 ; $i < count($all_l) ; $i ++){
625       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
626         $i++;
627         break;
628       }
629     }
630     while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
631       $i++;
632     }
634     if(!isset($all_l[$i])){
635       return(FALSE);
636     }
638     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
639       return($all_l[$i]['PARENT']);
640     }     
642     return($all_l[$i]['UNIQID']);
643   }
645  
646   function _get_next($id,$parent = 0)
647   {
648     $all_l = $this->_get_entries_for_release($this->FAIrelease);
649     for($i = 0 ; $i < count($all_l) ; $i ++){
650       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
651         $i++;
652         break;
653       }
654     }
655     if($parent != 0){
656       while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
657         $i++;
658       }
659     }else{
660       while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
661         $i++;
662       }
663     }
664     if(!isset($all_l[$i])){
665       return(FALSE);
666     }
667     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
668       return($all_l[$i]['PARENT']);
669     }
670     return($all_l[$i]['UNIQID']);
671   }
676   /* !\brief Handle ui POSTS, like sort up/down/delete
677    */ 
678   function save_object()
679   {
680     foreach($_POST as $name => $value){
681       if(preg_match("/del_/",$name)){
682         $id = preg_replace("/^del_/","",$name);
683         $id = preg_replace("/_(x|y)$/","",$id);
684         $this->_remove_entry_id($id);
685         break;
686       }
687       if(preg_match("/app_entry_edit/",$name)){
688         $id = preg_replace("/^app_entry_edit/","",$name);
689         $id = preg_replace("/_(x|y)$/","",$id);
690         $this->_edit_entry_edit($id);
691         break;
692       }
693       if(preg_match("/up_/",$name)){
694         $id = preg_replace("/^up_/","",$name);
695         $id = preg_replace("/_(x|y)$/","",$id);
696         $this->_move_entry($id,"up");
697         break;
698       }
699       if(preg_match("/down_/",$name)){
700         $id = preg_replace("/^down_/","",$name);
701         $id = preg_replace("/_(x|y)$/","",$id);
702         $this->_move_entry($id,"down");
703         break;
704       }
705       if(preg_match("/^parameter_/",$name) && 
706         count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
707         $name = preg_replace("/^parameter_/","",$name);
708         $this->app_parameter[$name] = $value;
709       }
710     }
711     if(isset($_POST['FAIrelease'])){
712       $this->FAIrelease = $_POST['FAIrelease'];
713       $this->_check_missing_release($this->FAIrelease);
714     }
715     if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
716       $this->curbase = base64_decode($_GET['depid']);
717     }
718     if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
719       $folder = $_POST['folder'];
720       foreach($_POST as $name => $value){
721         if(preg_match("/^AddApp_[0-9]*$/",$name)){
722           $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));   
723         }
724       }
725     }
726     if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
727       $folder = $_POST['menu_folder'];
728       $name = $_POST['menu_folder_name'];
729       if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
730         $this->_add_sub_folder($folder,$name);
731       }
732     }
733     if(isset($_POST['app_entry_save'])){ 
734       $this->_save_entry_edit();
735     }
737     if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
738       if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
739         $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
740       }
741     }
743     if(isset($_POST['edit_reset_image'])){
744       $this->edit_entry['ICON'] = "";
745     }
747     if(isset($_POST['app_entry_cancel'])){
748       $this->edit_entry = array();
749       $this->dialog = FALSE;
750     }
751     $this->reload();
752   }
754  
755   /*! \brief Returns the UNIQID of the currently selected release 
756    */ 
757   function _get_release_key($release,$add_if_missing = FALSE)
758   {
759     $release_info = $this->Releases[$release];
761     if($release_info['name'] == "/"){
762       return($this->a_Structure['0']['UNIQID']);
763     }
765     $cur = &$this->a_Structure[0]['ENTRIES'];
766     $s_key = "";
767     $found = FALSE;
768     foreach($release_info['parts'] as $name){
769       foreach($cur as $key => $obj){
770         if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
771           $s_key = $cur[$key]['UNIQID'];
772           $cur = &$cur[$key]['ENTRIES'];
773           $found = TRUE;
774           break;
775         }
776         $found = FALSE;
777       }
778     }
779     if($found){
780       return($s_key);  
781     }  
782     return(FALSE);
783   }
785  
786   /*! \brief Add a new folder folder to the specified folder id
787       @param  String $folder The folder id in where we want to add the new folder.
788       @param  String $name   The name of the new folder.
789    */ 
790   function _add_sub_folder($folder,$name)
791   {
792     $all = $this->_get_all_entries();
793     if($folder == "BASE"){
794       $folder = $this->_get_release_key($this->FAIrelease,TRUE);
795     }
796     
797     if(isset($all[$folder])){
798       $a_folder = array();
799       $a_folder['STATUS'] = "ADDED";
800       $a_folder['NAME']   = $name;
801       $a_folder['UNIQID'] = uniqid();
802       $a_folder['ENTRIES']= array();
803       $a_folder['PARENT'] = $folder;      
804       $a_folder['TYPE']   = "FOLDER";
805       $a_folder['ICON']   = "";
806       $all[$folder]['ENTRIES'][] = $a_folder;
807     }
808   }
811   /* !\brief Remove the given id from the menu structure.
812       @param  String  ID to of the entry we want to remove.
813       @return Boolean TRUE on success
814    */
815   function _remove_entry_id($id)
816   {
817     $all = $this->_get_all_entries();
818     if(isset($all[$id])){
819       $all[$id]['STATUS'] = "REMOVED";
820       $all[$id]['ENTRIES'] = array();
821       return(TRUE);
822     }
823     return(FALSE);
824   }
826   
827   /* !\brief Remove the given id from the menu structure.
828       @param  String  ID to of the entry we want to remove.
829       @return Boolean TRUE on success
830    */
831   function _add_entry($folder_id,$entry,$pos = 0)
832   {
833     $all = $this->_get_all_entries();
835     /* Do not add removed */
836     if($entry['STATUS'] == "REMOVED"){
837       return;
838     }
840     if(isset($all[$folder_id])){
842       if(!isset($entry['ENTRIES'])){
843         $entries = array();
844       }else{
845         $entries = $entry['ENTRIES'];
846       }
848       $folder  = &$all[$folder_id];
850       $entry['UNIQID'] = uniqid();     
851       $entry['PARENT'] = $folder_id;
852       $entry['ENTRIES']= array();
853       $entry['STATUS'] = "ADDED";
854       
855       $cnt = 0; 
856       $new = array();
857       $added =FALSE;
858       foreach($folder['ENTRIES'] as $key => $obj){
859         if($obj['STATUS'] == "LOADED"){
860           $obj['STATUS'] = "EDITED";
861         }
862         if($pos == $cnt){
863           $new[] = $entry;
864           $added = TRUE;
865         }
866         $cnt ++;
867         $new[] = $obj;
868       }
869       if(!$added){
870         $new[] = $entry;
871       }
872   
873       $all[$folder_id]['ENTRIES'] = $new;
874       foreach($entries as $sub){
875         $this->_add_entry($entry['UNIQID'],$sub,-1);
876       }
877       return(TRUE);
878     }
879     return(FALSE);
880   }
882  
883   /*! \brief Add the application identified by $app_id to folder $folder_id 
884       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
885       @param  Integer app_id    The ID of the application which should be added.
886    */ 
887   function _add_app_id($folder_id,$app_id)
888   {
889     $all = $this->_get_all_entries();
890     if($folder_id == "BASE"){
891       $folder_id = $this->_get_release_key($this->FAIrelease);
892     }
893     if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
895       $new = array();
896       $new['TYPE']  = "ENTRY";
897       $new['NAME']  = $this->apps[$app_id]['cn'][0];
898       $new['UNIQID']= uniqid(); 
899       $new['PARENT']= $folder_id;
900       $new['PARAMETER']= array();
901       if(isset($this->apps[$app_id]['description'][0])){
902         $new['INFO']  = $this->apps[$app_id]['description'][0];
903       }else{
904         $new['INFO']  = "";
905       }
906       $new['STATUS']= "ADDED";
907       $all[$folder_id]['ENTRIES'][] = $new;
908     }
909   }
912   /*! \brief  Return all entries linear. 
913       @param  Boolean   $add_tags  If TRUE, OPEN/CLOSE Tags will be appended.
914       @param  &Array    Start here, Pointer to an array.
915    */ 
916   function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, $cur = NULL)
917   {
918     $ret = array();
919     if($cur == NULL){
920       $cur = &$this->a_Structure;
921     }
922     foreach($cur as $key => $entry){
924       if($skip_release && $entry['TYPE'] == "RELEASE"){
925         continue;
926       }    
927       if($entry['TYPE'] == "ENTRY"){
928         $found = FALSE;
929         foreach($this->apps as $app){
930           if($app['cn'][0] == $entry['NAME']){
931             $found = TRUE;
932             if(isset($app['description'][0])){
933               $entry['INFO'] = "[".$app['description'][0]."]";
934             }
935             break;
936           }
937         } 
938         if(!$found){
939           $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
940         }
941       }
942       
944       $tmp = $entry;
945       if(!$add_tags){
946         $ret[$tmp['UNIQID']] = &$cur[$key];
947         if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
948           $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
949         }
950       }else{
951       
952         if(isset($tmp['ENTRIES'])){
953           unset($tmp['ENTRIES']);
954         }
955         if($tmp['STATUS'] != "REMOVED"){
956           $ret[] = $tmp;
957           if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
958             $add = false;
959             foreach($entry['ENTRIES'] as $entry){
960               if($entry['STATUS'] != "REMOVED"){
961                 $add = TRUE;
962                 break;
963               }
964             }
966             if($add){
967               $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
968               $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
969               $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
970             }
971           }
972         }
973       }
974     }
975     return($ret);
976   }
979   function save()
980   {
981     $ldap = $this->config->get_ldap_link();
982     $all = $this->_get_all_entries();
983     $prio = 0;
984     $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
986     foreach($all as $entry){
987       $prio ++;
988       $cur = $entry;
989       $dn = "";
991       do{  
992         if($cur['TYPE'] == "ENTRY"){
993           $dn.= "cn=".$cur['NAME'].",";
994         }elseif($cur['TYPE'] == "FOLDER"){
995           $dn.= "cn=".$cur['NAME'].",";
996         }elseif($cur['TYPE'] == "RELEASE"){
997           $dn.= "ou=".$cur['NAME'].",";
998         }elseif($cur['TYPE'] == "BASE"){
999         }
1000         if(!isset($all[$cur['PARENT']])){
1001           $cur = NULL;
1002         }else{
1003           $cur = $all[$cur['PARENT']];
1004         }
1005       }while(is_array($cur));
1007       $cur_dn = $dn.$this->dn;
1009       $attrs = array();
1010       switch($entry['TYPE']){
1011         case "ENTRY"    :
1012         { 
1013           $attrs['objectClass'] = "gotoMenuEntry";
1014           $attrs['cn']          = $entry['NAME'];
1015           $attrs['gosaApplicationPriority'] = $prio;
1016           $attrs['gosaApplicationParameter'] = array(); 
1017           
1018           
1019           foreach($entry['PARAMETER'] as $name => $value){
1020             $attrs['gosaApplicationParameter'][] = $name.":".$value; 
1021           }
1022           if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1023             unset($attrs['gosaApplicationParameter']);
1024           } 
1025         }
1026         break;
1027         case "FOLDER"   : 
1028         { 
1029           $attrs['objectClass'] = "gotoSubmenuEntry";
1030           $attrs['cn']          = $entry['NAME'];
1031           $attrs['gosaApplicationPriority'] = $prio;
1032           if($entry['STATUS'] != "ADDED"){
1033             $attrs['gosaApplicationIcon'] = array();
1034           }
1035           
1036           if(!empty($entry['ICON'])){
1037             $attrs['gosaApplicationIcon']     = $entry['ICON'];
1038           }
1039         }
1040         break;
1041         case "RELEASE"  : 
1042         { 
1043           $attrs['ou']            = $entry['NAME'];
1044           $attrs['objectClass']   = array();
1045           $attrs['objectClass'][] = "top";
1046           $attrs['objectClass'][] = "organizationalUnit";
1047           $attrs['objectClass'][] = "FAIbranch";
1048           if(!empty($entry['FAIstate'])){
1049             $attrs['FAIstate']      = $entry['FAIstate'];
1050           }
1051         }
1052         break;
1053       }
1054   
1055       if($entry['STATUS'] == "LOADED"){
1056         continue;
1057       }
1058       if($entry['STATUS'] == "REMOVED"){
1059         $Actions['Remove'][$cur_dn] = $cur_dn;
1060       }
1061       if($entry['STATUS'] == "EDITED"){
1062         $Actions['Edit'][$cur_dn] = $attrs;
1063       }
1064       if($entry['STATUS'] == "ADDED"){
1065         $Actions['Add'][$cur_dn] = $attrs;
1066       }
1067     }
1069     $ldap = $this->config->get_ldap_link();
1070     $ldap->cd($this->config->current['BASE']);
1071     foreach($Actions['Remove'] as $dn){
1072       $ldap->cd($dn);
1073       $ldap->cat($dn);
1074       if($ldap->count()){
1075         $ldap->rmdir_recursive($dn);
1076         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1077       }
1078     }
1079     foreach($Actions['Add'] as $dn => $data){
1080       $ldap->cd($dn);
1081       $ldap->cat($dn);
1082       if(!$ldap->count()){
1083         $ldap->add($data);
1084         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1085       }
1086     }
1087     foreach($Actions['Edit'] as $dn => $data){
1088       $ldap->cd($dn);
1089       $ldap->cat($dn);
1090       if($ldap->count()){
1091         $ldap->modify($data);
1092         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1093       }
1094     }
1095     $this->_load_menu_structure();
1096   }
1099   /* Return plugin informations for acl handling  */ 
1100   static function plInfo()
1101   {
1102     return (array(
1103           "plShortName"   => _("Applications"),
1104           "plDescription" => _("Group applications"),
1105           "plSelfModify"  => FALSE,
1106           "plDepends"     => array(),
1107           "plPriority"    => 0,
1108           "plSection"     => array("admin"),
1109           "plCategory"    => array("groups"),
1110           "plProvidedAcls"=> array(
1111             "gosaMemberApplication"     => _("Application"),
1112             "FAIrelease"                => _("Release"),
1113             "gosaApplicationParameter"  => _("Application parameter"))
1114           ));
1115   }
1118   function PrepareForCopyPaste($source)
1119   {
1120   }
1123   function multiple_save_object()
1124   {
1125     if(isset($_POST['group_apps_multi'])){
1126       $this->save_object(); 
1127       plugin::multiple_save_object();    
1128   
1129       /* Get posts */
1130       foreach(array("apps") as $attr){
1131         if(isset($_POST['use_'.$attr])) {
1132           $this->multi_boxes[] = $attr;
1133         }
1134       }
1135     }
1136   }
1137   
1139   function get_multi_edit_values()
1140   {
1141     $ret = plugin::get_multi_edit_values();
1143     if(in_array("apps",$this->multi_boxes)){
1144       $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1145       $ret['Categories']               = $this->Categories;
1146       $ret['gosaMemberApplication']    = $this->gosaMemberApplication;
1147       $ret['FAIrelease']               = $this->FAIrelease;
1148       $ret['appoption']                = $this->appoption;
1149     }
1150     return($ret);
1151   }
1153 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1154 ?>