Code

Fixed copy & paste for group - apps
[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/lists/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     $message = plugin::check();
537     return($message);
538   }
541   /*! \brief Create missing releases, if there is a release selected \
542               that is currently not part of the menu structure \
543               then create this entry
544    */
545   function _check_missing_release($release)
546   {
547     $release_info = $this->Releases[$release];
549     $parent_id = $this->a_Structure[0]['UNIQID'];
550     $cur = &$this->a_Structure[0]['ENTRIES'];
551     for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
552       $part = $release_info['parts'][$i];
553       $found = FALSE;
554       foreach($cur as $key => $name){
555         if($name['NAME'] == $part){
556           $parent_id = $cur[$key]['UNIQID'];
557           $cur = &$cur[$key]['ENTRIES'];
558           
559           $found =TRUE;
560           break;
561         }
562       }
563       if(!$found){
564         $release           =  array();
565         $release['UNIQID'] = uniqid();
566         $release['PARENT'] = $parent_id;
567         $release['NAME']   = $part;
568         $release['TYPE']   = "RELEASE";
569         $release['ENTRIES']= array();
570         $release['STATUS']   = "ADDED";
571         $release['FAIstate'] =  $release_info['FAIstate'];
572         $cur[] = $release;
573         $i --;
574       }
575     }
576   }
580   function _move_entry($id,$dir)
581   {
582     $all   = $this->_get_all_entries();
583     if($dir == "down"){
584       $to = $this->_get_next($id);
585     } 
586     if($dir == "up"){
587       $to = $this->_get_last($id);
588     }
590     if(!$to){
591       return;
592     }
594     $o_to   = $all[$to];
595     $o_from = $all[$id];
597     if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
598       $to    = $this->_get_next($to,$o_from['PARENT']); 
599       $o_to  = $all[$to]; 
600     }
601  
602  
603     /* Target is ENTRY && same BASE, just switch */
604     if($o_to['PARENT'] == $o_from['PARENT'] ){
605       $parent = $all[$o_to['PARENT']];
606       $pos = 0;
607       foreach($parent['ENTRIES'] as $entry){
608         $pos ++;
609         if($entry['UNIQID'] == $to){
610           break;
611         }
612       }
613       if($dir == "up" && $pos > 0){
614         $pos --;
615       }
616       $this->_add_entry($parent['UNIQID'],$o_from,$pos);
617       $this->_remove_entry_id($id);
618       return(TRUE);
619     }
620     return(FALSE);
621   }
624  
625   function _get_last($id)
626   {
627     $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
628     for($i = 0 ; $i < count($all_l) ; $i ++){
629       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
630         $i++;
631         break;
632       }
633     }
634     while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
635       $i++;
636     }
638     if(!isset($all_l[$i])){
639       return(FALSE);
640     }
642     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
643       return($all_l[$i]['PARENT']);
644     }     
646     return($all_l[$i]['UNIQID']);
647   }
649  
650   function _get_next($id,$parent = 0)
651   {
652     $all_l = $this->_get_entries_for_release($this->FAIrelease);
653     for($i = 0 ; $i < count($all_l) ; $i ++){
654       if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
655         $i++;
656         break;
657       }
658     }
659     if($parent != 0){
660       while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
661         $i++;
662       }
663     }else{
664       while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
665         $i++;
666       }
667     }
668     if(!isset($all_l[$i])){
669       return(FALSE);
670     }
671     if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
672       return($all_l[$i]['PARENT']);
673     }
674     return($all_l[$i]['UNIQID']);
675   }
680   /* !\brief Handle ui POSTS, like sort up/down/delete
681    */ 
682   function save_object()
683   {
684     foreach($_POST as $name => $value){
685       if(preg_match("/del_/",$name)){
686         $id = preg_replace("/^del_/","",$name);
687         $id = preg_replace("/_(x|y)$/","",$id);
688         $this->_remove_entry_id($id);
689         break;
690       }
691       if(preg_match("/app_entry_edit/",$name)){
692         $id = preg_replace("/^app_entry_edit/","",$name);
693         $id = preg_replace("/_(x|y)$/","",$id);
694         $this->_edit_entry_edit($id);
695         break;
696       }
697       if(preg_match("/up_/",$name)){
698         $id = preg_replace("/^up_/","",$name);
699         $id = preg_replace("/_(x|y)$/","",$id);
700         $this->_move_entry($id,"up");
701         break;
702       }
703       if(preg_match("/down_/",$name)){
704         $id = preg_replace("/^down_/","",$name);
705         $id = preg_replace("/_(x|y)$/","",$id);
706         $this->_move_entry($id,"down");
707         break;
708       }
709       if(preg_match("/^parameter_/",$name) && 
710         count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
711         $name = preg_replace("/^parameter_/","",$name);
712         $this->app_parameter[$name] = $value;
713       }
714     }
715     if(isset($_POST['FAIrelease'])){
716       $this->FAIrelease = $_POST['FAIrelease'];
717       $this->_check_missing_release($this->FAIrelease);
718     }
719     if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
720       $this->curbase = base64_decode($_GET['depid']);
721     }
722     if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
723       $folder = $_POST['folder'];
724       foreach($_POST as $name => $value){
725         if(preg_match("/^AddApp_[0-9]*$/",$name)){
726           $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));   
727         }
728       }
729     }
731     /* Add seperator */
732     if(isset($_POST['add_seperator']) && isset($_POST['menu_folder'])){
733       $folder = $_POST['menu_folder'];
734       $this->_add_seperator($folder);
735     }
737     if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
738       $folder = $_POST['menu_folder'];
739       $name = $_POST['menu_folder_name'];
740       if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
741         $this->_add_sub_folder($folder,$name);
742       }
743     }
744     if(isset($_POST['app_entry_save'])){ 
745       $this->_save_entry_edit();
746     }
748     if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
749       if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
750         $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
751       }
752     }
754     if(isset($_POST['edit_reset_image'])){
755       $this->edit_entry['ICON'] = "";
756     }
758     if(isset($_POST['app_entry_cancel'])){
759       $this->edit_entry = array();
760       $this->dialog = FALSE;
761     }
762     $this->reload();
763   }
765  
766   /*! \brief Returns the UNIQID of the currently selected release 
767    */ 
768   function _get_release_key($release,$add_if_missing = FALSE)
769   {
770     $release_info = $this->Releases[$release];
772     if($release_info['name'] == "/"){
773       return($this->a_Structure['0']['UNIQID']);
774     }
776     $cur = &$this->a_Structure[0]['ENTRIES'];
777     $s_key = "";
778     $found = FALSE;
779     foreach($release_info['parts'] as $name){
780       foreach($cur as $key => $obj){
781         if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
782           $s_key = $cur[$key]['UNIQID'];
783           $cur = &$cur[$key]['ENTRIES'];
784           $found = TRUE;
785           break;
786         }
787         $found = FALSE;
788       }
789     }
790     if($found){
791       return($s_key);  
792     }  
793     return(FALSE);
794   }
796  
797   /*! \brief Add a new folder folder to the specified folder id
798       @param  String $folder The folder id in where we want to add the new folder.
799       @param  String $name   The name of the new folder.
800    */ 
801   function _add_sub_folder($folder,$name)
802   {
803     $all = $this->_get_all_entries();
804     if($folder == "BASE"){
805       $folder = $this->_get_release_key($this->FAIrelease,TRUE);
806     }
807     
808     if(isset($all[$folder])){
809       $a_folder = array();
810       $a_folder['STATUS'] = "ADDED";
811       $a_folder['NAME']   = $name;
812       $a_folder['UNIQID'] = uniqid();
813       $a_folder['ENTRIES']= array();
814       $a_folder['PARENT'] = $folder;      
815       $a_folder['TYPE']   = "FOLDER";
816       $a_folder['ICON']   = "";
817       $all[$folder]['ENTRIES'][] = $a_folder;
818     }
819   }
822   /* !\brief Remove the given id from the menu structure.
823       @param  String  ID to of the entry we want to remove.
824       @return Boolean TRUE on success
825    */
826   function _remove_entry_id($id)
827   {
828     $all = $this->_get_all_entries();
829     if(isset($all[$id])){
830       $all[$id]['STATUS'] = "REMOVED";
831       $all[$id]['ENTRIES'] = array();
832       return(TRUE);
833     }
834     return(FALSE);
835   }
837   
838   /* !\brief Remove the given id from the menu structure.
839       @param  String  ID to of the entry we want to remove.
840       @return Boolean TRUE on success
841    */
842   function _add_entry($folder_id,$entry,$pos = 0)
843   {
844     $all = $this->_get_all_entries();
846     /* Do not add removed */
847     if($entry['STATUS'] == "REMOVED"){
848       return;
849     }
851     if(isset($all[$folder_id])){
853       if(!isset($entry['ENTRIES'])){
854         $entries = array();
855       }else{
856         $entries = $entry['ENTRIES'];
857       }
859       $folder  = &$all[$folder_id];
861       $entry['UNIQID'] = uniqid();     
862       $entry['PARENT'] = $folder_id;
863       $entry['ENTRIES']= array();
864       $entry['STATUS'] = "ADDED";
865       
866       $cnt = 0; 
867       $new = array();
868       $added =FALSE;
869       foreach($folder['ENTRIES'] as $key => $obj){
870         if($obj['STATUS'] == "LOADED"){
871           $obj['STATUS'] = "EDITED";
872         }
873         if($pos == $cnt){
874           $new[] = $entry;
875           $added = TRUE;
876         }
877         $cnt ++;
878         $new[] = $obj;
879       }
880       if(!$added){
881         $new[] = $entry;
882       }
883   
884       $all[$folder_id]['ENTRIES'] = $new;
885       foreach($entries as $sub){
886         $this->_add_entry($entry['UNIQID'],$sub,-1);
887       }
888       return(TRUE);
889     }
890     return(FALSE);
891   }
893  
894   /*! \brief Add the application identified by $app_id to folder $folder_id 
895       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
896       @param  Integer app_id    The ID of the application which should be added.
897    */ 
898   function _add_app_id($folder_id,$app_id)
899   {
900     $all = $this->_get_all_entries();
901     if($folder_id == "BASE"){
902       $folder_id = $this->_get_release_key($this->FAIrelease);
903     }
904     if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
906       $new = array();
907       $new['TYPE']  = "ENTRY";
908       $new['NAME']  = $this->apps[$app_id]['cn'][0];
909       $new['UNIQID']= uniqid(); 
910       $new['PARENT']= $folder_id;
911       $new['PARAMETER']= array();
912       if(isset($this->apps[$app_id]['description'][0])){
913         $new['INFO']  = $this->apps[$app_id]['description'][0];
914       }else{
915         $new['INFO']  = "";
916       }
917       $new['STATUS']= "ADDED";
918       $all[$folder_id]['ENTRIES'][] = $new;
919     }
920   }
923   /*! \brief Add the application identified by $app_id to folder $folder_id 
924       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
925       @param  Integer app_id    The ID of the application which should be added.
926    */ 
927   function _add_seperator($folder_id)
928   {
929     $all = $this->_get_all_entries();
930     if($folder_id == "BASE"){
931       $folder_id = $this->_get_release_key($this->FAIrelease);
932     }
934     if(isset($all[$folder_id])){
935       $new = array();
936       $new['TYPE']  = "SEPERATOR";
937       $new['NAME']  = "SEPERATOR";
938       $new['UNIQID']= uniqid(); 
939       $new['PARENT']= $folder_id;
940       $new['PARAMETER']= array();
941       $new['STATUS']= "ADDED";
942       $all[$folder_id]['ENTRIES'][] = $new;
943     }
944   }
947   /*! \brief  Return all entries linear. 
948       @param  Boolean   $add_tags  If TRUE, OPEN/CLOSE Tags will be appended.
949       @param  &Array    Start here, Pointer to an array.
950    */ 
951   function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, &$cur = NULL)
952   {
953     $ret = array();
954     if($cur == NULL){
955       $cur = &$this->a_Structure;
956     }
957     foreach($cur as $key => $entry){
959       if($skip_release && $entry['TYPE'] == "RELEASE"){
960         continue;
961       }    
962       if($entry['TYPE'] == "ENTRY"){
963         $found = FALSE;
964         foreach($this->apps as $app){
965           if($app['cn'][0] == $entry['NAME']){
966             $found = TRUE;
967             if(isset($app['description'][0])){
968               $entry['INFO'] = "[".$app['description'][0]."]";
969             }
970             break;
971           }
972         } 
973         if(!$found){
974           $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
975         }
976       }
977       
979       $tmp = $entry;
980       if(!$add_tags){
981         $ret[$tmp['UNIQID']] = &$cur[$key];
982         if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
983           $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
984         }
985       }else{
986       
987         if(isset($tmp['ENTRIES'])){
988           unset($tmp['ENTRIES']);
989         }
990         if($tmp['STATUS'] != "REMOVED"){
991           $ret[] = $tmp;
992           if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
993             $add = false;
994             foreach($entry['ENTRIES'] as $entry){
995               if($entry['STATUS'] != "REMOVED"){
996                 $add = TRUE;
997                 break;
998               }
999             }
1001             if($add){
1002               $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
1003               $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1004               $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
1005             }
1006           }
1007         }
1008       }
1009     }
1010     return($ret);
1011   }
1014   function save()
1015   {
1016     $ldap = $this->config->get_ldap_link();
1017     $all = $this->_get_all_entries();
1018     $prio = 0;
1019     $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
1021     $sep_id = 0;
1022     foreach($all as $entry){
1023       $prio ++;
1024       $cur = $entry;
1025       $dn = "";
1027       do{  
1028         if($cur['TYPE'] == "SEPERATOR"){
1029           $sep_id ++;
1030           $dn.= "cn=seperator_".$sep_id.",";
1031         }elseif($cur['TYPE'] == "ENTRY"){
1032           $dn.= "cn=".$cur['NAME'].",";
1033         }elseif($cur['TYPE'] == "FOLDER"){
1034           $dn.= "cn=".$cur['NAME'].",";
1035         }elseif($cur['TYPE'] == "RELEASE"){
1036           $dn.= "ou=".$cur['NAME'].",";
1037         }elseif($cur['TYPE'] == "BASE"){
1038         }
1039         if(!isset($all[$cur['PARENT']])){
1040           $cur = NULL;
1041         }else{
1042           $cur = $all[$cur['PARENT']];
1043         }
1044       }while(is_array($cur));
1046       $cur_dn = $dn.$this->dn;
1048       $attrs = array();
1050       switch($entry['TYPE']){
1051         case "SEPERATOR"    :
1052         { 
1053           $attrs['objectClass'] = array("gotoMenuEntry");
1054           $attrs['cn']          = "seperator_".$sep_id;
1055           $attrs['gosaApplicationPriority'] = $prio;
1056           $attrs['gosaApplicationParameter'] = "*separator*";
1057         }
1058         break;
1059         case "ENTRY"    :
1060         { 
1061           $attrs['objectClass'] = array("gotoMenuEntry");
1062           $attrs['cn']          = $entry['NAME'];
1063           $attrs['gosaApplicationPriority'] = $prio;
1064           $attrs['gosaApplicationParameter'] = array(); 
1065           
1066           
1067           foreach($entry['PARAMETER'] as $name => $value){
1068             $attrs['gosaApplicationParameter'][] = $name.":".$value; 
1069           }
1070           if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1071             unset($attrs['gosaApplicationParameter']);
1072           } 
1073         }
1074         break;
1075         case "FOLDER"   : 
1076         { 
1077           $attrs['objectClass'] = array("gotoSubmenuEntry");
1078           $attrs['cn']          = $entry['NAME'];
1079           $attrs['gosaApplicationPriority'] = $prio;
1080           if($entry['STATUS'] != "ADDED"){
1081             $attrs['gosaApplicationIcon'] = array();
1082           }
1083           
1084           if(!empty($entry['ICON'])){
1085             $attrs['gosaApplicationIcon']     = $entry['ICON'];
1086           }
1087         }
1088         break;
1089         case "RELEASE"  : 
1090         {
1091           $attrs['ou']            = $entry['NAME'];
1092           $attrs['objectClass']   = array();
1093           $attrs['objectClass'][] = "top";
1094           $attrs['objectClass'][] = "organizationalUnit";
1095           $attrs['objectClass'][] = "FAIbranch";
1096           if(!empty($entry['FAIstate'])){
1097             $attrs['FAIstate']      = $entry['FAIstate'];
1098           }
1099         }
1100         break;
1101       }
1102  
1103       /* Append missing ObjectClasses,  ...  Tagging */
1104       if(isset($entry['LDAP_ATTRS'])){
1105         for($i = 0 ; $i < $entry['LDAP_ATTRS']['objectClass']['count']; $i ++){
1106           $oc = $entry['LDAP_ATTRS']['objectClass'][$i];
1107           if(!in_array($oc,$attrs['objectClass'])){
1108             $attrs['objectClass'][] = $oc;
1109           }
1110         }
1111       }
1113  
1114       if($entry['STATUS'] == "LOADED"){
1115         continue;
1116       }
1117       if($entry['STATUS'] == "REMOVED"){
1118         if(isset($entry['DN'])){
1119           $Actions['Remove'][$entry['DN']] = $entry['DN'];
1120         }else{
1121           $Actions['Remove'][$cur_dn] = $cur_dn;
1122         }
1123       }
1124       if($entry['STATUS'] == "EDITED"){
1125         $Actions['Edit'][$cur_dn] = $attrs;
1126       }
1127       if($entry['STATUS'] == "ADDED"){
1128         $Actions['Add'][$cur_dn] = $attrs;
1129       }
1130     }
1132     print_a($Actions);
1134     $ldap = $this->config->get_ldap_link();
1135     $ldap->cd($this->config->current['BASE']);
1136     foreach($Actions['Remove'] as $dn){
1137       $ldap->cd($dn);
1138       $ldap->cat($dn);
1139       if($ldap->count()){
1140         $ldap->rmdir_recursive($dn);
1141         if (!$ldap->success()){
1142           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1143         }
1144       }
1145     }
1146     foreach($Actions['Add'] as $dn => $data){
1147       $ldap->cd($dn);
1148       $ldap->cat($dn);
1149       if(!$ldap->count()){
1150         $ldap->add($data);
1151         if (!$ldap->success()){
1152           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1153         }
1154       }
1155     }
1156     foreach($Actions['Edit'] as $dn => $data){
1157       $ldap->cd($dn);
1158       $ldap->cat($dn);
1159       if($ldap->count()){
1160         $ldap->modify($data);
1161         if (!$ldap->success()){
1162           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1163         }
1164       }
1165     }
1167     $this->_load_menu_structure();
1168   }
1171   /* Return plugin informations for acl handling  */ 
1172   static function plInfo()
1173   {
1174     return (array(
1175           "plShortName"   => _("Applications"),
1176           "plDescription" => _("Group applications"),
1177           "plSelfModify"  => FALSE,
1178           "plDepends"     => array(),
1179           "plPriority"    => 0,
1180           "plSection"     => array("admin"),
1181           "plCategory"    => array("groups"),
1182           "plProvidedAcls"=> array(
1183             "gosaMemberApplication"     => _("Application"),
1184             "FAIrelease"                => _("Release"),
1185             "gosaApplicationParameter"  => _("Application parameter"))
1186           ));
1187   }
1190   function PrepareForCopyPaste($source)
1191   {
1192     plugin::PrepareForCopyPaste($source);
1193    
1194     $tmp = new appgroup($this->config,$source['dn']);
1195     $this->is_account = TRUE;
1196     $this->a_Structure = $tmp->a_Structure;
1197     $all = $this->_get_all_entries();
1198     foreach($all as &$entry){
1199       if(isset($entry['STATUS'])){
1200         $entry['STATUS'] = "ADDED";
1201       }
1202     }
1203   }
1206   function multiple_save_object()
1207   {
1208     if(isset($_POST['group_apps_multi'])){
1209       $this->save_object(); 
1210       plugin::multiple_save_object();    
1211   
1212       /* Get posts */
1213       foreach(array("apps") as $attr){
1214         if(isset($_POST['use_'.$attr])) {
1215           $this->multi_boxes[] = $attr;
1216         }
1217       }
1218     }
1219   }
1220   
1222   function get_multi_edit_values()
1223   {
1224     $ret = plugin::get_multi_edit_values();
1226     if(in_array("apps",$this->multi_boxes)){
1227       $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1228       $ret['Categories']               = $this->Categories;
1229       $ret['gosaMemberApplication']    = $this->gosaMemberApplication;
1230       $ret['FAIrelease']               = $this->FAIrelease;
1231       $ret['appoption']                = $this->appoption;
1232     }
1233     return($ret);
1234   }
1236 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1237 ?>