Code

14d4d775766cb189e261da7637641e7795ab3a08
[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;
20     var $copied_release = ""; 
23     public function __construct(&$config, $dn= NULL, $parent= NULL)
24     {
25         plugin::plugin($config,$dn,$parent);
26         $this->dn = $dn; 
27         $this->_load_menu_structure();
28         $this->a_Structure_on_load = $this->a_Structure;
30         /* Check if we have relase mangement enabled and prepare group application for release management */
31         $this->enableReleaseManagement  = $this->config->pluginEnabled("faiManagement");
32         $this->Releases   = $this->getReleases();
34         /* Set intial release */
35         $this->FAIrelease = $config->get_cfg_value("faiManagement","defaultFaiRelease");
36         if(empty($this->FAIrelease) || !isset($this->Releases[$this->FAIrelease])){
37             $this->FAIrelease = "/";
38         }
40         $this->curbase    = $this->config->current['BASE'];
41         $this->reload();
43         /* If we have at least one assigned application-
44            Enable this account.
45          */ 
46         $this->is_account = FALSE;
47         if(count($this->_get_all_entries()) > 1){
48             $this->is_account= TRUE;
49         }   
50         $this->initially_was_account = $this->is_account;
52         // Prepare lists
53         $this->applicationList = new sortableListing();
54         $this->applicationList->setDeleteable(false);
55         $this->applicationList->setEditable(true);
56         $this->applicationList->setWidth("100%");
57         $this->applicationList->setHeight("300px");
58         $this->applicationList->setColspecs(array('20px','20px','*'));
59         $this->applicationList->setHeader(array("&nbsp;","&nbsp;",_("Application")));
60         $this->applicationList->setDefaultSortColumn(2);
61         $this->applicationList->setAcl('rwcdm'); // All ACLs, we filter on our own here.
63     }
66     /*! \brief Reload the list of applications for the currently selected release.
67       If necessary, maybe the list is already cached.
68      */
69     function reload()
70     {
71         $ret = array();
72         $release_info = $this->Releases[$this->FAIrelease];
74         /* Check if the available application were already been fetched.
75            If not, build up a list of available applications.
76          */  
77         if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
79             /* First of all, get all application departments to search in.
80              */  
81             $ldap = $this->config->get_ldap_link();
82             $ldap->cd($this->config->current['BASE']);
83             $ldap->search("ou=apps",array("dn"));
84             $app_deps = array();
85             while($attrs = $ldap->fetch()){
86                 $app_deps[] = $attrs['dn'];
87             }
89             /* Search all release departments for the above fetched application departments
90              */
91             foreach($app_deps as $dep){
92                 $ldap->cd($dep);
93                 $ldap->search("objectClass=FAIbranch",array("dn"));
94                 while($attrs = $ldap->fetch()){
95                     $app_deps[] = $attrs['dn'];
96                 }
97             }
99             /* Filter out those releases that match the currently selected release, 
100                and fetch all applications from those departments.
101              */
102             foreach($app_deps as $dep){
103                 if(preg_match("/^".preg_quote($release_info['suffix'], '/')."/",$dep)){
104                     $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
105                 }
106             }
108             /* Create a new array containing all fetch apps for the currently selected release,
109                sort it and store results in cache. 
110              */ 
111             $tmp = array();
112             foreach($ret as $key => $app){
113                 $tmp[$key] = $app['cn'][0];
114             }
115             natcasesort($tmp);
116             $res = array();
117             foreach($tmp as $key => $app){
118                 $res[] = $ret[$key];
119             }
121             $this->_cache['ReleaseApps'][$release_info['suffix']] = $res;
122         } 
123         $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
124     }
128     /*! \brief generate a list of available releases
129       @return return an array with all available releases.
131       e.g.
133       /     "name"    /
134       "found"   1
135       "parts"   Array (empty)
136       "suffix"  ou=apps,
138       halut "name"    halut
139       "found"   1
140       "FAIstate"  
141       "dn"      ou=halut,ou=apps,ou=Direktorium,o=Landeshauptstadt München,c=de
142       "parts"   0 halut
143       "suffix"  ou=halut,ou=apps,
145       This will be used as base for the application menu structure.
146       If there is a menu assigned for a release, this menu will be 
147       appended with the index 'ENTRIES';
148      */
149     function getReleases()
150     {
151         $ret =array("/" => array("name" => "/", "found" => TRUE , "parts" => array(),"suffix" => get_ou("application", "applicationRDN")));
152         if($this->enableReleaseManagement){
154             /* Only display those releases that we are able to read 
155              */
156             $dn     = get_ou("application", "applicationRDN").$this->config->current['BASE'];
157             $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
158             $res    = get_sub_list($filter,array("application","fai"), 
159                     array(get_ou("application", "applicationRDN"),get_ou("faiManagement", "faiBaseRDN")),$dn, array("ou","FAIstate"), GL_SUBSEARCH);
161             /* Go through all departments and check which department is a valid 
162                department release.
163              */
164             foreach($res as $attrs){
165                 if(preg_match("/".get_ou("application", "applicationRDN")."/i",$attrs['dn'])){
167                     /* Parse all returned departments dns into a useable type.
168                        (ou=1.0.0,ou=halut,ou=apps  ==> halue/1.0.0)
169                      */
170                     $bb     = preg_replace("/".preg_quote(get_ou("application", "applicationRDN"), '/').".*/i","",$attrs['dn']);
171                     $parts  = array_reverse(explode("ou=",$bb));
173                     $str ="";
174                     foreach($parts as $key => $part){
175                         if(empty($part)) {
176                             unset($parts[$key]);
177                             continue;
178                         }
179                         $part = str_replace(",","",$part);
180                         $str .= $part."/";
181                         $parts[$key] = $part;
182                     }
183                     $name = preg_replace("/\/$/","",$str);
184                     if(empty($name)) {
185                         $name ="/";
186                     }
188                     $FAIstate = "";
189                     if(isset($attrs['FAIstate'])){
190                         $FAIstate = $attrs['FAIstate'][0];
191                     }
193                     /* Check if this department has a menu structure assigned 
194                      */
195                     $all = $this->_get_all_entries();
196                     $found = FALSE;
197                     foreach($all as $entry){
198                         if(isset($entry['DN']) && preg_match("/^".preg_quote($bb, '/')."/",$entry['DN'])){
199                             $found =TRUE;
200                             break;
201                         }
202                     }
204                     $ret[$name] = array("name"     => $name, 
205                             "found"    => $found,
206                             "FAIstate" => $FAIstate,
207                             "dn"       => $attrs['dn'], 
208                             "parts"    => $parts,"suffix" => $bb.get_ou("application", "applicationRDN"));
209                 }
210             }
211         }
212         ksort($ret);
213         return($ret);
214     }
217     /*! \brief Load the menu structure from ldap and create a multi dimensional array.
219       This will create a multidimensional array.
220       e.g.:
222       $this->a_Structure =
224       [0]['TYPE']   = "BASE"
225       [0]['ENTRIES']  [0]['TYPE']   = "RELEASE"
226       [0]['NAME']   = "halut"
227       [0]['ENTRIES']= array()
228       ...
229       [0]['ENTRIES']  [1]['TYPE']   = "RELEASE"
230       [1]['NAME']   = "halut/1.0.0"
231       [1]['ENTRIES']  [0]['TYPE']   = "TYPE"
232       [0]['NAME']   = "Programme"
233       [0]['ENTRIES'][0]['TYPE'] = "ENTRY"
234       [0]['NAME'] = "konqueror"
235       [1]['TYPE'] = "ENTRY"
236       [1]['NAME'] = "firefox"
237      */
238     function _load_menu_structure()
239     {
240         /* Create the base object
241          */
242         $base =  array();
243         $base['UNIQID'] = uniqid();
244         $base['PARENT'] = 0; 
245         $base['NAME']   = "";
246         $base['TYPE']   = "BASE";
247         $base['ENTRIES']= array();
248         $base['STATUS'] = "LOADED";
250         $this->a_Structure  = array();
251         $this->a_Structure[0] = $base;
253         /* Search for all Releases/Menu Folders and Menu Entries,
254            to append them to our structure array.
255          */
256         $ldap = $this->config->get_ldap_link();
257         $ldap->cd($this->dn);
258         $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
259         while($attrs = $ldap->fetch()){
261             /* Find the correct position where to add this entry.
262                e.g. If we have cn=firefox,cn=Programme,ou=halut...
264                1. get a pointer to the halut array ($this->a_Structure['0'][ENTRIES''][]['halut'])
265                2. then get a pointer to the halut['ENTRIES'][]['Programme'] array. 
266                3. append 'firefox' to the 'ENTRIES' of our "Programme" pointer.
267              */
268             $cur          = &$this->a_Structure[0]['ENTRIES'];
269             $parent_id    = $base['UNIQID'];
270             $sub_dn       = preg_replace("/,".preg_quote($this->dn, '/')."$/","",$attrs['dn']);
271             $sub_dn_array = explode(",",$sub_dn);
273             /* Walk through our menu structure array while we have found 
274                the correct position where to add this object. 
275              */
276             $found = true;
277             for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
278                 $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
280                 /* We haven't found the end node where this object has to be added
281                  */
282                 if($i > 0){
283                     $found =FALSE;
284                     foreach($cur as $key => $entry){
285                         if($entry['NAME'] == $name){
286                             $cur = &$cur[$key]['ENTRIES'];
287                             $parent_id = $entry['UNIQID'];
288                             $found =true;
289                             break;
290                         }
291                     }
292                 }else{
294                     if(!$found){
295                         break;
296                     }
298                     /* Get application priority.
299                        And ensure that each priority exists once.
300                      */
301                     $priority = 1;
302                     if(isset($attrs['gosaApplicationPriority'])){
303                         $priority= $attrs['gosaApplicationPriority'][0];
304                     }
305                     while(isset($cur[$priority])){
306                         $priority ++;
307                     }
309                     /* Create the data object that should be added 
310                      * Folder
311                      * Entry
312                      * Release
313                      */
314                     $data = array();
316                     /* Add a menu folder 
317                      */
318                     if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
319                         $type = "FOLDER";
321                         $data['ICON'] = "";
322                         if(isset($attrs['gosaApplicationIcon'])){
323                             $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
324                         }
326                         /* Add a menu entry 
327                          */
328                     }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
330                         $type = "ENTRY";
331                         $data['INFO'] = "";
332                         $data['PARAMETER'] = array();
333                         if(isset($attrs['gosaApplicationParameter'])){
334                             for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
335                                 if(preg_match("/:/",$attrs['gosaApplicationParameter'][$p])){
336                                     $tmp = explode(":",$attrs['gosaApplicationParameter'][$p]);
337                                     $data['PARAMETER'][$tmp[0]] = preg_replace('/^[^:]+:/', '', $attrs['gosaApplicationParameter'][$p]);
338                                 }elseif($attrs['gosaApplicationParameter'][$p] == "*separator*"){
339                                     $type = "SEPERATOR";
340                                     $data['PARAMETER'] = array();
341                                     break;
342                                 }
343                             }
344                         }
346                         /* Add a release
347                          */
348                     }elseif(in_array("FAIbranch",$attrs['objectClass'])){
349                         $type = "RELEASE";
350                         if(isset($attrs['FAIstate'][0])){
351                             $data['FAIstate'] = $attrs['FAIstate'][0];
352                         }else{
353                             $data['FAIstate'] = "";
354                         }
355                     }
357                     /* Create object and append it to the current structure pointer 
358                      */
359                     $data['LDAP_ATTRS'] = $attrs;
360                     $data['DN']       = $attrs['dn'];
361                     $data['NAME']     = $name;
362                     $data['TYPE']     = $type;
363                     $data['PRIORITY'] = $priority;
364                     $data['ENTRIES']  = array();
365                     $data['UNIQID']   = uniqid();
366                     $data['PARENT']   = $parent_id;
367                     $data['STATUS']   = "LOADED";
368                     $cur[$priority]   = $data;
369                     ksort($cur);
370                 }
371             }
372         }
373     } 
376     function execute()
377     {
378         /* Call parent execute */
379         plugin::execute();
381         if(isset($_GET['r'])) $this->__construct($this->config,$this->dn);
383         if (isset($_POST['modify_state'])){
384             $this->is_account = !$this->is_account;
385         }
387         /* Do we represent a valid account? */
388         if (!$this->is_account){
389             $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Menu")), msgPool::featuresDisabled(_("Menu")));
390             return ($display);
391         }
393         $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Menu")), msgPool::featuresEnabled(_("Menu")));
395         if(isset($_GET['send'])){
396             $id = $_GET['send'];
397             $all = $this->_get_all_entries();
398             if(isset($all[$id])){
399                 send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
400                 exit;
401             }
402         }
404         if(isset($_GET['r']))
405             $this->__construct($this->config,$this->dn);
407         if(count($this->edit_entry)){
408             if($this->edit_entry['TYPE'] == "ENTRY"){
409                 $smarty = get_smarty();
410                 $smarty->assign("type", "ENTRY");
411                 $smarty->assign("entry",$this->edit_entry);
412                 $smarty->assign("paras", set_post($this->app_parameter));
413                 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
414                 return($display);
415             }
416             if($this->edit_entry['TYPE'] == "FOLDER"){
417                 $smarty = get_smarty();
419                 session::set("binarytype" , "image/jpeg");
420                 session::set("binary" , $this->edit_entry['ICON']);
422                 $smarty->assign("rand", microtime(TRUE));
423                 $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0); 
424                 $smarty->assign("type", "FOLDER");
425                 $smarty->assign("entry",$this->edit_entry);
426                 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
427                 return($display);
428             }
429         }
431         $smarty = get_smarty();
432         $smarty->assign("plug_id" , $_GET['plug']);
434         /* Create application list */
435         $departments = array();
436         if(!$this->enableReleaseManagement){
437             $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
438             foreach($res as $value){
439                 $fdn = $value['dn'];
440                 $fdn = preg_replace("/".preg_quote($this->curbase, '/')."/","",$fdn);
441                 $fdn= LDAP::fix($fdn);
442                 if($value["description"][0]!=".."){
443                     $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
444                 }else{
445                     $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
446                 }
447             }
448         }
450         /* Create base back entry */
451         $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
452         if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
453             $departments[$base_back]=".. ["._("back")."]";
454         }
456         // Append departments for current base 
457         $data = $lData = array();
458         foreach($departments as $key => $app){
459             $img = image('images/lists/folder.png');
460             $data[$key] = array('TYPE'=>'DEP','ID'=> $app);
461             $lData[$key] = array('data' => array($img,"&nbsp;",$app));
463         }
465         // Add applications found on this base 
466         $used_apps = $this->_get_used_entry_name();
467         foreach($this->apps as $key => $app){
468             if(in_array($app['cn'][0],$used_apps)) continue;
469             if(!preg_match("/".get_ou("application", "applicationRDN").preg_quote($this->curbase, '/')."$/",$app['dn'])){
470                 continue;
471             }
473             $name = $app['cn'][0];
474             if(isset($app['description'])){
475                 $name .= "&nbsp;[".$app['description'][0]."]";
476             }
477             $img = image('plugins/goto/images/select_application.png');
478             $chk = "<input class='center' type='checkbox' value='1' name='AddApp_".$key."'>";
479             $data[$key] = array('TYPE'=>'APP','ID'=> $app);
480             $lData[$key] = array('data' => array($img,$chk,$name));
481         }
482         $this->applicationList->setListData($data,$lData);
483         $this->applicationList->update();
485         /* Assign copy / paste values 
486          */
487         if(!empty($this->copied_release)){
488             $smarty->assign("copied", TRUE);
489             $smarty->assign("copy_source", $this->copied_release);
490         }else{
491             $smarty->assign("copied", FALSE);
492         }
493         $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
494         $smarty->assign("FAIrelease", set_post($this->FAIrelease));
495         $smarty->assign("app_list",$this->applicationList->render());
496         $smarty->assign("i",0);
497         $smarty->assign("releases", set_post($this->Releases));
498         $smarty->assign("folders" , set_post($this->_get_folder_names()));
499         $entries = $this->_get_entries_for_release($this->FAIrelease);
500         $smarty->assign("entries", set_post($entries));
501         $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
502         return($display);
503     }
506     /*! \brief Returns all used folder names 
507       @return Array  All used folder names.
508      */ 
509     function _get_folder_names()
510     {
511         $data = $this->_get_entries_for_release($this->FAIrelease);
512         $all    = $this->_get_all_entries();
513         $ret = array("BASE" => ".");
514         foreach($data as $entry){
516             if($entry['TYPE'] == "FOLDER"){
517                 $str = $entry['NAME'];
518                 $parent = $entry['PARENT'];
519                 $i = 10;
520                 while(isset($all[$parent]) && $i){  
521                     $i --;
522                     $parent_o = $all[$parent];
523                     $str      = $parent_o['NAME']."/".$str;
524                     $parent   = $all[$parent_o['UNIQID']]['PARENT'];
525                 }        
526                 $ret[$entry['UNIQID']] = $str;
527             }
528         }
529         return($ret);
530     }
533     /*! \brief return all used applications 
534       @return Array  All used applications.
535      */ 
536     function _get_used_entry_name()
537     {
538         $data = $this->_get_entries_for_release($this->FAIrelease);
539         $ret = array();
540         foreach($data as $entry){
541             if($entry['TYPE'] == "ENTRY"){
542                 $ret[] = $entry['NAME'];
543             }
544         }
545         return($ret);
546     }
549     /*! \brief Returns all folder an entries for the selected release 
550       @return Array  Returns the complete menu structure for the given array.
551      */ 
552     function _get_entries_for_release($release,$cur = NULL)
553     {
554         $all = $this->_get_all_entries();
555         $key = $this->_get_release_key($release);
556         if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
557             $res = $this->_get_all_entries(TRUE,TRUE,$all[$key]['ENTRIES']);
558             return($res);
559         } 
560         return(array());
561     }
564     /*! \brief Save the currently edited entry 
565      */
566     function _save_entry_edit()
567     {
568         $all    = $this->_get_all_entries();
569         $entry  = $this->edit_entry;
570         $r_entry= &$all[$entry['UNIQID']];
573         if($entry['TYPE'] == "ENTRY"){
574             $r_entry['PARAMETER'] = $this->app_parameter;
575             if($r_entry['STATUS'] != "ADDED"){
576                 $r_entry['STATUS'] = "EDITED";
577             } 
578         }
579         if($entry['TYPE'] == "FOLDER"){
580             $r_entry['ICON']   = $this->edit_entry['ICON'];
581             $r_entry['STATUS'] = "EDITED";
582         }
583         $this->dialog = FALSE;
584         $this->edit_entry = array();
585     }
588     /*! \brief prepare the entry with the given ID, to be edited.
589       Read application Parameter from ldap.
590      */
591     function _edit_entry_edit($id)
592     {
593         $all   = $this->_get_all_entries();
594         $entry = $all[$id];
596         $this->app_parameter = array();
597         if($entry['TYPE'] == "ENTRY"){
598             $found = FALSE;
599             foreach($this->apps as $id => $app){
601                 if($app['cn'][0] == $entry['NAME']){
602                     $found = TRUE;
603                     break;
604                 }
605             }
606             if($found){
608                 /* Create a list of editable parameter */
609                 if(isset($app['gosaApplicationParameter'])){
610                     for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
611                         $para = $app['gosaApplicationParameter'][$i];
612                         $tmp  = explode(":",$para);
613                         $this->app_parameter[$tmp[0]] = $tmp[1];
614                     }
615                 }
617                 /* Overwrite parameters with entry parameters */
618                 foreach($entry['PARAMETER'] as $name => $value){
619                     $this->app_parameter[$name] = $value;
620                 }
622                 $this->dialog = TRUE;
623                 $this->edit_entry = $entry;
624             }
625         }
627         if($entry['TYPE'] == "FOLDER"){
628             $this->dialog = TRUE;
629             $this->edit_entry = $entry;
630         }
631     }
634     /*! \brief Removes the menu structure from ldap 
635      */
636     function remove_from_parent()
637     {
638         $ldap = $this->config->get_ldap_link();
639         $ldap->cd($this->dn);
640         $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
641         $a_remove = array();
642         while($attrs = $ldap->fetch()){
643             $a_remove[] = $attrs['dn'];
644         }
645         foreach($a_remove as $remove){
646             $ldap->rmdir_recursive($remove);
647             if (!$ldap->success()){
648                 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
649             }
650         }
651         $this->_load_menu_structure();
652     }
655     function check()
656     {
657         $message = plugin::check();
658         return($message);
659     }
662     /*! \brief Create missing releases, if there is a release selected \
663       that is currently not part of the menu structure \
664       then create this entry
665      */
666     function _check_missing_release($release)
667     {
668         $release_info = $this->Releases[$release];
670         $parent_id = $this->a_Structure[0]['UNIQID'];
671         $cur = &$this->a_Structure[0]['ENTRIES'];
672         for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
673             $part = $release_info['parts'][$i];
674             $found = FALSE;
675             foreach($cur as $key => $name){
676                 if($name['NAME'] == $part){
677                     $parent_id = $cur[$key]['UNIQID'];
678                     $cur = &$cur[$key]['ENTRIES'];
680                     $found =TRUE;
681                     break;
682                 }
683             }
684             if(!$found){
685                 $release           =  array();
686                 $release['UNIQID'] = uniqid();
687                 $release['PARENT'] = $parent_id;
688                 $release['NAME']   = $part;
689                 $release['TYPE']   = "RELEASE";
690                 $release['ENTRIES']= array();
691                 $release['STATUS']   = "ADDED";
692                 $release['FAIstate'] =  $release_info['FAIstate'];
693                 $cur[] = $release;
694                 $i --;
695             }
696         }
697     }
701     /*! \brief Moves a given object ($id) in a specified direction ($dir).
702       @param  String The object ID of the object we want to move
703       @dir    String Move "up" or "down"
704      */
705     function _move_entry($id,$dir)
706     {
707         $all   = $this->_get_all_entries();
708         if($dir == "down"){
709             $to = $this->_get_next($id);
710         } 
711         if($dir == "up"){
712             $to = $this->_get_last($id);
713         }
715         if(!$to){
716             return;
717         }
719         $o_to   = $all[$to];
720         $o_from = $all[$id];
722         if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
723             $to    = $this->_get_next($to,$o_from['PARENT']); 
724             $o_to  = $all[$to]; 
725         }
727         /* Target is ENTRY && same BASE, just switch */
728         if($o_to['PARENT'] == $o_from['PARENT'] ){
729             $parent = $all[$o_to['PARENT']];
730             $pos = 0;
731             foreach($parent['ENTRIES'] as $entry){
732                 $pos ++;
733                 if($entry['UNIQID'] == $to){
734                     break;
735                 }
736             }
737             if($dir == "up" && $pos > 0){
738                 $pos --;
739             }
740             $this->_add_entry($parent['UNIQID'],$o_from,$pos);
741             $this->_remove_entry_id($id);
742             return(TRUE);
743         }
744         return(FALSE);
745     }
749     /*! \brief  Returns the railing object ID of the given object.
750       @return String  The id of the trailing object.
751      */ 
752     function _get_last($id)
753     {
754         $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
755         for($i = 0 ; $i < count($all_l) ; $i ++){
756             if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
757                 $i++;
758                 break;
759             }
760         }
761         while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
762             $i++;
763         }
765         if(!isset($all_l[$i])){
766             return(FALSE);
767         }
769         if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
770             return($all_l[$i]['PARENT']);
771         }     
773         return($all_l[$i]['UNIQID']);
774     }
777     /*! \brief  Returns the following object ID of the given object.
778       @return String  The id of the following object.
779      */ 
780     function _get_next($id,$parent = 0)
781     {
782         $all_l = $this->_get_entries_for_release($this->FAIrelease);
783         for($i = 0 ; $i < count($all_l) ; $i ++){
784             if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
785                 $i++;
786                 break;
787             }
788         }
789         if($parent != 0){
790             while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
791                 $i++;
792             }
793         }else{
794             while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
795                 $i++;
796             }
797         }
798         if(!isset($all_l[$i])){
799             return(FALSE);
800         }
801         if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
802             return($all_l[$i]['PARENT']);
803         }
804         return($all_l[$i]['UNIQID']);
805     }
810     /* !\brief Handle ui POSTS, like sort up/down/delete
811      */ 
812     function save_object()
813     {
814         foreach($_POST as $name => $value){
816             $value = get_post($name);
817             if(preg_match("/^menu_copy/",$name)){
818                 $this->copied_release = $this->FAIrelease;
819                 break;
820             }
821             if(preg_match("/^menu_delete/",$name)){
822                 $current_rel  = $this->_get_release_key($this->FAIrelease); 
823                 $this->_remove_entry_id($current_rel);
824                 break;
825             }
826             if(preg_match("/^menu_paste/",$name)){
827                 $source_rel   = $this->_get_release_key($this->copied_release); 
828                 $current_rel  = $this->_get_release_key($this->FAIrelease);
830                 $all = $this->_get_all_entries();
831                 $menu = $all[$source_rel]['ENTRIES'];
833                 foreach($menu as $entry){
834                     if(in_array($entry['TYPE'],array("FOLDER","ENTRY","SEPERATOR"))){
835                         $this->_add_entry($current_rel,$entry,-1);
836                     }
837                 }
838                 $this->copied_release = "";
839                 break;
840             }
842             if(preg_match("/del_/",$name)){
843                 $id = preg_replace("/^del_/","",$name);
844                 $this->_remove_entry_id($id);
845                 break;
846             }
847             if(preg_match("/app_entry_edit/",$name)){
848                 $id = preg_replace("/^app_entry_edit/","",$name);
849                 $this->_edit_entry_edit($id);
850                 break;
851             }
852             if(preg_match("/up_/",$name)){
853                 $id = preg_replace("/^up_/","",$name);
854                 $this->_move_entry($id,"up");
855                 break;
856             }
857             if(preg_match("/down_/",$name)){
858                 $id = preg_replace("/^down_/","",$name);
859                 $this->_move_entry($id,"down");
860                 break;
861             }
862             if(preg_match("/^parameter_/",$name) && 
863                     count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
864                 $name = preg_replace("/^parameter_/","",$name);
865                 $this->app_parameter[$name] = $value;
866             }
867         }
868         if(isset($_POST['FAIrelease'])){
869             $this->FAIrelease = get_post('FAIrelease');
870             $this->_check_missing_release($this->FAIrelease);
871         }
873         $this->applicationList->save_object();
874         $action = $this->applicationList->getAction();
875         if($action['action'] == "edit"){
876             $data= $this->applicationList->getData($action['targets'][0]);
877             $dn= $this->applicationList->getKey($action['targets'][0]);
878             if($data['TYPE'] == 'DEP'){
879                 $this->curbase = $dn; 
880             }elseif($data['TYPE'] == 'APP' && isset($_POST['folder'])){
881                 $this->_add_app_id(get_post('folder'),$dn); 
882             }
883         }
884         if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
885             $folder = get_post('folder');
886             foreach($_POST as $name => $value){
887                 if(preg_match("/^AddApp_[0-9]*$/",$name)){
888                     $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));   
889                 }
890             }
891         }
893         /* Add seperator */
894         if(isset($_POST['add_seperator']) && isset($_POST['menu_folder'])){
895             $folder = get_post('menu_folder');
896             $this->_add_seperator($folder);
897         }
899         if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
900             $folder = get_post('menu_folder');
901             $name = get_post('menu_folder_name');
902             if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
903                 $this->_add_sub_folder($folder,$name);
904             }
905         }
906         if(isset($_POST['app_entry_save'])){ 
907             $this->_save_entry_edit();
908         }
910         if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
911             if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
912                 $this->edit_entry['ICON'] = file_get_contents(gosa_file_name($_FILES['folder_image']['tmp_name']));
913             }
914         }
916         if(isset($_POST['edit_reset_image'])){
917             $this->edit_entry['ICON'] = "";
918         }
920         if(isset($_POST['app_entry_cancel'])){
921             $this->edit_entry = array();
922             $this->dialog = FALSE;
923         }
924         $this->reload();
925     }
928     /*! \brief Returns the UNIQID of the currently selected release 
929      */ 
930     function _get_release_key($release,$add_if_missing = FALSE)
931     {
932         $release_info = $this->Releases[$release];
934         if($release_info['name'] == "/"){
935             return($this->a_Structure['0']['UNIQID']);
936         }
938         $cur = &$this->a_Structure[0]['ENTRIES'];
939         $s_key = "";
940         $found = FALSE;
941         foreach($release_info['parts'] as $name){
942             foreach($cur as $key => $obj){
943                 if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
944                     $s_key = $cur[$key]['UNIQID'];
945                     $cur = &$cur[$key]['ENTRIES'];
946                     $found = TRUE;
947                     break;
948                 }
949                 $found = FALSE;
950             }
951         }
952         if($found){
953             return($s_key);  
954         }  
955         return(FALSE);
956     }
959     /*! \brief Add a new folder folder to the specified folder id
960       @param  String $folder The folder id in where we want to add the new folder.
961       @param  String $name   The name of the new folder.
962      */ 
963     function _add_sub_folder($folder,$name)
964     {
965         $all = $this->_get_all_entries();
966         if($folder == "BASE"){
967             $folder = $this->_get_release_key($this->FAIrelease,TRUE);
968         }
970         if(isset($all[$folder])){
971             $a_folder = array();
972             $a_folder['STATUS'] = "ADDED";
973             $a_folder['NAME']   = $name;
974             $a_folder['UNIQID'] = uniqid();
975             $a_folder['ENTRIES']= array();
976             $a_folder['PARENT'] = $folder;      
977             $a_folder['TYPE']   = "FOLDER";
978             $a_folder['ICON']   = "";
979             $all[$folder]['ENTRIES'][] = $a_folder;
980         }
981     }
984     /* !\brief  Remove the given id from the menu structure.
985        @param  String  ID to of the entry we want to remove.
986        @return Boolean TRUE on success
987      */
988     function _remove_entry_id($id)
989     {
990         $all = $this->_get_all_entries();
991         if(isset($all[$id])){
992             $all[$id]['STATUS'] = "REMOVED";
993             $all[$id]['ENTRIES'] = array();
994             return(TRUE);
995         }
996         return(FALSE);
997     }
1000     /* !\brief  Adds an object to a given folder.
1001        @param  String  The folder where we should add the entry
1002        @param  Array   The entry we want to add.
1003        @param  Array   The position in the destination entry array.
1004      */
1005     function _add_entry($folder_id,$entry,$pos = 0)
1006     {
1007         $all = $this->_get_all_entries();
1009         /* Do not add removed */
1010         if($entry['STATUS'] == "REMOVED"){
1011             return;
1012         }
1014         /* Check if the folder exists 
1015          */
1016         if(isset($all[$folder_id])){
1018             /* Check if the entry we want to add, 
1019                contains su objects.
1020              */
1021             if(!isset($entry['ENTRIES'])){
1022                 $entries = array();
1023             }else{
1024                 $entries = $entry['ENTRIES'];
1025             }
1026             $folder  = &$all[$folder_id];
1028             /* Prepare the entry to be added.
1029              */
1030             $entry['UNIQID'] = uniqid();     
1031             $entry['PARENT'] = $folder_id;
1032             $entry['ENTRIES']= array();
1033             $entry['STATUS'] = "ADDED";
1035             /* Append the ebtry to the given folder 
1036                and to the given position \$pos
1037              */ 
1038             $cnt = 0; 
1039             $new = array();
1040             $added =FALSE;
1041             foreach($folder['ENTRIES'] as $key => $obj){
1042                 if($obj['STATUS'] == "LOADED"){
1043                     $obj['STATUS'] = "EDITED";
1044                 }
1045                 if($pos == $cnt){
1046                     $new[] = $entry;
1047                     $added = TRUE;
1048                 }
1049                 $cnt ++;
1050                 $new[] = $obj;
1051             }
1052             if(!$added){
1053                 $new[] = $entry;
1054             }
1055             $all[$folder_id]['ENTRIES'] = &$new;
1057             /* Add sub entries too.
1058              */ 
1059             foreach($entries as $sub){
1060                 $this->_add_entry($entry['UNIQID'],$sub,-1);
1061             }
1062             return(TRUE);
1063         }
1064         return(FALSE);
1065     }
1068     /*! \brief Add the application identified by $app_id to folder $folder_id 
1069       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
1070       @param  Integer app_id    The ID of the application which should be added.
1071      */ 
1072     function _add_app_id($folder_id,$app_id)
1073     {
1074         $all = $this->_get_all_entries();
1075         if($folder_id == "BASE"){
1076             $folder_id = $this->_get_release_key($this->FAIrelease);
1077         }
1078         if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
1080             $new = array();
1081             $new['TYPE']  = "ENTRY";
1082             $new['NAME']  = $this->apps[$app_id]['cn'][0];
1083             $new['UNIQID']= uniqid(); 
1084             $new['PARENT']= $folder_id;
1085             $new['PARAMETER']= array();
1086             if(isset($this->apps[$app_id]['description'][0])){
1087                 $new['INFO']  = $this->apps[$app_id]['description'][0];
1088             }else{
1089                 $new['INFO']  = "";
1090             }
1091             $new['STATUS']= "ADDED";
1092             $all[$folder_id]['ENTRIES'][] = $new;
1093         }
1094     }
1097     /*! \brief Add the application identified by $app_id to folder $folder_id 
1098       @param  String  folder_id The UNIQID of the folder where we want to add the new folder.
1099       @param  Integer app_id    The ID of the application which should be added.
1100      */ 
1101     function _add_seperator($folder_id)
1102     {
1103         $all = $this->_get_all_entries();
1104         if($folder_id == "BASE"){
1105             $folder_id = $this->_get_release_key($this->FAIrelease);
1106         }
1108         if(isset($all[$folder_id])){
1109             $new = array();
1110             $new['TYPE']  = "SEPERATOR";
1111             $new['NAME']  = "SEPERATOR";
1112             $new['UNIQID']= uniqid(); 
1113             $new['PARENT']= $folder_id;
1114             $new['PARAMETER']= array();
1115             $new['STATUS']= "ADDED";
1116             $all[$folder_id]['ENTRIES'][] = $new;
1117         }
1118     }
1121     /*! \brief  Return all entries linear. ($this->a_Structure is a multidimensional array) 
1122       @param  Boolean   $add_tags  If TRUE, OPEN/CLOSE Tags will be appended.
1123       Used in the smarty template to display logical sperations.
1124       @param  &Array    Start here, Pointer to an array.
1125      */ 
1126     function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, &$cur = NULL)
1127     {
1128         $ret = array();
1129         if($cur == NULL){
1130             $cur = &$this->a_Structure;
1131         }
1133         /* Walk through all entries and append them to our return array 
1134          */
1135         foreach($cur as $key => $entry){
1136             if($skip_release && $entry['TYPE'] == "RELEASE"){
1137                 continue;
1138             }    
1139             if($entry['TYPE'] == "ENTRY"){
1140                 $found = FALSE;
1141                 foreach($this->apps as $app){
1142                     if($app['cn'][0] == $entry['NAME']){
1143                         $found = TRUE;
1144                         if(isset($app['description'][0])){
1145                             $entry['INFO'] = "[".$app['description'][0]."]";
1146                         }
1147                         break;
1148                     }
1149                 } 
1150                 if(!$found){
1151                     $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
1152                 }
1153             }
1155             $tmp = $entry;
1157             /* Recursive resolution of the subentries  
1158                There are two methods.
1159                - Just add sub entries  
1160                - Add sub entries and additionaly add OPEN / CLOSE tags to be able 
1161                to display logical seperators in the smarty template.
1162              */ 
1163             if(!$add_tags){
1164                 $ret[$tmp['UNIQID']] = &$cur[$key];
1165                 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
1166                     $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1167                 }
1168             }else{
1170                 if(isset($tmp['ENTRIES'])){
1171                     unset($tmp['ENTRIES']);
1172                 }
1173                 if($tmp['STATUS'] != "REMOVED"){
1174                     $ret[] = $tmp;
1175                     if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
1176                         $add = false;
1177                         foreach($entry['ENTRIES'] as $entry){
1178                             if($entry['STATUS'] != "REMOVED"){
1179                                 $add = TRUE;
1180                                 break;
1181                             }
1182                         }
1184                         if($add){
1185                             $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
1186                             $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1187                             $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
1188                         }
1189                     }
1190                 }
1191             }
1192         }
1193         return($ret);
1194     }
1197     /*! \brief Save this plugin data to ldap.
1198       Save the current menu structure to ldap.
1199      */
1200     function save()
1201     {
1202         $ldap = $this->config->get_ldap_link();
1203         $all = $this->_get_all_entries();
1204         $prio = 0;
1205         $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
1207         /* Walk through the menu structure and build up the ldap data object, 
1208            the entry dn and the entry priority.
1209          */
1210         $sep_id = 0;
1211         foreach($all as $entry){
1212             $prio ++;
1213             $cur = $entry;
1214             $dn = "";
1216             /* Build entry dn
1217              */
1218             do{  
1219                 if($cur['TYPE'] == "SEPERATOR"){
1220                     $sep_id ++;
1221                     $dn.= "cn=seperator_".$sep_id.",";
1222                 }elseif($cur['TYPE'] == "ENTRY"){
1223                     $dn.= "cn=".$cur['NAME'].",";
1224                 }elseif($cur['TYPE'] == "FOLDER"){
1225                     $dn.= "cn=".$cur['NAME'].",";
1226                 }elseif($cur['TYPE'] == "RELEASE"){
1227                     $dn.= "ou=".$cur['NAME'].",";
1228                 }elseif($cur['TYPE'] == "BASE"){
1229                 }
1230                 if(!isset($all[$cur['PARENT']])){
1231                     $cur = NULL;
1232                 }else{
1233                     $cur = $all[$cur['PARENT']];
1234                 }
1235             }while(is_array($cur));
1237             $cur_dn = $dn.$this->dn;
1238             $attrs = array();
1240             /* Build entry data object.
1241              */
1242             switch($entry['TYPE']){
1243                 case "SEPERATOR"    :
1244                 { 
1245                     $attrs['objectClass'] = array("gotoMenuEntry");
1246                     $attrs['cn']          = "seperator_".$sep_id;
1247                     $attrs['gosaApplicationPriority'] = $prio;
1248                     $attrs['gosaApplicationParameter'] = "*separator*";
1249                 }
1250                 break;
1251                 case "ENTRY"    :
1252                 { 
1253                     $attrs['objectClass'] = array("gotoMenuEntry");
1254                     $attrs['cn']          = $entry['NAME'];
1255                     $attrs['gosaApplicationPriority'] = $prio;
1256                     $attrs['gosaApplicationParameter'] = array(); 
1258                     foreach($entry['PARAMETER'] as $name => $value){
1259                         $attrs['gosaApplicationParameter'][] = $name.":".$value; 
1260                     }
1261                     if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1262                         unset($attrs['gosaApplicationParameter']);
1263                     } 
1264                 }
1265                 break;
1266                 case "FOLDER"   : 
1267                 { 
1268                     $attrs['objectClass'] = array("gotoSubmenuEntry");
1269                     $attrs['cn']          = $entry['NAME'];
1270                     $attrs['gosaApplicationPriority'] = $prio;
1271                     if($entry['STATUS'] != "ADDED"){
1272                         $attrs['gosaApplicationIcon'] = array();
1273                     }
1275                     if(!empty($entry['ICON'])){
1276                         $attrs['gosaApplicationIcon']     = $entry['ICON'];
1277                     }
1278                 }
1279                 break;
1280                 case "RELEASE"  : 
1281                 {
1282                     $attrs['ou']            = $entry['NAME'];
1283                     $attrs['objectClass']   = array();
1284                     $attrs['objectClass'][] = "top";
1285                     $attrs['objectClass'][] = "organizationalUnit";
1286                     $attrs['objectClass'][] = "FAIbranch";
1287                     if(!empty($entry['FAIstate'])){
1288                         $attrs['FAIstate']      = $entry['FAIstate'];
1289                     }
1290                 }
1291                 break;
1292             }
1294             /* Append missing ObjectClasses,  ...  Tagging 
1295              */
1296             if(isset($entry['LDAP_ATTRS'])){
1297                 for($i = 0 ; $i < $entry['LDAP_ATTRS']['objectClass']['count']; $i ++){
1298                     $oc = $entry['LDAP_ATTRS']['objectClass'][$i];
1299                     if(!in_array($oc,$attrs['objectClass'])){
1300                         $attrs['objectClass'][] = $oc;
1301                     }
1302                 }
1303             }
1305             /* Create an array containing all operations sorted by type. (add,remove...)
1306              */
1307             if($entry['STATUS'] == "LOADED"){
1308                 continue;
1309             }
1310             if($entry['STATUS'] == "REMOVED"){
1311                 if(isset($entry['DN'])){
1312                     $Actions['Remove'][$entry['DN']] = $entry['DN'];
1313                 }else{
1314                     $Actions['Remove'][$cur_dn] = $cur_dn;
1315                 }
1316             }
1317             if($entry['STATUS'] == "EDITED"){
1318                 $Actions['Edit'][$cur_dn] = $attrs;
1319             }
1320             if($entry['STATUS'] == "ADDED"){
1321                 $Actions['Add'][$cur_dn] = $attrs;
1322             }
1323         }
1325         /* First remove entries
1326          */
1327         $ldap = $this->config->get_ldap_link();
1328         $ldap->cd($this->config->current['BASE']);
1329         foreach($Actions['Remove'] as $dn){
1330             $ldap->cd($dn);
1331             $ldap->cat($dn);
1332             if($ldap->count()){
1333                 $ldap->rmdir_recursive($dn);
1334                 if (!$ldap->success()){
1335                     msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1336                 }
1337             }
1338         }
1340         /* Add new entries
1341          */
1342         foreach($Actions['Add'] as $dn => $data){
1343             $this->tag_attrs($data,$dn,$this->gosaUnitTag);
1344             $ldap->cd($dn);
1345             $ldap->cat($dn);
1346             if(!$ldap->count()){
1347                 $ldap->add($data);
1348                 if (!$ldap->success()){
1349                     msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
1350                 }
1351             }
1352         }
1354         /* Modify entries
1355          */
1356         foreach($Actions['Edit'] as $dn => $data){
1357             $this->tag_attrs($data,$dn,$this->gosaUnitTag);
1358             $ldap->cd($dn);
1359             $ldap->cat($dn);
1360             if($ldap->count()){
1361                 $ldap->modify($data);
1362                 if (!$ldap->success()){
1363                     msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
1364                 }
1365             }
1366         }
1368         $this->_load_menu_structure();
1369     }
1372     /*! \brief  Return plugin informations for acl handling  
1373       @return Array containing all plugin ACL informations
1374      */ 
1375     static function plInfo()
1376     {
1377         return (array(
1378                     "plShortName"   => _("Applications"),
1379                     "plDescription" => _("Group applications"),
1380                     "plSelfModify"  => FALSE,
1381                     "plDepends"     => array(),
1382                     "plPriority"    => 7,
1383                     "plSection"     => array("administration"),
1384                     "plCategory"    => array("groups","ogroups"),
1385                     "plRequirements"=> array(
1386                         'ldapSchema' => array('gotoSubmenuEntry'=>'>=2.7','gotoMenuEntry' => '>=2.7'),
1387                         'onFailureDisablePlugin' => array(get_class())
1388                         ),
1389                     "plProvidedAcls"=> array(
1390                         "gosaMemberApplication"     => _("Application"),
1391                         "FAIrelease"                => _("Release"),
1392                         "gosaApplicationParameter"  => _("Application parameter"))
1393                     ));
1394     }
1397     /* \brief   Prepare this plugin to be copied.
1398        Adapt all required attributes from the source object.
1399        In this case, update the menu structure too, mark all elements
1400        as newly added, so they will be saved in save();
1401      */
1402     function PrepareForCopyPaste($source)
1403     {
1404         plugin::PrepareForCopyPaste($source);
1406         $tmp = new appgroup($this->config,$source['dn']);
1407         $this->is_account = TRUE;
1408         $this->a_Structure = $tmp->a_Structure;
1409         $all = $this->_get_all_entries();
1410         foreach($all as &$entry){
1411             if(isset($entry['STATUS'])){
1412                 $entry['STATUS'] = "ADDED";
1413             }
1414         }
1415     }
1418     /*! \brief  Save HTML posts in multiple edit mode
1419      */
1420     function multiple_save_object()
1421     {
1422         if(isset($_POST['group_apps_multi'])){
1423             $this->save_object(); 
1424             plugin::multiple_save_object();    
1426             /* Get posts */
1427             foreach(array("apps") as $attr){
1428                 if(isset($_POST['use_'.$attr])) {
1429                     $this->multi_boxes[] = $attr;
1430                 }
1431             }
1432         }
1433     }
1436     /*! \brief  Return values used in multiple edit mode.
1437       Some values can be modified for multiple 
1438       groups at the same time.
1439       @return Array  All values that support multiple edit.
1440      */
1441     function get_multi_edit_values()
1442     {
1443         $ret = plugin::get_multi_edit_values();
1445         if(in_array("apps",$this->multi_boxes)){
1446             $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1447             $ret['Categories']               = $this->Categories;
1448             $ret['gosaMemberApplication']    = $this->gosaMemberApplication;
1449             $ret['FAIrelease']               = $this->FAIrelease;
1450             $ret['appoption']                = $this->appoption;
1451         }
1452         return($ret);
1453     }
1455 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1456 ?>