Code

Fixed sorting
[gosa.git] / gosa-plugins / goto / admin / groups / apps / class_groupApplication2.inc
1 <?php
2 class appgroup2 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;
26   public function __construct(&$config, $dn= NULL, $parent= NULL)
27   {
28     plugin::plugin($config,$dn,$parent);
29     $this->dn = $dn; 
30     $this->_load_menu_structure();
31     $this->a_Structure_on_load = $this->a_Structure;
33     /* Check if we have relase mangement enabled and prepare group application for release management */
34     $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
35     if(!empty($tmp)){
36       $this->enableReleaseManagement = true;
37     }
39     $this->Releases   = $this->getReleases();
40     $this->FAIrelease = "/";
41     $this->curbase = $this->config->current['BASE'];
42     $this->reload();
43   }
46   /*! \brief Reload the list of applications for the currently selected release 
47    */
48   function reload()
49   {
50     $ret = array();
51     $release_info = $this->Releases[$this->FAIrelease];
53     if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
55       $ldap = $this->config->get_ldap_link();
56       $ldap->cd($this->config->current['BASE']);
57       $ldap->search("ou=apps",array("dn"));
58       $app_deps = array();
59       while($attrs = $ldap->fetch()){
60         $app_deps[] = $attrs['dn'];
61       }
63       foreach($app_deps as $dep){
64         $ldap->cd($dep);
65         $ldap->search("objectClass=FAIbranch",array("dn"));
66         while($attrs = $ldap->fetch()){
67           $app_deps[] = $attrs['dn'];
68         }
69       }
71       foreach($app_deps as $dep){
72         if(preg_match("/^".normalizePreg($release_info['suffix'])."/",$dep)){
73           $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
74         }
75       }
76       $this->_cache['ReleaseApps'][$release_info['suffix']] = $ret;
77     } 
78     $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
79   }
81   
82   
83   
84   /*! \brief generate a list of available releases
85       @return return an array with all available releases.
86     */
87   function getReleases()
88   {
89     $ret =array("/" => array("name" => "/" , "parts" => array(),"suffix" => get_ou('applicationou')));
90     if($this->enableReleaseManagement){
92       /* Only display those releases that we are able to read */
93       $dn     = $this->config->current['BASE'];
94       $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
95       $res    = get_list($filter,"application", $dn, array("ou","FAIstate"), GL_SUBSEARCH);
97       foreach($res as $attrs){
98         if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
99           $bb     = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
100           $parts  = array_reverse(split("ou=",$bb));
102           $str ="";
103           foreach($parts as $key => $part){
104             if(empty($part)) {
105               unset($parts[$key]);
106               continue;
107             }
108             $part = str_replace(",","",$part);
109             $str .= $part."/";
110             $parts[$key] = $part;
111           }
112           $name = preg_replace("/\/$/","",$str);
113           if(empty($name)) {
114             $name ="/";
115           }
116           $FAIstate = "";
117           if(isset($attrs['FAIstate'])){
118             $FAIstate = $attrs['FAIstate'][0];
119           }
121           $ret[$name] = array("name"     => $name, 
122               "FAIstate" => $FAIstate,
123               "dn"       => $attrs['dn'], 
124               "parts"    => $parts,"suffix" => $bb.get_ou('applicationou'));
125         }
126       }
127     }
128     ksort($ret);
129     return($ret);
130   }
133   /*! \brief Load the menu structure from ldap and create a multi dimensional array
134    */
135   function _load_menu_structure()
136   {
137     $this->a_Structure  = array();
138     $ldap = $this->config->get_ldap_link();
139     $ldap->cd($this->dn);
140     $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
142     $base =  array();
143     $base['UNIQID'] = uniqid();
144     $base['PARENT'] = 0; 
145     $base['NAME']   = "";
146     $base['TYPE']   = "BASE";
147     $base['ENTRIES']= array();
148     $base['STATUS'] = "LOADED";
149     
150     $this->a_Structure[0] = $base;
152     while($attrs = $ldap->fetch()){
153       $cur = &$this->a_Structure[0]['ENTRIES'];
154       $parent_id    = $base['UNIQID'];
155       $sub_dn       = preg_replace("/,".normalizePreg($this->dn)."$/","",$attrs['dn']);
156       $sub_dn_array = split("\,",$sub_dn);
159       for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
160         $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
161         if($i > 0){
162           foreach($cur as $key => $entry){
163             if($entry['NAME'] == $name){
164               $cur = &$cur[$key]['ENTRIES'];
165               $parent_id = $entry['UNIQID'];
166             }
167           }
168         }else{
170           $priority = 1;
171           if(isset($attrs['gosaApplicationPriority'])){
172             $priority= $attrs['gosaApplicationPriority'][0];
173           }
174           while(isset($cur[$priority])){
175             $priority ++;
176           }
178           $data = array();
179           if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
180             $type = "FOLDER";
182             $data['ICON'] = "";
183             if(isset($attrs['gosaApplicationIcon'])){
184               $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
185             }
187           }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
188             $type = "ENTRY";
189             $data['INFO'] = "";
190             $data['PARAMETER'] = array();
191             if(isset($attrs['gosaApplicationParameter'])){
192               for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
193                 $tmp = split(":",$attrs['gosaApplicationParameter'][$p]);
194                 $data['PARAMETER'][$tmp[0]] = $tmp[1];
195               }
196             }
197           }elseif(in_array("FAIbranch",$attrs['objectClass'])){
199             $type = "RELEASE";
200             if(isset($attrs['FAIstate'][0])){
201               $data['FAIstate'] = $attrs['FAIstate'][0];
202             }else{
203               $data['FAIstate'] = "";
204             }
205           }
207           $data['DN']       = $attrs['dn'];
208           $data['NAME']     = $name;
209           $data['TYPE']     = $type;
210           $data['PRIORITY'] = $priority;
211           $data['ENTRIES']  = array();
212           $data['UNIQID']   = uniqid();
213           $data['PARENT']   = $parent_id;
214           $data['STATUS']   = "LOADED";
215           $cur[$priority]   = $data;
216           ksort($cur);
217         }
218       }
219     }
220   } 
223   function execute()
224   {
225     /* Call parent execute */
226     plugin::execute();
228     if(isset($_GET['send'])){
229       $id = $_GET['send'];
230       $all = $this->_get_all_entries();
231       if(isset($all[$id])){
232         send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
233         exit;
234       }
235     }
237     if(isset($_GET['r']))
238     $this->__construct($this->config,$this->dn);
240     if(count($this->edit_entry)){
241       if($this->edit_entry['TYPE'] == "ENTRY"){
242         $smarty = get_smarty();
243         $smarty->assign("type", "ENTRY");
244         $smarty->assign("entry",$this->edit_entry);
245         $smarty->assign("paras",$this->app_parameter);
246         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
247         return($display);
248       }
249       if($this->edit_entry['TYPE'] == "FOLDER"){
250         $smarty = get_smarty();
252         session::set("binarytype" , "image/jpeg");
253         session::set("binary" , $this->edit_entry['ICON']);
254   
255         $smarty->assign("rand", microtime(TRUE));
256         $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0); 
257         $smarty->assign("type", "FOLDER");
258         $smarty->assign("entry",$this->edit_entry);
259         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
260         return($display);
261       }
262     }
264     $smarty = get_smarty();
265     $smarty->assign("plug_id" , $_GET['plug']);
267     /* Create application list */
268     $div = new divSelectBox("appgroup");
269     $div->SetHeight(300);
270     $departments = array();
271     $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
272     foreach($res as $value){
273       $fdn = $value['dn'];
274       $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
275       $fdn= @LDAP::fix($fdn);
276       if($value["description"][0]!=".."){
277         $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
278       }else{
279         $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
280       }
281     }
283     $linkopen = "<a href='?plug=".$_GET['plug']."&amp;act=depopen&amp;depid=%s'>%s</a>";
285     /* Create base back entry */
286     $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
287     if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
288       $div->AddEntry(array(
289             array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
290               "attach"=>"style='border:0px;'")
291             ));
292     }
294     /* Append departments for current base */
295     foreach($departments as $key => $app){
296       $div->AddEntry(array(
297             array("string"=>"<img class='center' src='images/folder.png' alt='"._("department")."'>&nbsp;".sprintf($linkopen,
298                 base64_encode($key),$app),
299               "attach"=>"style='border:0px;'")
300             ));
301     }
303   
304     /* Add applications found on this base */
305     $used_apps = $this->_get_used_entry_name();
306     foreach($this->apps as $key => $app){
307       if(in_array($app['cn'][0],$used_apps)){
308         continue;
309       }
310       if(!preg_match("/".get_ou('applicationou').normalizePreg($this->curbase)."$/",$app['dn'])){
311         continue;
312       }
314       $name = $app['cn'][0];
315       if(isset($app['description'])){
316         $name .= "&nbsp;[".$app['description'][0]."]";
317       }
318       $div->AddEntry(array(
319             array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
320               "<img class='center' src='images/select_application.png' alt='"._("application")."'>&nbsp;".$name,
321               "attach"=>"style='border:0px;'")
322             ));
323     }
325     
326     $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
327     $smarty->assign("FAIrelease",$this->FAIrelease);
328     $smarty->assign("app_list",$div->DrawList());
329     $smarty->assign("releases",$this->Releases);
330     $smarty->assign("folders" , $this->_get_folder_names());
331     $entries = $this->_get_entries_for_release($this->FAIrelease);
332     $smarty->assign("entries",$entries);
333     $display= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
334     return($display);
335   }
337    
338   /*! \brief Returns all used folder names 
339       @return Array  All used folder names.
340    */ 
341   function _get_folder_names()
342   {
343     $data = $this->_get_entries_for_release($this->FAIrelease);
344     $ret = array("BASE" => ".");
345     foreach($data as $entry){
346       if($entry['TYPE'] == "FOLDER"){
347         $ret[$entry['UNIQID']] = $entry['NAME'];
348       }
349     }
350     return($ret);
351   }
354   /*! \brief return all used applications 
355       @return Array  All used applications.
356    */ 
357   function _get_used_entry_name()
358   {
359     $data = $this->_get_entries_for_release($this->FAIrelease);
360     $ret = array();
361     foreach($data as $entry){
362       if($entry['TYPE'] == "ENTRY"){
363         $ret[] = $entry['NAME'];
364       }
365     }
366     return($ret);
367   }
370   /*! \brief Returns all folder an entries for the selected release 
371       @return Array  Returns the complete menu structure for the given array.
372    */ 
373   function _get_entries_for_release($release,$cur = NULL)
374   {
375     $all = $this->_get_all_entries();
376     $key = $this->_get_release_key($release);
377     if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
378       $res = $this->_get_all_entries(TRUE,TRUE,&$all[$key]['ENTRIES']);
379       return($res);
380     } 
381     return(array());
382   }
385   /*! \brief Save the currently edited entry */
386   function _save_entry_edit()
387   {
388     $all    = $this->_get_all_entries();
389     $entry  = $this->edit_entry;
390     $r_entry= &$all[$entry['UNIQID']];
392     if($entry['TYPE'] == "ENTRY"){
393       $r_entry['PARAMETER'] = $this->app_parameter;
394       $r_entry['STATUS'] = "EDITED";
395     }
396     if($entry['TYPE'] == "FOLDER"){
397       $r_entry['ICON']   = $this->edit_entry['ICON'];
398       $r_entry['STATUS'] = "EDITED";
399     }
400     $this->dialog = FALSE;
401     $this->edit_entry = array();
402   }
405   /*! \brief prepare the entry with the given ID, to be edited.
406    */
407   function _edit_entry_edit($id)
408   {
409     $all   = $this->_get_all_entries();
410     $entry = $all[$id];
412     $this->app_parameter = array();
413     if($entry['TYPE'] == "ENTRY"){
414       $found = FALSE;
415       foreach($this->apps as $id => $app){
417         if($app['cn'][0] == $entry['NAME']){
418           $found = TRUE;
419           break;
420         }
421       }
422       if($found){
423       
424         /* Create a list of editable parameter */
425         if(isset($app['gosaApplicationParameter'])){
426           for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
427             $para = $app['gosaApplicationParameter'][$i];
428             $tmp  = split(":",$para);
429             $this->app_parameter[$tmp[0]] = $tmp[1];
430           }
431         }
433         /* Overwrite parameters with entry parameters */
434         foreach($entry['PARAMETER'] as $name => $value){
435           $this->app_parameter[$name] = $value;
436         }
437         
438         $this->dialog = TRUE;
439         $this->edit_entry = $entry;
440       }
441     }
443     if($entry['TYPE'] == "FOLDER"){
444       $this->dialog = TRUE;
445       $this->edit_entry = $entry;
446     }
447   }
450   function remove_from_parent()
451   {
452   }
456   function check()
457   {
458   }
461   /*! \brief Create missing releases, if there is a release selected \
462               that is currently not part of the menu structure \
463               then create this entry
464    */
465   function _check_missing_release($release)
466   {
467     $release_info = $this->Releases[$release];
469     $parent_id = $this->a_Structure[0]['UNIQID'];
470     $cur = &$this->a_Structure[0]['ENTRIES'];
471     for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
472       $part = $release_info['parts'][$i];
473       $found = FALSE;
474       foreach($cur as $key => $name){
475         if($name['NAME'] == $part){
476           $parent_id = $cur[$key]['UNIQID'];
477           $cur = &$cur[$key]['ENTRIES'];
478           
479           $found =TRUE;
480           break;
481         }
482       }
483       if(!$found){
484         $release           =  array();
485         $release['UNIQID'] = uniqid();
486         $release['PARENT'] = $parent_id;
487         $release['NAME']   = $part;
488         $release['TYPE']   = "RELEASE";
489         $release['ENTRIES']= array();
490         $release['STATUS']   = "ADDED";
491         $release['FAIstate'] =  $release_info['FAIstate'];
492         $cur[] = $release;
493         $i --;
494       }
495     }
496   }
500   function _move_entry($id,$dir)
501   {
502     $all   = $this->_get_all_entries();
503     if($dir == "down"){
504       $to = $this->_get_next($id);
505     } 
506     if($dir == "up"){
507       $to = $this->_get_last($id);
508     }
510     if(!$to){
511       echo "Fehler";
512       return;
513     }
515     $o_to   = $all[$to];
516     $o_from = $all[$id];
518     if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
519       $to    = $this->_get_next($to,$o_from['PARENT']); 
520       $o_to  = $all[$to]; 
521     }
522  
523  
524     /* Target is ENTRY && same BASE, just switch */
525     if($o_to['PARENT'] == $o_from['PARENT'] ){
526       $parent = $all[$o_to['PARENT']];
527       $pos = 0;
528       foreach($parent['ENTRIES'] as $entry){
529         $pos ++;
530         if($entry['UNIQID'] == $to){
531           break;
532         }
533       }
534       if($dir == "up" && $pos > 0){
535         $pos --;
536       }
537       $this->_add_entry($parent['UNIQID'],$o_from,$pos);
538       $this->_remove_entry_id($id);
539       return(TRUE);
540     }
541     return(FALSE);
542   }
545  
546   function _get_last($id)
547   {
548     $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
549     for($i = 0 ; $i < count($all_l) ; $i ++){
550       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
551         $i++;
552         break;
553       }
554     }
555     while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
556       $i++;
557     }
559     if(!isset($all_l[$i])){
560       return(FALSE);
561     }
563     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
564       return($all_l[$i]['PARENT']);
565     }     
567     return($all_l[$i]['UNIQID']);
568   }
570  
571   function _get_next($id,$parent = 0)
572   {
573     $all_l = $this->_get_entries_for_release($this->FAIrelease);
574     for($i = 0 ; $i < count($all_l) ; $i ++){
575       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
576         $i++;
577         break;
578       }
579     }
580     if($parent != 0){
581       while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
582         $i++;
583       }
584     }else{
585       while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
586         $i++;
587       }
588     }
589     if(!isset($all_l[$i])){
590       return(FALSE);
591     }
592     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
593       return($all_l[$i]['PARENT']);
594     }
595     return($all_l[$i]['UNIQID']);
596   }
601   /* !\brief Handle ui POSTS, like sort up/down/delete
602    */ 
603   function save_object()
604   {
605     foreach($_POST as $name => $value){
606       if(preg_match("/del_/",$name)){
607         $id = preg_replace("/^del_/","",$name);
608         $id = preg_replace("/_(x|y)$/","",$id);
609         $this->_remove_entry_id($id);
610         break;
611       }
612       if(preg_match("/app_entry_edit/",$name)){
613         $id = preg_replace("/^app_entry_edit/","",$name);
614         $id = preg_replace("/_(x|y)$/","",$id);
615         $this->_edit_entry_edit($id);
616         break;
617       }
618       if(preg_match("/up_/",$name)){
619         $id = preg_replace("/^up_/","",$name);
620         $id = preg_replace("/_(x|y)$/","",$id);
621 #        $this->_move_entry_up($id);
622         $this->_move_entry($id,"up");
623         break;
624       }
625       if(preg_match("/down_/",$name)){
626         $id = preg_replace("/^down_/","",$name);
627         $id = preg_replace("/_(x|y)$/","",$id);
628 #        $this->_move_entry_down($id);
629         $this->_move_entry($id,"down");
630         break;
631       }
632       if(preg_match("/^parameter_/",$name) && 
633         count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
634         $name = preg_replace("/^parameter_/","",$name);
635         $this->app_parameter[$name] = $value;
636       }
637     }
638     if(isset($_POST['FAIrelease'])){
639       $this->FAIrelease = $_POST['FAIrelease'];
640       $this->_check_missing_release($this->FAIrelease);
641     }
642     if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
643       $this->curbase = base64_decode($_GET['depid']);
644     }
645     if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
646       $folder = $_POST['folder'];
647       foreach($_POST as $name => $value){
648         if(preg_match("/^AddApp_[0-9]*$/",$name)){
649           $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));   
650         }
651       }
652     }
653     if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
654       $folder = $_POST['menu_folder'];
655       $name = $_POST['menu_folder_name'];
656       if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
657         $this->_add_sub_folder($folder,$name);
658       }
659     }
660     if(isset($_POST['app_entry_save'])){ 
661       $this->_save_entry_edit();
662     }
664     if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
665       if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
666         $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
667       }
668     }
670     if(isset($_POST['edit_reset_image'])){
671       $this->edit_entry['ICON'] = "";
672     }
674     if(isset($_POST['app_entry_cancel'])){
675       $this->edit_entry = array();
676       $this->dialog = FALSE;
677     }
678     $this->reload();
679   }
681  
682   /*! \brief Returns the UNIQID of the currently selected release 
683    */ 
684   function _get_release_key($release,$add_if_missing = FALSE)
685   {
686     $release_info = $this->Releases[$release];
688     if($release_info['name'] == "/"){
689       return($this->a_Structure['0']['UNIQID']);
690     }
692     $cur = &$this->a_Structure[0]['ENTRIES'];
693     $s_key = "";
694     $found = FALSE;
695     foreach($release_info['parts'] as $name){
696       foreach($cur as $key => $obj){
697         if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
698           $s_key = $cur[$key]['UNIQID'];
699           $cur = &$cur[$key]['ENTRIES'];
700           $found = TRUE;
701           break;
702         }
703         $found = FALSE;
704       }
705     }
706     if($found){
707       return($s_key);  
708     }  
709     return(FALSE);
710   }
712  
713   /*! \brief Add a new folder folder to the specified folder id
714       @param  String $folder The folder id in where we want to add the new folder.
715       @param  String $name   The name of the new folder.
716    */ 
717   function _add_sub_folder($folder,$name)
718   {
719     $all = $this->_get_all_entries();
720     if($folder == "BASE"){
721       $folder = $this->_get_release_key($this->FAIrelease,TRUE);
722     }
723     
724     if(isset($all[$folder])){
725       $a_folder = array();
726       $a_folder['STATUS'] = "ADDED";
727       $a_folder['NAME']   = $name;
728       $a_folder['UNIQID'] = uniqid();
729       $a_folder['ENTRIES']= array();
730       $a_folder['PARENT'] = $folder;      
731       $a_folder['TYPE']   = "FOLDER";
732       $a_folder['ICON']   = "";
733       $all[$folder]['ENTRIES'][] = $a_folder;
734     }
735   }
738   /* !\brief Remove the given id from the menu structure.
739       @param  String  ID to of the entry we want to remove.
740       @return Boolean TRUE on success
741    */
742   function _remove_entry_id($id)
743   {
744     $all = $this->_get_all_entries();
745     if(isset($all[$id])){
746       $all[$id]['STATUS'] = "REMOVED";
747       return(TRUE);
748     }
749     return(FALSE);
750   }
752   
753   /* !\brief Remove the given id from the menu structure.
754       @param  String  ID to of the entry we want to remove.
755       @return Boolean TRUE on success
756    */
757   function _add_entry($folder_id,$entry,$pos = 0)
758   {
759     $all = $this->_get_all_entries();
761     if(isset($all[$folder_id])){
763       $folder  = &$all[$folder_id];
764       $entries = $entry['ENTRIES'];
766       $entry['UNIQID'] = uniqid();     
767       $entry['PARENT'] = $folder_id;
768       $entry['ENTRIES']= array();
769       $entry['STATUS'] = "ADDED";
770       
771       $cnt = 0; 
772       $new = array();
773       $added =FALSE;
774       foreach($folder['ENTRIES'] as $key => $obj){
775         if($pos == $cnt){
776           $new[] = $entry;
777           $added = TRUE;
778         }
779         $cnt ++;
780         $new[] = $obj;
781       }
782       if(!$added){
783         echo "hmkk";
784         $new[] = $entry;
785       }
786       $all[$folder_id]['ENTRIES'] = $new;
787       foreach($entries as $sub){
788         $this->_add_entry($entry['UNIQID'],$sub);
789       }
790       return(TRUE);
791     }
792     return(FALSE);
793   }
795  
796   /*! \brief Add the application identified by $app_id to folder $folder_id 
797       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
798       @param  Integer app_id    The ID of the application which should be added.
799    */ 
800   function _add_app_id($folder_id,$app_id)
801   {
802     $all = $this->_get_all_entries();
803     if($folder_id == "BASE"){
804       $folder_id = $this->_get_release_key($this->FAIrelease);
805     }
806     if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
808       $new = array();
809       $new['TYPE']  = "ENTRY";
810       $new['NAME']  = $this->apps[$app_id]['cn'][0];
811       $new['UNIQID']= uniqid(); 
812       $new['PARENT']= $folder_id;
813       $new['PARAMETER']= array();
814       if(isset($this->apps[$app_id]['description'][0])){
815         $new['INFO']  = $this->apps[$app_id]['description'][0];
816       }else{
817         $new['INFO']  = "";
818       }
819       $new['STATUS']= "ADDED";
820       $all[$folder_id]['ENTRIES'][] = $new;
821     }
822   }
825   /*! \brief move the object identified by the given ID one position up.
826       @param  String  The ID of the entry to be moved.
827       @return Boolean TRUE on success, else FALSE;
828    */
829   function _move_entry_up($id)
830   {
832     $all = $this->_get_entries_for_release($this->FAIrelease);
833     $all2 = $this->_get_all_entries();
834     $parent = FALSE;
836     foreach($all as $entry){
837       if(isset($entry['STATUS']) && $entry['STATUS'] == "REMOVED"){
838         continue;
839       }
840       if(isset($entry['UNIQID']) && $entry['UNIQID'] == $id){
841         if($parent != FALSE){
842           return($this->__switch_entries($id,"up",$parent));
843         }
844         trigger_error("Unknown ID ".$id);
845         return(FALSE);
846       }else{
847         if(in_array($entry['TYPE'],array("CLOSE","OPEN"))){
848           $parent = $entry['PARENT'];
849         }else{
850           $parent = $entry['UNIQID'];
851         }
852       }
853     }
854     return(FALSE);
855   }
858   /*! \brief move the object identified by the given ID one position down.
859       @param  String  The ID of the entry to be moved.
860       @return Boolean TRUE on success, else FALSE;
861    */
862   function _move_entry_down($id)
863   {
864     $all = $this->_get_entries_for_release($this->FAIrelease);
865     $found = FALSE;
866     foreach($all as $entry){
868       if(isset($entry['STATUS']) && $entry['STATUS'] == "REMOVED"){
869         continue;
870       }
872       if(isset($entry['UNIQID']) && $entry['UNIQID'] == $id){
873         $found = TRUE;
874         continue;
875       }else{
876         if(in_array($entry['TYPE'],array("CLOSE","OPEN"))){
877           $parent = $entry['PARENT'];
878         }else{
879           $parent = $entry['UNIQID'];
880         }
881         if($found){
883     
884           if($id == $parent && $entry['TYPE'] == "OPEN"){
885   
886             for($i = 0 ; $i < count($all) ; $i ++){
887               $sub = $all[$i];
888               if($sub['TYPE'] == "CLOSE" && $sub['PARENT'] == $entry['PARENT']){
889                 $i++;
890                 while($all[$i]['TYPE'] == "ENTRY" && count($all) < $i){
891                   $i++;
892                 }
893                 if(isset($all[$i])){
894                   $parent = $all[$i]['UNIQID'];
895                 }
896               }
897             }
898           }
900           return($this->__switch_entries($id,"down",$parent));
901         }
902       }
903     }
904     return(FALSE);
905   }
908   /*! \brief  Return all entries linear. 
909       @param  Boolean   $add_tags  If TRUE, OPEN/CLOSE Tags will be appended.
910       @param  &Array    Start here, Pointer to an array.
911    */ 
912   function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, $cur = NULL)
913   {
914     $ret = array();
915     if($cur == NULL){
916       $cur = &$this->a_Structure;
917     }
918     foreach($cur as $key => $entry){
920       if($skip_release && $entry['TYPE'] == "RELEASE"){
921         continue;
922       }    
923       if($entry['TYPE'] == "ENTRY"){
924         $found = FALSE;
925         foreach($this->apps as $app){
926           if($app['cn'][0] == $entry['NAME']){
927             $found = TRUE;
928             if(isset($app['description'][0])){
929               $entry['INFO'] = "[".$app['description'][0]."]";
930             }
931             break;
932           }
933         } 
934         if(!$found){
935           $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
936         }
937       }
938       
940       $tmp = $entry;
941       if(!$add_tags){
942         $ret[$tmp['UNIQID']] = &$cur[$key];
943         if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
944           $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
945         }
946       }else{
947       
948         if(isset($tmp['ENTRIES'])){
949           unset($tmp['ENTRIES']);
950         }
951         if($tmp['STATUS'] != "REMOVED"){
952           $ret[] = $tmp;
953           if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
954             $add = false;
955             foreach($entry['ENTRIES'] as $entry){
956               if($entry['STATUS'] != "REMOVED"){
957                 $add = TRUE;
958                 break;
959               }
960             }
962             if($add){
963               $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
964               $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
965               $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
966             }
967           }
968         }
969       }
970     }
971     return($ret);
972   }
975   /* !\brief Switch one entry with another 
976      @param  String  from  The source ID.
977      @param  String  type  "up"/"down" type switched.
978      @param  String  to    The destination ID.
979      return  Boolean TRUE on success 
980    */
981   function __switch_entries($from,$type,$to)
982   {
983     $all = $this->_get_all_entries();
985     $o_to   = &$all[$to];
986     $o_from = &$all[$from];
988     if($o_to['TYPE'] == "ENTRY" && $o_from['TYPE'] == "FOLDER"){
989       echo "FEHLER 1";
990       return;
991     }
994     if($type == "down"){
995       $this->_add_entry($o_to['UNIQID'],$o_from);
996       $this->_remove_entry_id($from);
997     }
1003     print_a(array($o_to,$o_from));
1004   
1005     return;
1006     /***********************
1007      * Source == Destination 
1008      * Move into next parent. 
1009      ************************/
1010     if($to == $from){
1011       $to = $o_to['PARENT'];
1012       $o_to   = &$all[$to];
1013     }
1015     /***********************
1016      * Target is container 
1017      ************************/
1018     if(in_array($o_to['TYPE'],array("FOLDER","RELEASE"))){
1020       /***********************
1021        * Move into parent folder  
1022        *   + Target 
1023        *   |-> Source
1024        ************************/
1025       if($to == $o_from['PARENT']){
1027  
1028         /* Check if source is a folder object 
1029          */
1030         $o_to_sub = &$all[$o_to['PARENT']]; 
1031         if(in_array($o_to_sub['TYPE'],array("FOLDER","RELEASE"))){
1033           $o_from['STATUS'] = "ADDED";
1035           /* Adding new */
1036           $tmp2 = array();  
1037           $cnt = 0; 
1038           foreach($o_to_sub['ENTRIES'] as $key => $entry){
1039             $cnt ++;
1040             if($entry['UNIQID'] == $to){
1041               break;
1042             }
1043           }
1044           if($type == "up"){
1045             $cnt --;
1046  
1047          }
1048          $this->_add_entry($o_to_sub['UNIQID'],$o_from,$cnt);
1050           /* Removing old */
1051           $tmp = array();
1052           if(!$this->_remove_entry_id($from)){
1053             return(FALSE);
1054           }
1055         } 
1056       }else{
1058         /***********************
1059          * Target is NOT parent container
1060          *  + Parent Folder
1061          *  |-> Source 
1062          *  + Destination
1063          ************************/
1065         /* Removing old */
1066         $o_to   = $all[$to];
1067         $o_from = $all[$from];
1068         $this->_add_entry($to,$o_from);
1069         $this->_remove_entry_id($from);
1070       }
1071     }else{
1073       /***********************
1074        * Source and Destination in some Folder.
1075        *  + Parent folder
1076        *  |-> Source
1077        *  |-> Destination
1078        ************************/
1079       $o_to   = &$all[$to];
1080       $o_from = &$all[$from];
1081       $parent = &$all[$o_to['PARENT']];
1083       if($o_to['PARENT'] == $o_from['PARENT']){
1084         $tmp = $all[$to];
1085         $all[$to]   = $o_from;
1086         $all[$from] = $tmp;
1087   
1088         /* Ensure that the app priority is updated */
1089         foreach($parent['ENTRIES'] as $key => $entry){
1090           $parent['ENTRIES'][$key]['STATUS'] = "EDITED";
1091         }
1092       }
1093     }
1094   }
1097   function save()
1098   {
1099     $ldap = $this->config->get_ldap_link();
1100     $all = $this->_get_all_entries();
1101     $prio = 0;
1102     $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
1104     foreach($all as $entry){
1105       $prio ++;
1106       $cur = $entry;
1107       $dn = "";
1109       do{  
1110         if($cur['TYPE'] == "ENTRY"){
1111           $dn.= "cn=".$cur['NAME'].",";
1112         }elseif($cur['TYPE'] == "FOLDER"){
1113           $dn.= "cn=".$cur['NAME'].",";
1114         }elseif($cur['TYPE'] == "RELEASE"){
1115           $dn.= "ou=".$cur['NAME'].",";
1116         }elseif($cur['TYPE'] == "BASE"){
1117         }
1118         if(!isset($all[$cur['PARENT']])){
1119           $cur = NULL;
1120         }else{
1121           $cur = $all[$cur['PARENT']];
1122         }
1123       }while(is_array($cur));
1125       $cur_dn = $dn.$this->dn;
1127       $attrs = array();
1128       switch($entry['TYPE']){
1129         case "ENTRY"    :
1130         { 
1131           $attrs['objectClass'] = "gotoMenuEntry";
1132           $attrs['cn']          = $entry['NAME'];
1133           $attrs['gosaApplicationPriority'] = $prio;
1134           $attrs['gosaApplicationParameter'] = array(); 
1135           
1136           
1137           foreach($entry['PARAMETER'] as $name => $value){
1138             $attrs['gosaApplicationParameter'][] = $name.":".$value; 
1139           }
1140           if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1141             unset($attrs['gosaApplicationParameter']);
1142           } 
1143         }
1144         break;
1145         case "FOLDER"   : 
1146         { 
1147           $attrs['objectClass'] = "gotoSubmenuEntry";
1148           $attrs['cn']          = $entry['NAME'];
1149           $attrs['gosaApplicationPriority'] = $prio;
1150           if($entry['STATUS'] != "ADDED"){
1151             $attrs['gosaApplicationIcon'] = array();
1152           }
1153           
1154           if(!empty($entry['ICON'])){
1155             $attrs['gosaApplicationIcon']     = $entry['ICON'];
1156           }
1157         }
1158         break;
1159         case "RELEASE"  : 
1160         { 
1161           $attrs['ou']            = $entry['NAME'];
1162           $attrs['objectClass']   = array();
1163           $attrs['objectClass'][] = "top";
1164           $attrs['objectClass'][] = "organizationalUnit";
1165           $attrs['objectClass'][] = "FAIbranch";
1166           if(!empty($entry['FAIstate'])){
1167             $attrs['FAIstate']      = $entry['FAIstate'];
1168           }
1169         }
1170         break;
1171       }
1172   
1173       if($entry['STATUS'] == "LOADED"){
1174         continue;
1175       }
1176       if($entry['STATUS'] == "REMOVED"){
1177         $Actions['Remove'][$cur_dn] = $cur_dn;
1178       }
1179       if($entry['STATUS'] == "EDITED"){
1180         $Actions['Edit'][$cur_dn] = $attrs;
1181       }
1182       if($entry['STATUS'] == "ADDED"){
1183         $Actions['Add'][$cur_dn] = $attrs;
1184       }
1185     }
1187     $ldap = $this->config->get_ldap_link();
1188     $ldap->cd($this->config->current['BASE']);
1189     foreach($Actions['Remove'] as $dn){
1190       $ldap->cd($dn);
1191       $ldap->cat($dn);
1192       if($ldap->count()){
1193         $ldap->rmdir_recursive($dn);
1194         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1195       }
1196     }
1197     foreach($Actions['Add'] as $dn => $data){
1198       $ldap->cd($dn);
1199       $ldap->cat($dn);
1200       if(!$ldap->count()){
1201         $ldap->add($data);
1202         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1203       }
1204     }
1205     foreach($Actions['Edit'] as $dn => $data){
1206       $ldap->cd($dn);
1207       $ldap->cat($dn);
1208       if($ldap->count()){
1209         $ldap->modify($data);
1210         show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1211       }
1212     }
1213     $this->_load_menu_structure();
1214   }
1217   /* Return plugin informations for acl handling  */ 
1218   static function plInfo()
1219   {
1220     return (array(
1221           "plShortName"   => _("Applications"),
1222           "plDescription" => _("Group applications"),
1223           "plSelfModify"  => FALSE,
1224           "plDepends"     => array(),
1225           "plPriority"    => 0,
1226           "plSection"     => array("admin"),
1227           "plCategory"    => array("groups"),
1228           "plProvidedAcls"=> array(
1229             "gosaMemberApplication"     => _("Application"),
1230             "FAIrelease"                => _("Release"),
1231             "gosaApplicationParameter"  => _("Application parameter"))
1232           ));
1233   }
1236   function PrepareForCopyPaste($source)
1237   {
1238   }
1241   function multiple_save_object()
1242   {
1243     if(isset($_POST['group_apps_multi'])){
1244       $this->save_object(); 
1245       plugin::multiple_save_object();    
1246   
1247       /* Get posts */
1248       foreach(array("apps") as $attr){
1249         if(isset($_POST['use_'.$attr])) {
1250           $this->multi_boxes[] = $attr;
1251         }
1252       }
1253     }
1254   }
1255   
1257   function get_multi_edit_values()
1258   {
1259     $ret = plugin::get_multi_edit_values();
1261     if(in_array("apps",$this->multi_boxes)){
1262       $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1263       $ret['Categories']               = $this->Categories;
1264       $ret['gosaMemberApplication']    = $this->gosaMemberApplication;
1265       $ret['FAIrelease']               = $this->FAIrelease;
1266       $ret['appoption']                = $this->appoption;
1267     }
1268     return($ret);
1269   }
1271 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1272 ?>