Code

Only search inside of the 'root'. Closes #398
[gosa.git] / gosa-plugins / goto / admin / groups / apps / class_groupApplication.inc
1 <?php
2 class appgroup extends plugin
3 {
4   var $config;
5   var $curbase;
7   /* Contains the menu structure in an array.
8    */
9   var $a_Structure= array();
10   var $a_Structure_on_load = array();
11   var $Releases;
12   var $FAIrelease = 0;
13   var $apps = array();
14   var $_cache = array();
16   var $app_parameter = array();
17   var $edit_entry    = array();
18   var $enableReleaseManagement = FALSE;
19   
21   public function __construct(&$config, $dn= NULL, $parent= NULL)
22   {
23     plugin::plugin($config,$dn,$parent);
24     $this->dn = $dn; 
25     $this->_load_menu_structure();
26     $this->a_Structure_on_load = $this->a_Structure;
28     /* Check if we have relase mangement enabled and prepare group application for release management */
29     $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
30     if(!empty($tmp)){
31       $this->enableReleaseManagement = true;
32     }
34     $this->Releases   = $this->getReleases();
35     $this->FAIrelease = "/";
36     $this->curbase = $this->config->current['BASE'];
37     $this->reload();
38   
39     $this->is_account = FALSE;
40     if(count($this->_get_all_entries()) > 1){
41       $this->is_account= TRUE;
42     }   
43     $this->initially_was_account = $this->is_account;
44   }
47   /*! \brief Reload the list of applications for the currently selected release 
48    */
49   function reload()
50   {
51     $ret = array();
52     $release_info = $this->Releases[$this->FAIrelease];
54     if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
56       $ldap = $this->config->get_ldap_link();
57       $ldap->cd($this->config->current['BASE']);
58       $ldap->search("ou=apps",array("dn"));
59       $app_deps = array();
60       while($attrs = $ldap->fetch()){
61         $app_deps[] = $attrs['dn'];
62       }
64       foreach($app_deps as $dep){
65         $ldap->cd($dep);
66         $ldap->search("objectClass=FAIbranch",array("dn"));
67         while($attrs = $ldap->fetch()){
68           $app_deps[] = $attrs['dn'];
69         }
70       }
72       foreach($app_deps as $dep){
73         if(preg_match("/^".normalizePreg($release_info['suffix'])."/",$dep)){
74           $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
75         }
76       }
78       $tmp = array();
79       foreach($ret as $key => $app){
80         $tmp[$key] = $app['cn'][0];
81       }
82       natcasesort($tmp);
83       $res = array();
84       foreach($tmp as $key => $app){
85         $res[] = $ret[$key];
86       }
88       $this->_cache['ReleaseApps'][$release_info['suffix']] = $res;
89     } 
90     $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
91   }
93   
94   
95   
96   /*! \brief generate a list of available releases
97       @return return an array with all available releases.
98     */
99   function getReleases()
100   {
101     $ret =array("/" => array("name" => "/", "found" => TRUE , "parts" => array(),"suffix" => get_ou('applicationou')));
102     if($this->enableReleaseManagement){
104       /* Only display those releases that we are able to read */
105       $dn     = get_ou("applicationou").$this->config->current['BASE'];
106       $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
107       $res    = get_sub_list($filter,array("application","fai"), array(get_ou("applicationou"),get_ou("faiou")),$dn, array("ou","FAIstate"), GL_SUBSEARCH);
110       foreach($res as $attrs){
111         if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
112           $bb     = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
113           $parts  = array_reverse(split("ou=",$bb));
115           $str ="";
116           foreach($parts as $key => $part){
117             if(empty($part)) {
118               unset($parts[$key]);
119               continue;
120             }
121             $part = str_replace(",","",$part);
122             $str .= $part."/";
123             $parts[$key] = $part;
124           }
125           $name = preg_replace("/\/$/","",$str);
126           if(empty($name)) {
127             $name ="/";
128           }
129           $FAIstate = "";
130           if(isset($attrs['FAIstate'])){
131             $FAIstate = $attrs['FAIstate'][0];
132           }
134           $all = $this->_get_all_entries();
135           $found = FALSE;
136           foreach($all as $entry){
137             if(isset($entry['DN']) && preg_match("/^".normalizePreg($bb)."/",$entry['DN'])){
138               $found =TRUE;
139               break;
140             }
141           }
143           $cnt = 0;
144           $ret[$name] = array("name"     => $name, 
145               "found"    => $found,
146               "FAIstate" => $FAIstate,
147               "dn"       => $attrs['dn'], 
148               "parts"    => $parts,"suffix" => $bb.get_ou('applicationou'));
149         }
150       }
151     }
152     ksort($ret);
153     return($ret);
154   }
157   /*! \brief Load the menu structure from ldap and create a multi dimensional array
158    */
159   function _load_menu_structure()
160   {
161     $this->a_Structure  = array();
162     $ldap = $this->config->get_ldap_link();
163     $ldap->cd($this->dn);
164     $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
166     $base =  array();
167     $base['UNIQID'] = uniqid();
168     $base['PARENT'] = 0; 
169     $base['NAME']   = "";
170     $base['TYPE']   = "BASE";
171     $base['ENTRIES']= array();
172     $base['STATUS'] = "LOADED";
173     
174     $this->a_Structure[0] = $base;
176     while($attrs = $ldap->fetch()){
177       $cur = &$this->a_Structure[0]['ENTRIES'];
178       $parent_id    = $base['UNIQID'];
179       $sub_dn       = preg_replace("/,".normalizePreg($this->dn)."$/","",$attrs['dn']);
180       $sub_dn_array = split("\,",$sub_dn);
182       $found = true;
183       for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
184         $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
185         
186         if($i > 0){
187           $found =FALSE;
188           foreach($cur as $key => $entry){
189             if($entry['NAME'] == $name){
190               $cur = &$cur[$key]['ENTRIES'];
191               $parent_id = $entry['UNIQID'];
192               $found =true;
193               break;
194             }
195           }
196         }else{
197           
198           if(!$found){
199             break;
200           }
201           $priority = 1;
202           if(isset($attrs['gosaApplicationPriority'])){
203             $priority= $attrs['gosaApplicationPriority'][0];
204           }
205           while(isset($cur[$priority])){
206             $priority ++;
207           }
209           $data = array();
210           if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
211             $type = "FOLDER";
213             $data['ICON'] = "";
214             if(isset($attrs['gosaApplicationIcon'])){
215               $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
216             }
218           }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
220             $type = "ENTRY";
221             $data['INFO'] = "";
222             $data['PARAMETER'] = array();
223             if(isset($attrs['gosaApplicationParameter'])){
224               for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
225                 if(preg_match("/:/",$attrs['gosaApplicationParameter'][$p])){
226                   $tmp = split(":",$attrs['gosaApplicationParameter'][$p]);
227                   $data['PARAMETER'][$tmp[0]] = $tmp[1];
228                 }elseif($attrs['gosaApplicationParameter'][$p] == "*separator*"){
229                   $type = "SEPERATOR";
230                   $data['PARAMETER'] = array();
231                   break;
232                 }
233               }
234             }
235           }elseif(in_array("FAIbranch",$attrs['objectClass'])){
237             $type = "RELEASE";
238             if(isset($attrs['FAIstate'][0])){
239               $data['FAIstate'] = $attrs['FAIstate'][0];
240             }else{
241               $data['FAIstate'] = "";
242             }
243           }
245           $data['LDAP_ATTRS'] = $attrs;
246           $data['DN']       = $attrs['dn'];
247           $data['NAME']     = $name;
248           $data['TYPE']     = $type;
249           $data['PRIORITY'] = $priority;
250           $data['ENTRIES']  = array();
251           $data['UNIQID']   = uniqid();
252           $data['PARENT']   = $parent_id;
253           $data['STATUS']   = "LOADED";
254           $cur[$priority]   = $data;
255           ksort($cur);
256         }
257       }
258     }
259   } 
262   function execute()
263   {
264     /* Call parent execute */
265     plugin::execute();
267     if(isset($_GET['r'])) $this->__construct($this->config,$this->dn);
269     if (isset($_POST['modify_state'])){
270       $this->is_account = !$this->is_account;
271     }
273     /* Do we represent a valid account? */
274     if (!$this->is_account){
275       $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Menu")), msgPool::featuresDisabled(_("Menu")));
276       return ($display);
277     }
279     $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Menu")), msgPool::featuresEnabled(_("Menu")));
281     if(isset($_GET['send'])){
282       $id = $_GET['send'];
283       $all = $this->_get_all_entries();
284       if(isset($all[$id])){
285         send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
286         exit;
287       }
288     }
290     if(isset($_GET['r']))
291     $this->__construct($this->config,$this->dn);
293     if(count($this->edit_entry)){
294       if($this->edit_entry['TYPE'] == "ENTRY"){
295         $smarty = get_smarty();
296         $smarty->assign("type", "ENTRY");
297         $smarty->assign("entry",$this->edit_entry);
298         $smarty->assign("paras",$this->app_parameter);
299         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
300         return($display);
301       }
302       if($this->edit_entry['TYPE'] == "FOLDER"){
303         $smarty = get_smarty();
305         session::set("binarytype" , "image/jpeg");
306         session::set("binary" , $this->edit_entry['ICON']);
307   
308         $smarty->assign("rand", microtime(TRUE));
309         $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0); 
310         $smarty->assign("type", "FOLDER");
311         $smarty->assign("entry",$this->edit_entry);
312         $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
313         return($display);
314       }
315     }
317     $smarty = get_smarty();
318     $smarty->assign("plug_id" , $_GET['plug']);
320     /* Create application list */
321     $div = new divSelectBox("appgroup");
322     $div->SetHeight(300);
323     $departments = array();
324     $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
325     foreach($res as $value){
326       $fdn = $value['dn'];
327       $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
328       $fdn= @LDAP::fix($fdn);
329       if($value["description"][0]!=".."){
330         $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
331       }else{
332         $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
333       }
334     }
336     $linkopen = "<a href='?plug=".$_GET['plug']."&amp;act=depopen&amp;depid=%s'>%s</a>";
338     /* Create base back entry */
339     $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
340     if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
341       $div->AddEntry(array(
342             array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
343               "attach"=>"style='border:0px;'")
344             ));
345     }
347     /* Append departments for current base */
348     foreach($departments as $key => $app){
349       $div->AddEntry(array(
350             array("string"=>"<img class='center' src='images/folder.png' alt='"._("department")."'>&nbsp;".sprintf($linkopen,
351                 base64_encode($key),$app),
352               "attach"=>"style='border:0px;'")
353             ));
354     }
356   
357     /* Add applications found on this base */
358     $used_apps = $this->_get_used_entry_name();
359     foreach($this->apps as $key => $app){
360       if(in_array($app['cn'][0],$used_apps)){
361         continue;
362       }
363       if(!preg_match("/".get_ou('applicationou').normalizePreg($this->curbase)."$/",$app['dn'])){
364         continue;
365       }
367       $name = $app['cn'][0];
368       if(isset($app['description'])){
369         $name .= "&nbsp;[".$app['description'][0]."]";
370       }
371       $div->AddEntry(array(
372             array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
373               "<img class='center' src='images/select_application.png' alt='"._("application")."'>&nbsp;".$name,
374               "attach"=>"style='border:0px;'")
375             ));
376     }
378     
379     $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
380     $smarty->assign("FAIrelease",$this->FAIrelease);
381     $smarty->assign("app_list",$div->DrawList());
382     $smarty->assign("i",0);
383     $smarty->assign("releases",$this->Releases);
384     $smarty->assign("folders" , $this->_get_folder_names());
385     $entries = $this->_get_entries_for_release($this->FAIrelease);
386     $smarty->assign("entries",$entries);
387     $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
388     return($display);
389   }
391    
392   /*! \brief Returns all used folder names 
393       @return Array  All used folder names.
394    */ 
395   function _get_folder_names()
396   {
397     $data = $this->_get_entries_for_release($this->FAIrelease);
398     $all    = $this->_get_all_entries();
399     $ret = array("BASE" => ".");
400     foreach($data as $entry){
402       if($entry['TYPE'] == "FOLDER"){
403         $str = $entry['NAME'];
404         $parent = $entry['PARENT'];
405         $i = 10;
406         while(isset($all[$parent]) && $i){  
407           $i --;
408           $parent_o = $all[$parent];
409           $str      = $parent_o['NAME']."/".$str;
410           $parent   = $all[$parent_o['UNIQID']]['PARENT'];
411         }        
412         $ret[$entry['UNIQID']] = $str;
413       }
414     }
415     return($ret);
416   }
419   /*! \brief return all used applications 
420       @return Array  All used applications.
421    */ 
422   function _get_used_entry_name()
423   {
424     $data = $this->_get_entries_for_release($this->FAIrelease);
425     $ret = array();
426     foreach($data as $entry){
427       if($entry['TYPE'] == "ENTRY"){
428         $ret[] = $entry['NAME'];
429       }
430     }
431     return($ret);
432   }
435   /*! \brief Returns all folder an entries for the selected release 
436       @return Array  Returns the complete menu structure for the given array.
437    */ 
438   function _get_entries_for_release($release,$cur = NULL)
439   {
440     $all = $this->_get_all_entries();
441     $key = $this->_get_release_key($release);
442     if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
443       $res = $this->_get_all_entries(TRUE,TRUE,$all[$key]['ENTRIES']);
444       return($res);
445     } 
446     return(array());
447   }
450   /*! \brief Save the currently edited entry */
451   function _save_entry_edit()
452   {
453     $all    = $this->_get_all_entries();
454     $entry  = $this->edit_entry;
455     $r_entry= &$all[$entry['UNIQID']];
457     if($entry['TYPE'] == "ENTRY"){
458       $r_entry['PARAMETER'] = $this->app_parameter;
459       $r_entry['STATUS'] = "EDITED";
460     }
461     if($entry['TYPE'] == "FOLDER"){
462       $r_entry['ICON']   = $this->edit_entry['ICON'];
463       $r_entry['STATUS'] = "EDITED";
464     }
465     $this->dialog = FALSE;
466     $this->edit_entry = array();
467   }
470   /*! \brief prepare the entry with the given ID, to be edited.
471    */
472   function _edit_entry_edit($id)
473   {
474     $all   = $this->_get_all_entries();
475     $entry = $all[$id];
477     $this->app_parameter = array();
478     if($entry['TYPE'] == "ENTRY"){
479       $found = FALSE;
480       foreach($this->apps as $id => $app){
482         if($app['cn'][0] == $entry['NAME']){
483           $found = TRUE;
484           break;
485         }
486       }
487       if($found){
488       
489         /* Create a list of editable parameter */
490         if(isset($app['gosaApplicationParameter'])){
491           for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
492             $para = $app['gosaApplicationParameter'][$i];
493             $tmp  = split(":",$para);
494             $this->app_parameter[$tmp[0]] = $tmp[1];
495           }
496         }
498         /* Overwrite parameters with entry parameters */
499         foreach($entry['PARAMETER'] as $name => $value){
500           $this->app_parameter[$name] = $value;
501         }
502         
503         $this->dialog = TRUE;
504         $this->edit_entry = $entry;
505       }
506     }
508     if($entry['TYPE'] == "FOLDER"){
509       $this->dialog = TRUE;
510       $this->edit_entry = $entry;
511     }
512   }
515   function remove_from_parent()
516   {
517     $ldap = $this->config->get_ldap_link();
518     $ldap->cd($this->dn);
519     $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
520     $a_remove = array();
521     while($attrs = $ldap->fetch()){
522       $a_remove[] = $attrs['dn'];
523     }
524     foreach($a_remove as $remove){
525       $ldap->rmdir_recursive($remove);
526       if (!$ldap->success()){
527         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
528       }
529     }
530     $this->_load_menu_structure();
531   }
534   function check()
535   {
536   }
539   /*! \brief Create missing releases, if there is a release selected \
540               that is currently not part of the menu structure \
541               then create this entry
542    */
543   function _check_missing_release($release)
544   {
545     $release_info = $this->Releases[$release];
547     $parent_id = $this->a_Structure[0]['UNIQID'];
548     $cur = &$this->a_Structure[0]['ENTRIES'];
549     for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
550       $part = $release_info['parts'][$i];
551       $found = FALSE;
552       foreach($cur as $key => $name){
553         if($name['NAME'] == $part){
554           $parent_id = $cur[$key]['UNIQID'];
555           $cur = &$cur[$key]['ENTRIES'];
556           
557           $found =TRUE;
558           break;
559         }
560       }
561       if(!$found){
562         $release           =  array();
563         $release['UNIQID'] = uniqid();
564         $release['PARENT'] = $parent_id;
565         $release['NAME']   = $part;
566         $release['TYPE']   = "RELEASE";
567         $release['ENTRIES']= array();
568         $release['STATUS']   = "ADDED";
569         $release['FAIstate'] =  $release_info['FAIstate'];
570         $cur[] = $release;
571         $i --;
572       }
573     }
574   }
578   function _move_entry($id,$dir)
579   {
580     $all   = $this->_get_all_entries();
581     if($dir == "down"){
582       $to = $this->_get_next($id);
583     } 
584     if($dir == "up"){
585       $to = $this->_get_last($id);
586     }
588     if(!$to){
589       return;
590     }
592     $o_to   = $all[$to];
593     $o_from = $all[$id];
595     if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
596       $to    = $this->_get_next($to,$o_from['PARENT']); 
597       $o_to  = $all[$to]; 
598     }
599  
600  
601     /* Target is ENTRY && same BASE, just switch */
602     if($o_to['PARENT'] == $o_from['PARENT'] ){
603       $parent = $all[$o_to['PARENT']];
604       $pos = 0;
605       foreach($parent['ENTRIES'] as $entry){
606         $pos ++;
607         if($entry['UNIQID'] == $to){
608           break;
609         }
610       }
611       if($dir == "up" && $pos > 0){
612         $pos --;
613       }
614       $this->_add_entry($parent['UNIQID'],$o_from,$pos);
615       $this->_remove_entry_id($id);
616       return(TRUE);
617     }
618     return(FALSE);
619   }
622  
623   function _get_last($id)
624   {
625     $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
626     for($i = 0 ; $i < count($all_l) ; $i ++){
627       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
628         $i++;
629         break;
630       }
631     }
632     while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
633       $i++;
634     }
636     if(!isset($all_l[$i])){
637       return(FALSE);
638     }
640     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
641       return($all_l[$i]['PARENT']);
642     }     
644     return($all_l[$i]['UNIQID']);
645   }
647  
648   function _get_next($id,$parent = 0)
649   {
650     $all_l = $this->_get_entries_for_release($this->FAIrelease);
651     for($i = 0 ; $i < count($all_l) ; $i ++){
652       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
653         $i++;
654         break;
655       }
656     }
657     if($parent != 0){
658       while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
659         $i++;
660       }
661     }else{
662       while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
663         $i++;
664       }
665     }
666     if(!isset($all_l[$i])){
667       return(FALSE);
668     }
669     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
670       return($all_l[$i]['PARENT']);
671     }
672     return($all_l[$i]['UNIQID']);
673   }
678   /* !\brief Handle ui POSTS, like sort up/down/delete
679    */ 
680   function save_object()
681   {
682     foreach($_POST as $name => $value){
683       if(preg_match("/del_/",$name)){
684         $id = preg_replace("/^del_/","",$name);
685         $id = preg_replace("/_(x|y)$/","",$id);
686         $this->_remove_entry_id($id);
687         break;
688       }
689       if(preg_match("/app_entry_edit/",$name)){
690         $id = preg_replace("/^app_entry_edit/","",$name);
691         $id = preg_replace("/_(x|y)$/","",$id);
692         $this->_edit_entry_edit($id);
693         break;
694       }
695       if(preg_match("/up_/",$name)){
696         $id = preg_replace("/^up_/","",$name);
697         $id = preg_replace("/_(x|y)$/","",$id);
698         $this->_move_entry($id,"up");
699         break;
700       }
701       if(preg_match("/down_/",$name)){
702         $id = preg_replace("/^down_/","",$name);
703         $id = preg_replace("/_(x|y)$/","",$id);
704         $this->_move_entry($id,"down");
705         break;
706       }
707       if(preg_match("/^parameter_/",$name) && 
708         count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
709         $name = preg_replace("/^parameter_/","",$name);
710         $this->app_parameter[$name] = $value;
711       }
712     }
713     if(isset($_POST['FAIrelease'])){
714       $this->FAIrelease = $_POST['FAIrelease'];
715       $this->_check_missing_release($this->FAIrelease);
716     }
717     if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
718       $this->curbase = base64_decode($_GET['depid']);
719     }
720     if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
721       $folder = $_POST['folder'];
722       foreach($_POST as $name => $value){
723         if(preg_match("/^AddApp_[0-9]*$/",$name)){
724           $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));   
725         }
726       }
727     }
729     /* Add seperator */
730     if(isset($_POST['add_seperator']) && isset($_POST['menu_folder'])){
731       $folder = $_POST['menu_folder'];
732       $this->_add_seperator($folder);
733     }
735     if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
736       $folder = $_POST['menu_folder'];
737       $name = $_POST['menu_folder_name'];
738       if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
739         $this->_add_sub_folder($folder,$name);
740       }
741     }
742     if(isset($_POST['app_entry_save'])){ 
743       $this->_save_entry_edit();
744     }
746     if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
747       if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
748         $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
749       }
750     }
752     if(isset($_POST['edit_reset_image'])){
753       $this->edit_entry['ICON'] = "";
754     }
756     if(isset($_POST['app_entry_cancel'])){
757       $this->edit_entry = array();
758       $this->dialog = FALSE;
759     }
760     $this->reload();
761   }
763  
764   /*! \brief Returns the UNIQID of the currently selected release 
765    */ 
766   function _get_release_key($release,$add_if_missing = FALSE)
767   {
768     $release_info = $this->Releases[$release];
770     if($release_info['name'] == "/"){
771       return($this->a_Structure['0']['UNIQID']);
772     }
774     $cur = &$this->a_Structure[0]['ENTRIES'];
775     $s_key = "";
776     $found = FALSE;
777     foreach($release_info['parts'] as $name){
778       foreach($cur as $key => $obj){
779         if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
780           $s_key = $cur[$key]['UNIQID'];
781           $cur = &$cur[$key]['ENTRIES'];
782           $found = TRUE;
783           break;
784         }
785         $found = FALSE;
786       }
787     }
788     if($found){
789       return($s_key);  
790     }  
791     return(FALSE);
792   }
794  
795   /*! \brief Add a new folder folder to the specified folder id
796       @param  String $folder The folder id in where we want to add the new folder.
797       @param  String $name   The name of the new folder.
798    */ 
799   function _add_sub_folder($folder,$name)
800   {
801     $all = $this->_get_all_entries();
802     if($folder == "BASE"){
803       $folder = $this->_get_release_key($this->FAIrelease,TRUE);
804     }
805     
806     if(isset($all[$folder])){
807       $a_folder = array();
808       $a_folder['STATUS'] = "ADDED";
809       $a_folder['NAME']   = $name;
810       $a_folder['UNIQID'] = uniqid();
811       $a_folder['ENTRIES']= array();
812       $a_folder['PARENT'] = $folder;      
813       $a_folder['TYPE']   = "FOLDER";
814       $a_folder['ICON']   = "";
815       $all[$folder]['ENTRIES'][] = $a_folder;
816     }
817   }
820   /* !\brief Remove the given id from the menu structure.
821       @param  String  ID to of the entry we want to remove.
822       @return Boolean TRUE on success
823    */
824   function _remove_entry_id($id)
825   {
826     $all = $this->_get_all_entries();
827     if(isset($all[$id])){
828       $all[$id]['STATUS'] = "REMOVED";
829       $all[$id]['ENTRIES'] = array();
830       return(TRUE);
831     }
832     return(FALSE);
833   }
835   
836   /* !\brief Remove the given id from the menu structure.
837       @param  String  ID to of the entry we want to remove.
838       @return Boolean TRUE on success
839    */
840   function _add_entry($folder_id,$entry,$pos = 0)
841   {
842     $all = $this->_get_all_entries();
844     /* Do not add removed */
845     if($entry['STATUS'] == "REMOVED"){
846       return;
847     }
849     if(isset($all[$folder_id])){
851       if(!isset($entry['ENTRIES'])){
852         $entries = array();
853       }else{
854         $entries = $entry['ENTRIES'];
855       }
857       $folder  = &$all[$folder_id];
859       $entry['UNIQID'] = uniqid();     
860       $entry['PARENT'] = $folder_id;
861       $entry['ENTRIES']= array();
862       $entry['STATUS'] = "ADDED";
863       
864       $cnt = 0; 
865       $new = array();
866       $added =FALSE;
867       foreach($folder['ENTRIES'] as $key => $obj){
868         if($obj['STATUS'] == "LOADED"){
869           $obj['STATUS'] = "EDITED";
870         }
871         if($pos == $cnt){
872           $new[] = $entry;
873           $added = TRUE;
874         }
875         $cnt ++;
876         $new[] = $obj;
877       }
878       if(!$added){
879         $new[] = $entry;
880       }
881   
882       $all[$folder_id]['ENTRIES'] = $new;
883       foreach($entries as $sub){
884         $this->_add_entry($entry['UNIQID'],$sub,-1);
885       }
886       return(TRUE);
887     }
888     return(FALSE);
889   }
891  
892   /*! \brief Add the application identified by $app_id to folder $folder_id 
893       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
894       @param  Integer app_id    The ID of the application which should be added.
895    */ 
896   function _add_app_id($folder_id,$app_id)
897   {
898     $all = $this->_get_all_entries();
899     if($folder_id == "BASE"){
900       $folder_id = $this->_get_release_key($this->FAIrelease);
901     }
902     if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
904       $new = array();
905       $new['TYPE']  = "ENTRY";
906       $new['NAME']  = $this->apps[$app_id]['cn'][0];
907       $new['UNIQID']= uniqid(); 
908       $new['PARENT']= $folder_id;
909       $new['PARAMETER']= array();
910       if(isset($this->apps[$app_id]['description'][0])){
911         $new['INFO']  = $this->apps[$app_id]['description'][0];
912       }else{
913         $new['INFO']  = "";
914       }
915       $new['STATUS']= "ADDED";
916       $all[$folder_id]['ENTRIES'][] = $new;
917     }
918   }
921   /*! \brief Add the application identified by $app_id to folder $folder_id 
922       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
923       @param  Integer app_id    The ID of the application which should be added.
924    */ 
925   function _add_seperator($folder_id)
926   {
927     $all = $this->_get_all_entries();
928     if($folder_id == "BASE"){
929       $folder_id = $this->_get_release_key($this->FAIrelease);
930     }
932     if(isset($all[$folder_id])){
933       $new = array();
934       $new['TYPE']  = "SEPERATOR";
935       $new['NAME']  = "SEPERATOR";
936       $new['UNIQID']= uniqid(); 
937       $new['PARENT']= $folder_id;
938       $new['PARAMETER']= array();
939       $new['STATUS']= "ADDED";
940       $all[$folder_id]['ENTRIES'][] = $new;
941     }
942   }
945   /*! \brief  Return all entries linear. 
946       @param  Boolean   $add_tags  If TRUE, OPEN/CLOSE Tags will be appended.
947       @param  &Array    Start here, Pointer to an array.
948    */ 
949   function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, &$cur = NULL)
950   {
951     $ret = array();
952     if($cur == NULL){
953       $cur = &$this->a_Structure;
954     }
955     foreach($cur as $key => $entry){
957       if($skip_release && $entry['TYPE'] == "RELEASE"){
958         continue;
959       }    
960       if($entry['TYPE'] == "ENTRY"){
961         $found = FALSE;
962         foreach($this->apps as $app){
963           if($app['cn'][0] == $entry['NAME']){
964             $found = TRUE;
965             if(isset($app['description'][0])){
966               $entry['INFO'] = "[".$app['description'][0]."]";
967             }
968             break;
969           }
970         } 
971         if(!$found){
972           $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
973         }
974       }
975       
977       $tmp = $entry;
978       if(!$add_tags){
979         $ret[$tmp['UNIQID']] = &$cur[$key];
980         if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
981           $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
982         }
983       }else{
984       
985         if(isset($tmp['ENTRIES'])){
986           unset($tmp['ENTRIES']);
987         }
988         if($tmp['STATUS'] != "REMOVED"){
989           $ret[] = $tmp;
990           if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
991             $add = false;
992             foreach($entry['ENTRIES'] as $entry){
993               if($entry['STATUS'] != "REMOVED"){
994                 $add = TRUE;
995                 break;
996               }
997             }
999             if($add){
1000               $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
1001               $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1002               $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
1003             }
1004           }
1005         }
1006       }
1007     }
1008     return($ret);
1009   }
1012   function save()
1013   {
1014     $ldap = $this->config->get_ldap_link();
1015     $all = $this->_get_all_entries();
1016     $prio = 0;
1017     $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
1019     $sep_id = 0;
1020     foreach($all as $entry){
1021       $prio ++;
1022       $cur = $entry;
1023       $dn = "";
1025       do{  
1026         if($cur['TYPE'] == "SEPERATOR"){
1027           $sep_id ++;
1028           $dn.= "cn=seperator_".$sep_id.",";
1029         }elseif($cur['TYPE'] == "ENTRY"){
1030           $dn.= "cn=".$cur['NAME'].",";
1031         }elseif($cur['TYPE'] == "FOLDER"){
1032           $dn.= "cn=".$cur['NAME'].",";
1033         }elseif($cur['TYPE'] == "RELEASE"){
1034           $dn.= "ou=".$cur['NAME'].",";
1035         }elseif($cur['TYPE'] == "BASE"){
1036         }
1037         if(!isset($all[$cur['PARENT']])){
1038           $cur = NULL;
1039         }else{
1040           $cur = $all[$cur['PARENT']];
1041         }
1042       }while(is_array($cur));
1044       $cur_dn = $dn.$this->dn;
1046       $attrs = array();
1048       switch($entry['TYPE']){
1049         case "SEPERATOR"    :
1050         { 
1051           $attrs['objectClass'] = array("gotoMenuEntry");
1052           $attrs['cn']          = "seperator_".$sep_id;
1053           $attrs['gosaApplicationPriority'] = $prio;
1054           $attrs['gosaApplicationParameter'] = "*separator*";
1055         }
1056         break;
1057         case "ENTRY"    :
1058         { 
1059           $attrs['objectClass'] = array("gotoMenuEntry");
1060           $attrs['cn']          = $entry['NAME'];
1061           $attrs['gosaApplicationPriority'] = $prio;
1062           $attrs['gosaApplicationParameter'] = array(); 
1063           
1064           
1065           foreach($entry['PARAMETER'] as $name => $value){
1066             $attrs['gosaApplicationParameter'][] = $name.":".$value; 
1067           }
1068           if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1069             unset($attrs['gosaApplicationParameter']);
1070           } 
1071         }
1072         break;
1073         case "FOLDER"   : 
1074         { 
1075           $attrs['objectClass'] = array("gotoSubmenuEntry");
1076           $attrs['cn']          = $entry['NAME'];
1077           $attrs['gosaApplicationPriority'] = $prio;
1078           if($entry['STATUS'] != "ADDED"){
1079             $attrs['gosaApplicationIcon'] = array();
1080           }
1081           
1082           if(!empty($entry['ICON'])){
1083             $attrs['gosaApplicationIcon']     = $entry['ICON'];
1084           }
1085         }
1086         break;
1087         case "RELEASE"  : 
1088         {
1089           $attrs['ou']            = $entry['NAME'];
1090           $attrs['objectClass']   = array();
1091           $attrs['objectClass'][] = "top";
1092           $attrs['objectClass'][] = "organizationalUnit";
1093           $attrs['objectClass'][] = "FAIbranch";
1094           if(!empty($entry['FAIstate'])){
1095             $attrs['FAIstate']      = $entry['FAIstate'];
1096           }
1097         }
1098         break;
1099       }
1100  
1101       /* Append missing ObjectClasses,  ...  Tagging */
1102       if(isset($entry['LDAP_ATTRS'])){
1103         for($i = 0 ; $i < $entry['LDAP_ATTRS']['objectClass']['count']; $i ++){
1104           $oc = $entry['LDAP_ATTRS']['objectClass'][$i];
1105           if(!in_array($oc,$attrs['objectClass'])){
1106             $attrs['objectClass'][] = $oc;
1107           }
1108         }
1109       }
1110  
1111       if($entry['STATUS'] == "LOADED"){
1112         continue;
1113       }
1114       if($entry['STATUS'] == "REMOVED"){
1115         if(isset($entry['DN'])){
1116           $Actions['Remove'][$entry['DN']] = $entry['DN'];
1117         }else{
1118           $Actions['Remove'][$cur_dn] = $cur_dn;
1119         }
1120       }
1121       if($entry['STATUS'] == "EDITED"){
1122         $Actions['Edit'][$cur_dn] = $attrs;
1123       }
1124       if($entry['STATUS'] == "ADDED"){
1125         $Actions['Add'][$cur_dn] = $attrs;
1126       }
1127     }
1129     $ldap = $this->config->get_ldap_link();
1130     $ldap->cd($this->config->current['BASE']);
1131     foreach($Actions['Remove'] as $dn){
1132       $ldap->cd($dn);
1133       $ldap->cat($dn);
1134       if($ldap->count()){
1135         $ldap->rmdir_recursive($dn);
1136         if (!$ldap->success()){
1137           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1138         }
1139       }
1140     }
1141     foreach($Actions['Add'] as $dn => $data){
1142       $ldap->cd($dn);
1143       $ldap->cat($dn);
1144       if(!$ldap->count()){
1145         $ldap->add($data);
1146         if (!$ldap->success()){
1147           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1148         }
1149       }
1150     }
1151     foreach($Actions['Edit'] as $dn => $data){
1152       $ldap->cd($dn);
1153       $ldap->cat($dn);
1154       if($ldap->count()){
1155         $ldap->modify($data);
1156         if (!$ldap->success()){
1157           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1158         }
1159       }
1160     }
1162     $this->_load_menu_structure();
1163   }
1166   /* Return plugin informations for acl handling  */ 
1167   static function plInfo()
1168   {
1169     return (array(
1170           "plShortName"   => _("Applications"),
1171           "plDescription" => _("Group applications"),
1172           "plSelfModify"  => FALSE,
1173           "plDepends"     => array(),
1174           "plPriority"    => 0,
1175           "plSection"     => array("admin"),
1176           "plCategory"    => array("groups"),
1177           "plProvidedAcls"=> array(
1178             "gosaMemberApplication"     => _("Application"),
1179             "FAIrelease"                => _("Release"),
1180             "gosaApplicationParameter"  => _("Application parameter"))
1181           ));
1182   }
1185   function PrepareForCopyPaste($source)
1186   {
1187   }
1190   function multiple_save_object()
1191   {
1192     if(isset($_POST['group_apps_multi'])){
1193       $this->save_object(); 
1194       plugin::multiple_save_object();    
1195   
1196       /* Get posts */
1197       foreach(array("apps") as $attr){
1198         if(isset($_POST['use_'.$attr])) {
1199           $this->multi_boxes[] = $attr;
1200         }
1201       }
1202     }
1203   }
1204   
1206   function get_multi_edit_values()
1207   {
1208     $ret = plugin::get_multi_edit_values();
1210     if(in_array("apps",$this->multi_boxes)){
1211       $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1212       $ret['Categories']               = $this->Categories;
1213       $ret['gosaMemberApplication']    = $this->gosaMemberApplication;
1214       $ret['FAIrelease']               = $this->FAIrelease;
1215       $ret['appoption']                = $this->appoption;
1216     }
1217     return($ret);
1218   }
1220 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1221 ?>