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 = "";
21 var $gosaApplicationFlags;
22 var $app_flags = array(
23 "placeOnDesktop" => "D",
24 "placeOnKicker" => "L",
25 "placeInStartmenu" => "M",
26 );
29 public function __construct(&$config, $dn= NULL, $parent= NULL)
30 {
31 plugin::plugin($config,$dn,$parent);
32 $this->dn = $dn;
33 $this->_load_menu_structure();
34 $this->a_Structure_on_load = $this->a_Structure;
36 /* Check if we have relase mangement enabled and prepare group application for release management */
37 $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
38 if(!empty($tmp)){
39 $this->enableReleaseManagement = true;
40 }
42 $this->Releases = $this->getReleases();
44 /* Set intial release */
45 $this->FAIrelease = $config->search("faiManagement","DEFAULTFAIRELEASE",array("menu"));
46 if(empty($this->FAIrelease) || !isset($this->Releases[$this->FAIrelease])){
47 $this->FAIrelease = "/";
48 }
50 $this->curbase = $this->config->current['BASE'];
51 $this->reload();
53 /* If we have at least one assigned application-
54 Enable this account.
55 */
56 $this->is_account = FALSE;
57 if(count($this->_get_all_entries()) > 1){
58 $this->is_account= TRUE;
59 }
60 $this->initially_was_account = $this->is_account;
61 }
64 /*! \brief Reload the list of applications for the currently selected release.
65 If necessary, maybe the list is already cached.
66 */
67 function reload()
68 {
69 $ret = array();
70 $release_info = $this->Releases[$this->FAIrelease];
72 /* Check if the available application were already been fetched.
73 If not, build up a list of available applications.
74 */
75 if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
77 /* First of all, get all application departments to search in.
78 */
79 $ldap = $this->config->get_ldap_link();
80 $ldap->cd($this->config->current['BASE']);
81 $ldap->search("ou=apps",array("dn"));
82 $app_deps = array();
83 while($attrs = $ldap->fetch()){
84 $app_deps[] = $attrs['dn'];
85 }
87 /* Search all release departments for the above fetched application departments
88 */
89 foreach($app_deps as $dep){
90 $ldap->cd($dep);
91 $ldap->search("objectClass=FAIbranch",array("dn"));
92 while($attrs = $ldap->fetch()){
93 $app_deps[] = $attrs['dn'];
94 }
95 }
97 /* Filter out those releases that match the currently selected release,
98 and fetch all applications from those departments.
99 */
100 foreach($app_deps as $dep){
101 if(preg_match("/^".preg_quote($release_info['suffix'], '/')."/",$dep)){
102 $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
103 }
104 }
106 /* Create a new array containing all fetch apps for the currently selected release,
107 sort it and store results in cache.
108 */
109 $tmp = array();
110 foreach($ret as $key => $app){
111 $tmp[$key] = $app['cn'][0];
112 }
113 natcasesort($tmp);
114 $res = array();
115 foreach($tmp as $key => $app){
116 $res[] = $ret[$key];
117 }
119 $this->_cache['ReleaseApps'][$release_info['suffix']] = $res;
120 }
121 $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
122 }
126 /*! \brief generate a list of available releases
127 @return return an array with all available releases.
129 e.g.
131 / "name" /
132 "found" 1
133 "parts" Array (empty)
134 "suffix" ou=apps,
136 halut "name" halut
137 "found" 1
138 "FAIstate"
139 "dn" ou=halut,ou=apps,ou=Direktorium,o=Landeshauptstadt München,c=de
140 "parts" 0 halut
141 "suffix" ou=halut,ou=apps,
143 This will be used as base for the application menu structure.
144 If there is a menu assigned for a release, this menu will be
145 appended with the index 'ENTRIES';
146 */
147 function getReleases()
148 {
149 $ret =array("/" => array("name" => "/", "found" => TRUE , "parts" => array(),"suffix" => get_ou('applicationRDN')));
150 if($this->enableReleaseManagement){
152 /* Only display those releases that we are able to read
153 */
154 $dn = get_ou("applicationRDN").$this->config->current['BASE'];
155 $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
156 $res = get_sub_list($filter,array("application","fai"),
157 array(get_ou("applicationRDN"),get_ou("faiBaseRDN")),$dn, array("ou","FAIstate"), GL_SUBSEARCH);
159 /* Go through all departments and check which department is a valid
160 department release.
161 */
162 foreach($res as $attrs){
163 if(preg_match("/".get_ou('applicationRDN')."/",$attrs['dn'])){
165 /* Parse all returned departments dns into a useable type.
166 (ou=1.0.0,ou=halut,ou=apps ==> halue/1.0.0)
167 */
168 $bb = preg_replace("/".get_ou('applicationRDN').".*/","",$attrs['dn']);
169 $parts = array_reverse(split("ou=",$bb));
171 $str ="";
172 foreach($parts as $key => $part){
173 if(empty($part)) {
174 unset($parts[$key]);
175 continue;
176 }
177 $part = str_replace(",","",$part);
178 $str .= $part."/";
179 $parts[$key] = $part;
180 }
181 $name = preg_replace("/\/$/","",$str);
182 if(empty($name)) {
183 $name ="/";
184 }
186 $FAIstate = "";
187 if(isset($attrs['FAIstate'])){
188 $FAIstate = $attrs['FAIstate'][0];
189 }
191 /* Check if this department has a menu structure assigned
192 */
193 $all = $this->_get_all_entries();
194 $found = FALSE;
195 foreach($all as $entry){
196 if(isset($entry['DN']) && preg_match("/^".preg_quote($bb, '/')."/",$entry['DN'])){
197 $found =TRUE;
198 break;
199 }
200 }
202 $ret[$name] = array("name" => $name,
203 "found" => $found,
204 "FAIstate" => $FAIstate,
205 "dn" => $attrs['dn'],
206 "parts" => $parts,"suffix" => $bb.get_ou('applicationRDN'));
207 }
208 }
209 }
210 ksort($ret);
211 return($ret);
212 }
215 /*! \brief Load the menu structure from ldap and create a multi dimensional array.
217 This will create a multidimensional array.
218 e.g.:
220 $this->a_Structure =
222 [0]['TYPE'] = "BASE"
223 [0]['ENTRIES'] [0]['TYPE'] = "RELEASE"
224 [0]['NAME'] = "halut"
225 [0]['ENTRIES']= array()
226 ...
227 [0]['ENTRIES'] [1]['TYPE'] = "RELEASE"
228 [1]['NAME'] = "halut/1.0.0"
229 [1]['ENTRIES'] [0]['TYPE'] = "TYPE"
230 [0]['NAME'] = "Programme"
231 [0]['ENTRIES'][0]['TYPE'] = "ENTRY"
232 [0]['NAME'] = "konqueror"
233 [1]['TYPE'] = "ENTRY"
234 [1]['NAME'] = "firefox"
235 */
236 function _load_menu_structure()
237 {
238 /* Create the base object
239 */
240 $base = array();
241 $base['UNIQID'] = uniqid();
242 $base['PARENT'] = 0;
243 $base['NAME'] = "";
244 $base['TYPE'] = "BASE";
245 $base['ENTRIES']= array();
246 $base['STATUS'] = "LOADED";
248 $this->a_Structure = array();
249 $this->a_Structure[0] = $base;
251 /* Search for all Releases/Menu Folders and Menu Entries,
252 to append them to our structure array.
253 */
254 $ldap = $this->config->get_ldap_link();
255 $ldap->cd($this->dn);
256 $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
257 while($attrs = $ldap->fetch()){
259 /* Find the correct position where to add this entry.
260 e.g. If we have cn=firefox,cn=Programme,ou=halut...
262 1. get a pointer to the halut array ($this->a_Structure['0'][ENTRIES''][]['halut'])
263 2. then get a pointer to the halut['ENTRIES'][]['Programme'] array.
264 3. append 'firefox' to the 'ENTRIES' of our "Programme" pointer.
265 */
266 $cur = &$this->a_Structure[0]['ENTRIES'];
267 $parent_id = $base['UNIQID'];
268 $sub_dn = preg_replace("/,".preg_quote($this->dn, '/')."$/","",$attrs['dn']);
269 $sub_dn_array = split("\,",$sub_dn);
271 /* Walk through our menu structure array while we have found
272 the correct position where to add this object.
273 */
274 $found = true;
275 for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
276 $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
278 /* We haven't found the end node where this object has to be added
279 */
280 if($i > 0){
281 $found =FALSE;
282 foreach($cur as $key => $entry){
283 if($entry['NAME'] == $name){
284 $cur = &$cur[$key]['ENTRIES'];
285 $parent_id = $entry['UNIQID'];
286 $found =true;
287 break;
288 }
289 }
290 }else{
292 if(!$found){
293 break;
294 }
296 /* Get application priority.
297 And ensure that each priority exists once.
298 */
299 $priority = 1;
300 if(isset($attrs['gosaApplicationPriority'])){
301 $priority= $attrs['gosaApplicationPriority'][0];
302 }
303 while(isset($cur[$priority])){
304 $priority ++;
305 }
307 /* Create the data object that should be added
308 * Folder
309 * Entry
310 * Release
311 */
312 $data = array();
314 /* Add a menu folder
315 */
316 if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
317 $type = "FOLDER";
319 $data['ICON'] = "";
320 if(isset($attrs['gosaApplicationIcon'])){
321 $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
322 }
324 /* Add a menu entry
325 */
326 }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
328 $type = "ENTRY";
329 $data['INFO'] = "";
330 $data['PARAMETER'] = array();
331 if(isset($attrs['gosaApplicationParameter'])){
332 for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
333 if(preg_match("/:/",$attrs['gosaApplicationParameter'][$p])){
334 list($key, $value) = explode(":",$attrs['gosaApplicationParameter'][$p], 2);
335 if ($key == "gosaApplicationFlags") {
336 $data['FLAGS'] = $value;
337 }
338 else {
339 $data['PARAMETER'][$key] = $value;
340 }
341 }elseif($attrs['gosaApplicationParameter'][$p] == "*separator*"){
342 $type = "SEPERATOR";
343 $data['PARAMETER'] = array();
344 break;
345 }
346 }
347 }
349 /* Add a release
350 */
351 }elseif(in_array("FAIbranch",$attrs['objectClass'])){
352 $type = "RELEASE";
353 if(isset($attrs['FAIstate'][0])){
354 $data['FAIstate'] = $attrs['FAIstate'][0];
355 }else{
356 $data['FAIstate'] = "";
357 }
358 }
360 /* Create object and append it to the current structure pointer
361 */
362 $data['LDAP_ATTRS'] = $attrs;
363 $data['DN'] = $attrs['dn'];
364 $data['NAME'] = $name;
365 $data['TYPE'] = $type;
366 $data['PRIORITY'] = $priority;
367 $data['ENTRIES'] = array();
368 $data['UNIQID'] = uniqid();
369 $data['PARENT'] = $parent_id;
370 $data['STATUS'] = "LOADED";
371 $cur[$priority] = $data;
372 ksort($cur);
373 }
374 }
375 }
376 }
379 function execute()
380 {
381 /* Call parent execute */
382 plugin::execute();
384 if(isset($_GET['r'])) $this->__construct($this->config,$this->dn);
386 if (isset($_POST['modify_state'])){
387 $this->is_account = !$this->is_account;
388 }
390 /* Do we represent a valid account? */
391 if (!$this->is_account){
392 $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Menu")), msgPool::featuresDisabled(_("Menu")));
393 return ($display);
394 }
396 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Menu")), msgPool::featuresEnabled(_("Menu")));
398 if(isset($_GET['send'])){
399 $id = $_GET['send'];
400 $all = $this->_get_all_entries();
401 if(isset($all[$id])){
402 send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
403 exit;
404 }
405 }
407 if(isset($_GET['r']))
408 $this->__construct($this->config,$this->dn);
410 if(count($this->edit_entry)){
411 $smarty = get_smarty();
412 /* Checkboxes */
413 foreach ($this->app_flags as $name => $flag){
414 if (preg_match("/$flag/", $this->gosaApplicationFlags) && $this->acl_is_readable("$name")){
416 $smarty->assign("$name", "checked");
417 } else {
418 $smarty->assign("$name", "");
419 }
420 }
422 $tmp = $this->plInfo();
423 foreach($tmp['plProvidedAcls'] as $name => $translation){
424 $smarty->assign($name."ACL",$this->getacl($name));
425 }
427 if($this->edit_entry['TYPE'] == "ENTRY"){
428 $smarty->assign("type", "ENTRY");
429 $smarty->assign("entry",$this->edit_entry);
430 $smarty->assign("paras",$this->app_parameter);
431 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
432 return($display);
433 }
434 if($this->edit_entry['TYPE'] == "FOLDER"){
436 session::set("binarytype" , "image/jpeg");
437 session::set("binary" , $this->edit_entry['ICON']);
439 $smarty->assign("rand", microtime(TRUE));
440 $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0);
441 $smarty->assign("type", "FOLDER");
442 $smarty->assign("entry",$this->edit_entry);
443 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
444 return($display);
445 }
446 }
448 $smarty = get_smarty();
449 $smarty->assign("plug_id" , $_GET['plug']);
451 /* Create application list */
452 $div = new divSelectBox("appgroup");
453 $div->SetHeight(300);
454 $departments = array();
455 if(!$this->enableReleaseManagement){
456 $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
457 foreach($res as $value){
458 $fdn = $value['dn'];
459 $fdn = preg_replace("/".preg_quote($this->curbase, '/')."/","",$fdn);
460 $fdn= LDAP::fix($fdn);
461 if($value["description"][0]!=".."){
462 $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
463 }else{
464 $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
465 }
466 }
467 }
469 $linkopen = "<a href='?plug=".$_GET['plug']."&act=depopen&depid=%s'>%s</a>";
471 /* Create base back entry */
472 $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
473 if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
474 $div->AddEntry(array(
475 array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
476 "attach"=>"style='border:0px;'")
477 ));
478 }
480 /* Append departments for current base */
481 foreach($departments as $key => $app){
482 $div->AddEntry(array(
483 array("string"=>"<img class='center' src='images/lists/folder.png' alt='"._("department")."'> ".sprintf($linkopen,
484 base64_encode($key),$app),
485 "attach"=>"style='border:0px;'")
486 ));
487 }
490 /* Add applications found on this base */
491 $used_apps = $this->_get_used_entry_name();
492 foreach($this->apps as $key => $app){
493 if(in_array($app['cn'][0],$used_apps)){
494 continue;
495 }
496 if(!preg_match("/".get_ou('applicationRDN').preg_quote($this->curbase, '/')."$/",$app['dn'])){
497 continue;
498 }
500 $name = $app['cn'][0];
501 if(isset($app['description'])){
502 $name .= " [".$app['description'][0]."]";
503 }
504 $div->AddEntry(array(
505 array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
506 "<img class='center' src='plugins/goto/images/select_application.png' alt='"._("application")."'> ".$name,
507 "attach"=>"style='border:0px;'")
508 ));
509 }
511 /* Assign copy / paste values
512 */
513 if(!empty($this->copied_release)){
514 $smarty->assign("copied", TRUE);
515 $smarty->assign("copy_source", $this->copied_release);
516 }else{
517 $smarty->assign("copied", FALSE);
518 }
519 $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
520 $smarty->assign("FAIrelease",$this->FAIrelease);
521 $smarty->assign("app_list",$div->DrawList());
522 $smarty->assign("i",0);
523 $smarty->assign("releases",$this->Releases);
524 $smarty->assign("folders" , $this->_get_folder_names());
525 $entries = $this->_get_entries_for_release($this->FAIrelease);
526 $smarty->assign("entries",$entries);
527 $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
528 return($display);
529 }
532 /*! \brief Returns all used folder names
533 @return Array All used folder names.
534 */
535 function _get_folder_names()
536 {
537 $data = $this->_get_entries_for_release($this->FAIrelease);
538 $all = $this->_get_all_entries();
539 $ret = array("BASE" => ".");
540 foreach($data as $entry){
542 if($entry['TYPE'] == "FOLDER"){
543 $str = $entry['NAME'];
544 $parent = $entry['PARENT'];
545 $i = 10;
546 while(isset($all[$parent]) && $i){
547 $i --;
548 $parent_o = $all[$parent];
549 $str = $parent_o['NAME']."/".$str;
550 $parent = $all[$parent_o['UNIQID']]['PARENT'];
551 }
552 $ret[$entry['UNIQID']] = $str;
553 }
554 }
555 return($ret);
556 }
559 /*! \brief return all used applications
560 @return Array All used applications.
561 */
562 function _get_used_entry_name()
563 {
564 $data = $this->_get_entries_for_release($this->FAIrelease);
565 $ret = array();
566 foreach($data as $entry){
567 if($entry['TYPE'] == "ENTRY"){
568 $ret[] = $entry['NAME'];
569 }
570 }
571 return($ret);
572 }
575 /*! \brief Returns all folder an entries for the selected release
576 @return Array Returns the complete menu structure for the given array.
577 */
578 function _get_entries_for_release($release,$cur = NULL)
579 {
580 $all = $this->_get_all_entries();
581 $key = $this->_get_release_key($release);
582 if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
583 $res = $this->_get_all_entries(TRUE,TRUE,$all[$key]['ENTRIES']);
584 return($res);
585 }
586 return(array());
587 }
590 /*! \brief Save the currently edited entry
591 */
592 function _save_entry_edit()
593 {
594 $all = $this->_get_all_entries();
595 $entry = $this->edit_entry;
596 $r_entry= &$all[$entry['UNIQID']];
599 if($entry['TYPE'] == "ENTRY"){
600 $r_entry['PARAMETER'] = $this->app_parameter;
601 $r_entry['FLAGS'] = $this->gosaApplicationFlags;
602 if($r_entry['STATUS'] != "ADDED"){
603 $r_entry['STATUS'] = "EDITED";
604 }
605 }
606 if($entry['TYPE'] == "FOLDER"){
607 $r_entry['ICON'] = $this->edit_entry['ICON'];
608 $r_entry['STATUS'] = "EDITED";
609 }
610 $this->dialog = FALSE;
611 $this->edit_entry = array();
612 }
615 /*! \brief prepare the entry with the given ID, to be edited.
616 Read application Parameter from ldap.
617 */
618 function _edit_entry_edit($id)
619 {
620 $all = $this->_get_all_entries();
621 $entry = $all[$id];
623 $this->app_parameter = array();
624 if($entry['TYPE'] == "ENTRY"){
625 $found = FALSE;
626 foreach($this->apps as $id => $app){
628 if($app['cn'][0] == $entry['NAME']){
629 $found = TRUE;
630 break;
631 }
632 }
633 if($found){
634 /* Create a list of editable parameter */
635 if(isset($app['gosaApplicationParameter'])){
636 for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
637 $para = $app['gosaApplicationParameter'][$i];
638 $tmp = explode(":",$para, 2);
639 $this->app_parameter[$tmp[0]] = $tmp[1];
640 }
641 }
643 if(isset($app['gosaApplicationFlags'])) {
644 $this->gosaApplicationFlags = $app['gosaApplicationFlags'][0];
645 }
647 /* Overwrite parameters with entry parameters */
648 foreach($entry['PARAMETER'] as $name => $value){
649 $this->app_parameter[$name] = $value;
650 }
652 if (isset($entry['FLAGS'])) {
653 $this->gosaApplicationFlags = $entry['FLAGS'];
654 }
656 $this->dialog = TRUE;
657 $this->edit_entry = $entry;
658 }
659 }
661 if($entry['TYPE'] == "FOLDER"){
662 $this->dialog = TRUE;
663 $this->edit_entry = $entry;
664 }
665 }
668 /*! \brief Removes the menu structure from ldap
669 */
670 function remove_from_parent()
671 {
672 $ldap = $this->config->get_ldap_link();
673 $ldap->cd($this->dn);
674 $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
675 $a_remove = array();
676 while($attrs = $ldap->fetch()){
677 $a_remove[] = $attrs['dn'];
678 }
679 foreach($a_remove as $remove){
680 $ldap->rmdir_recursive($remove);
681 if (!$ldap->success()){
682 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
683 }
684 }
685 $this->_load_menu_structure();
686 }
689 function check()
690 {
691 $message = plugin::check();
692 return($message);
693 }
696 /*! \brief Create missing releases, if there is a release selected \
697 that is currently not part of the menu structure \
698 then create this entry
699 */
700 function _check_missing_release($release)
701 {
702 $release_info = $this->Releases[$release];
704 $parent_id = $this->a_Structure[0]['UNIQID'];
705 $cur = &$this->a_Structure[0]['ENTRIES'];
706 for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
707 $part = $release_info['parts'][$i];
708 $found = FALSE;
709 foreach($cur as $key => $name){
710 if($name['NAME'] == $part){
711 $parent_id = $cur[$key]['UNIQID'];
712 $cur = &$cur[$key]['ENTRIES'];
714 $found =TRUE;
715 break;
716 }
717 }
718 if(!$found){
719 $release = array();
720 $release['UNIQID'] = uniqid();
721 $release['PARENT'] = $parent_id;
722 $release['NAME'] = $part;
723 $release['TYPE'] = "RELEASE";
724 $release['ENTRIES']= array();
725 $release['STATUS'] = "ADDED";
726 $release['FAIstate'] = $release_info['FAIstate'];
727 $cur[] = $release;
728 $i --;
729 }
730 }
731 }
735 /*! \brief Moves a given object ($id) in a specified direction ($dir).
736 @param String The object ID of the object we want to move
737 @dir String Move "up" or "down"
738 */
739 function _move_entry($id,$dir)
740 {
741 $all = $this->_get_all_entries();
742 if($dir == "down"){
743 $to = $this->_get_next($id);
744 }
745 if($dir == "up"){
746 $to = $this->_get_last($id);
747 }
749 if(!$to){
750 return;
751 }
753 $o_to = $all[$to];
754 $o_from = $all[$id];
756 if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
757 $to = $this->_get_next($to,$o_from['PARENT']);
758 $o_to = $all[$to];
759 }
761 /* Target is ENTRY && same BASE, just switch */
762 if($o_to['PARENT'] == $o_from['PARENT'] ){
763 $parent = $all[$o_to['PARENT']];
764 $pos = 0;
765 foreach($parent['ENTRIES'] as $entry){
766 $pos ++;
767 if($entry['UNIQID'] == $to){
768 break;
769 }
770 }
771 if($dir == "up" && $pos > 0){
772 $pos --;
773 }
774 $this->_add_entry($parent['UNIQID'],$o_from,$pos);
775 $this->_remove_entry_id($id);
776 return(TRUE);
777 }
778 return(FALSE);
779 }
783 /*! \brief Returns the railing object ID of the given object.
784 @return String The id of the trailing object.
785 */
786 function _get_last($id)
787 {
788 $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
789 for($i = 0 ; $i < count($all_l) ; $i ++){
790 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
791 $i++;
792 break;
793 }
794 }
795 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("SEPERATOR","ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
796 $i++;
797 }
799 if(!isset($all_l[$i])){
800 return(FALSE);
801 }
803 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
804 return($all_l[$i]['PARENT']);
805 }
807 return($all_l[$i]['UNIQID']);
808 }
811 /*! \brief Returns the following object ID of the given object.
812 @return String The id of the following object.
813 */
814 function _get_next($id,$parent = 0)
815 {
816 $all_l = $this->_get_entries_for_release($this->FAIrelease);
817 for($i = 0 ; $i < count($all_l) ; $i ++){
818 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
819 $i++;
820 break;
821 }
822 }
823 if($parent != 0){
824 while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
825 $i++;
826 }
827 }else{
828 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("SEPERATOR","ENTRY","FOLDER")) && $i < count($all_l)){
829 $i++;
830 }
831 }
832 if(!isset($all_l[$i])){
833 return(FALSE);
834 }
835 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
836 return($all_l[$i]['PARENT']);
837 }
838 return($all_l[$i]['UNIQID']);
839 }
841 /* !\brief Handle ui POSTS, like sort up/down/delete
842 */
843 function save_object()
844 {
845 foreach($_POST as $name => $value){
847 if(preg_match("/^menu_copy_/",$name)){
848 $this->copied_release = $this->FAIrelease;
849 break;
850 }
851 if(preg_match("/^menu_delete/",$name)){
852 $current_rel = $this->_get_release_key($this->FAIrelease);
853 $this->_remove_entry_id($current_rel);
854 break;
855 }
856 if(preg_match("/^menu_paste_/",$name)){
857 $source_rel = $this->_get_release_key($this->copied_release);
858 $current_rel = $this->_get_release_key($this->FAIrelease);
860 $all = $this->_get_all_entries();
861 $menu = $all[$source_rel]['ENTRIES'];
863 foreach($menu as $entry){
864 if(in_array($entry['TYPE'],array("FOLDER","ENTRY","SEPERATOR"))){
865 $this->_add_entry($current_rel,$entry,-1);
866 }
867 }
868 $this->copied_release = "";
869 break;
870 }
872 if(preg_match("/del_/",$name)){
873 $id = preg_replace("/^del_/","",$name);
874 $id = preg_replace("/_(x|y)$/","",$id);
875 $this->_remove_entry_id($id);
876 break;
877 }
878 if(preg_match("/app_entry_edit/",$name)){
879 $id = preg_replace("/^app_entry_edit/","",$name);
880 $id = preg_replace("/_(x|y)$/","",$id);
881 $this->_edit_entry_edit($id);
882 break;
883 }
884 if(preg_match("/up_/",$name)){
885 $id = preg_replace("/^up_/","",$name);
886 $id = preg_replace("/_(x|y)$/","",$id);
887 $this->_move_entry($id,"up");
888 break;
889 }
890 if(preg_match("/down_/",$name)){
891 $id = preg_replace("/^down_/","",$name);
892 $id = preg_replace("/_(x|y)$/","",$id);
893 $this->_move_entry($id,"down");
894 break;
895 }
896 if(preg_match("/^parameter_/",$name) &&
897 count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
898 $name = preg_replace("/^parameter_/","",$name);
899 $this->app_parameter[$name] = $value;
900 }
901 }
903 if(isset($_POST['FAIrelease'])){
904 $this->FAIrelease = $_POST['FAIrelease'];
905 $this->_check_missing_release($this->FAIrelease);
906 }
907 if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
908 $this->curbase = base64_decode($_GET['depid']);
909 }
910 if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
911 $folder = $_POST['folder'];
912 foreach($_POST as $name => $value){
913 if(preg_match("/^AddApp_[0-9]*$/",$name)){
914 $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));
915 }
916 }
917 }
919 /* Add seperator */
920 if(isset($_POST['add_seperator']) && isset($_POST['menu_folder'])){
921 $folder = $_POST['menu_folder'];
922 $this->_add_seperator($folder);
923 }
925 if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
926 $folder = $_POST['menu_folder'];
927 $name = $_POST['menu_folder_name'];
928 if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
929 $this->_add_sub_folder($folder,$name);
930 }
931 }
932 if(isset($_POST['app_entry_save'])){
933 foreach($this->app_flags as $name => $flag) {
934 if($this->acl_is_writeable($name)) {
935 if(!isset($_POST[$name]) && strstr($this->gosaApplicationFlags,$flag)){
936 $this->gosaApplicationFlags = str_replace($flag,"",$this->gosaApplicationFlags);
937 }elseif(isset($_POST[$name]) && !strstr($this->gosaApplicationFlags,$flag)){
938 $this->gosaApplicationFlags = str_replace("]", "$flag]", $this->gosaApplicationFlags);
939 }
940 }
941 }
943 $this->_save_entry_edit();
944 }
946 if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
947 if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
948 $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
949 }
950 }
952 if(isset($_POST['edit_reset_image'])){
953 $this->edit_entry['ICON'] = "";
954 }
956 if(isset($_POST['app_entry_cancel'])){
957 $this->edit_entry = array();
958 $this->dialog = FALSE;
959 }
960 $this->reload();
961 }
964 /*! \brief Returns the UNIQID of the currently selected release
965 */
966 function _get_release_key($release,$add_if_missing = FALSE)
967 {
968 $release_info = $this->Releases[$release];
970 if($release_info['name'] == "/"){
971 return($this->a_Structure['0']['UNIQID']);
972 }
974 $cur = &$this->a_Structure[0]['ENTRIES'];
975 $s_key = "";
976 $found = FALSE;
977 foreach($release_info['parts'] as $name){
978 foreach($cur as $key => $obj){
979 if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
980 $s_key = $cur[$key]['UNIQID'];
981 $cur = &$cur[$key]['ENTRIES'];
982 $found = TRUE;
983 break;
984 }
985 $found = FALSE;
986 }
987 }
988 if($found){
989 return($s_key);
990 }
991 return(FALSE);
992 }
995 /*! \brief Add a new folder folder to the specified folder id
996 @param String $folder The folder id in where we want to add the new folder.
997 @param String $name The name of the new folder.
998 */
999 function _add_sub_folder($folder,$name)
1000 {
1001 $all = $this->_get_all_entries();
1002 if($folder == "BASE"){
1003 $folder = $this->_get_release_key($this->FAIrelease,TRUE);
1004 }
1006 if(isset($all[$folder])){
1007 $a_folder = array();
1008 $a_folder['STATUS'] = "ADDED";
1009 $a_folder['NAME'] = $name;
1010 $a_folder['UNIQID'] = uniqid();
1011 $a_folder['ENTRIES']= array();
1012 $a_folder['PARENT'] = $folder;
1013 $a_folder['TYPE'] = "FOLDER";
1014 $a_folder['ICON'] = "";
1015 $all[$folder]['ENTRIES'][] = $a_folder;
1016 }
1017 }
1020 /* !\brief Remove the given id from the menu structure.
1021 @param String ID to of the entry we want to remove.
1022 @return Boolean TRUE on success
1023 */
1024 function _remove_entry_id($id)
1025 {
1026 $all = $this->_get_all_entries();
1027 if(isset($all[$id])){
1028 $all[$id]['STATUS'] = "REMOVED";
1029 $all[$id]['ENTRIES'] = array();
1030 return(TRUE);
1031 }
1032 return(FALSE);
1033 }
1036 /* !\brief Adds an object to a given folder.
1037 @param String The folder where we should add the entry
1038 @param Array The entry we want to add.
1039 @param Array The position in the destination entry array.
1040 */
1041 function _add_entry($folder_id,$entry,$pos = 0)
1042 {
1043 $all = $this->_get_all_entries();
1045 /* Do not add removed */
1046 if($entry['STATUS'] == "REMOVED"){
1047 return;
1048 }
1050 /* Check if the folder exists
1051 */
1052 if(isset($all[$folder_id])){
1054 /* Check if the entry we want to add,
1055 contains su objects.
1056 */
1057 if(!isset($entry['ENTRIES'])){
1058 $entries = array();
1059 }else{
1060 $entries = $entry['ENTRIES'];
1061 }
1062 $folder = &$all[$folder_id];
1064 /* Prepare the entry to be added.
1065 */
1066 $entry['UNIQID'] = uniqid();
1067 $entry['PARENT'] = $folder_id;
1068 $entry['ENTRIES']= array();
1069 $entry['STATUS'] = "ADDED";
1071 /* Append the ebtry to the given folder
1072 and to the given position \$pos
1073 */
1074 $cnt = 0;
1075 $new = array();
1076 $added =FALSE;
1077 foreach($folder['ENTRIES'] as $key => $obj){
1078 if($obj['STATUS'] == "LOADED"){
1079 $obj['STATUS'] = "EDITED";
1080 }
1081 if($pos == $cnt){
1082 $new[] = $entry;
1083 $added = TRUE;
1084 }
1085 $cnt ++;
1086 $new[] = $obj;
1087 }
1088 if(!$added){
1089 $new[] = $entry;
1090 }
1091 $all[$folder_id]['ENTRIES'] = &$new;
1093 /* Add sub entries too.
1094 */
1095 foreach($entries as $sub){
1096 $this->_add_entry($entry['UNIQID'],$sub,-1);
1097 }
1098 return(TRUE);
1099 }
1100 return(FALSE);
1101 }
1104 /*! \brief Add the application identified by $app_id to folder $folder_id
1105 @param String folder_id The UNIQID of the folder where we want to add the new folder.
1106 @param Integer app_id The ID of the application which should be added.
1107 */
1108 function _add_app_id($folder_id,$app_id)
1109 {
1110 $all = $this->_get_all_entries();
1111 if($folder_id == "BASE"){
1112 $folder_id = $this->_get_release_key($this->FAIrelease);
1113 }
1114 if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
1116 $new = array();
1117 $new['TYPE'] = "ENTRY";
1118 $new['NAME'] = $this->apps[$app_id]['cn'][0];
1119 $new['UNIQID']= uniqid();
1120 $new['PARENT']= $folder_id;
1121 $new['PARAMETER']= array();
1122 if(isset($this->apps[$app_id]['description'][0])){
1123 $new['INFO'] = $this->apps[$app_id]['description'][0];
1124 }else{
1125 $new['INFO'] = "";
1126 }
1127 $new['STATUS']= "ADDED";
1128 $all[$folder_id]['ENTRIES'][] = $new;
1129 }
1130 }
1133 /*! \brief Add the application identified by $app_id to folder $folder_id
1134 @param String folder_id The UNIQID of the folder where we want to add the new folder.
1135 @param Integer app_id The ID of the application which should be added.
1136 */
1137 function _add_seperator($folder_id)
1138 {
1139 $all = $this->_get_all_entries();
1140 if($folder_id == "BASE"){
1141 $folder_id = $this->_get_release_key($this->FAIrelease);
1142 }
1144 if(isset($all[$folder_id])){
1145 $new = array();
1146 $new['TYPE'] = "SEPERATOR";
1147 $new['NAME'] = "SEPERATOR";
1148 $new['UNIQID']= uniqid();
1149 $new['PARENT']= $folder_id;
1150 $new['PARAMETER']= array();
1151 $new['STATUS']= "ADDED";
1152 $all[$folder_id]['ENTRIES'][] = $new;
1153 }
1154 }
1157 /*! \brief Return all entries linear. ($this->a_Structure is a multidimensional array)
1158 @param Boolean $add_tags If TRUE, OPEN/CLOSE Tags will be appended.
1159 Used in the smarty template to display logical sperations.
1160 @param &Array Start here, Pointer to an array.
1161 */
1162 function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, &$cur = NULL)
1163 {
1164 $ret = array();
1165 if($cur == NULL){
1166 $cur = &$this->a_Structure;
1167 }
1169 /* Walk through all entries and append them to our return array
1170 */
1171 foreach($cur as $key => $entry){
1172 if($skip_release && $entry['TYPE'] == "RELEASE"){
1173 continue;
1174 }
1175 if($entry['TYPE'] == "ENTRY"){
1176 $found = FALSE;
1177 foreach($this->apps as $app){
1178 if($app['cn'][0] == $entry['NAME']){
1179 $found = TRUE;
1180 if(isset($app['description'][0])){
1181 $entry['INFO'] = "[".$app['description'][0]."]";
1182 }
1183 break;
1184 }
1185 }
1186 if(!$found){
1187 $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
1188 }
1189 }
1191 $tmp = $entry;
1193 /* Recursive resolution of the subentries
1194 There are two methods.
1195 - Just add sub entries
1196 - Add sub entries and additionaly add OPEN / CLOSE tags to be able
1197 to display logical seperators in the smarty template.
1198 */
1199 if(!$add_tags){
1200 $ret[$tmp['UNIQID']] = &$cur[$key];
1201 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
1202 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1203 }
1204 }else{
1206 if(isset($tmp['ENTRIES'])){
1207 unset($tmp['ENTRIES']);
1208 }
1209 if($tmp['STATUS'] != "REMOVED"){
1210 $ret[] = $tmp;
1211 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
1212 $add = false;
1213 foreach($entry['ENTRIES'] as $entry){
1214 if($entry['STATUS'] != "REMOVED"){
1215 $add = TRUE;
1216 break;
1217 }
1218 }
1220 if($add){
1221 $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
1222 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1223 $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
1224 }
1225 }
1226 }
1227 }
1228 }
1229 return($ret);
1230 }
1233 /*! \brief Save this plugin data to ldap.
1234 Save the current menu structure to ldap.
1235 */
1236 function save()
1237 {
1238 $ldap = $this->config->get_ldap_link();
1239 $all = $this->_get_all_entries();
1240 $prio = 0;
1241 $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
1243 /* Walk through the menu structure and build up the ldap data object,
1244 the entry dn and the entry priority.
1245 */
1246 $sep_id = 0;
1247 foreach($all as $entry){
1248 $prio ++;
1249 $cur = $entry;
1250 $dn = "";
1252 /* Build entry dn
1253 */
1254 do{
1255 if($cur['TYPE'] == "SEPERATOR"){
1256 $sep_id ++;
1257 $dn.= "cn=seperator_".$sep_id.",";
1258 }elseif($cur['TYPE'] == "ENTRY"){
1259 $dn.= "cn=".$cur['NAME'].",";
1260 }elseif($cur['TYPE'] == "FOLDER"){
1261 $dn.= "cn=".$cur['NAME'].",";
1262 }elseif($cur['TYPE'] == "RELEASE"){
1263 $dn.= "ou=".$cur['NAME'].",";
1264 }elseif($cur['TYPE'] == "BASE"){
1265 }
1266 if(!isset($all[$cur['PARENT']])){
1267 $cur = NULL;
1268 }else{
1269 $cur = $all[$cur['PARENT']];
1270 }
1271 }while(is_array($cur));
1273 $cur_dn = $dn.$this->dn;
1274 $attrs = array();
1276 /* Build entry data object.
1277 */
1278 switch($entry['TYPE']){
1279 case "SEPERATOR" :
1280 {
1281 $attrs['objectClass'] = array("gotoMenuEntry");
1282 $attrs['cn'] = "seperator_".$sep_id;
1283 $attrs['gosaApplicationPriority'] = $prio;
1284 $attrs['gosaApplicationParameter'] = "*separator*";
1285 }
1286 break;
1287 case "ENTRY" :
1288 {
1289 $attrs['objectClass'] = array("gotoMenuEntry");
1290 $attrs['cn'] = $entry['NAME'];
1291 $attrs['gosaApplicationPriority'] = $prio;
1292 $attrs['gosaApplicationParameter'] = array();
1294 if (isset($entry['FLAGS'])) {
1295 /* Check if the flags changed at all */
1296 $diff = FALSE;
1297 foreach($this->apps as $id => $app) {
1298 if($app['cn'][0] == $entry['NAME']){
1299 $orig_flags = $app['gosaApplicationFlags'][0];
1300 foreach($this->app_flags as $name => $flag) {
1301 if((strstr($orig_flags, $flag) && !strstr($entry['FLAGS'],$flag)) || !strstr($orig_flags, $flag) && strstr($entry['FLAGS'], $flag)) {
1302 $diff = TRUE;
1303 break;
1304 }
1305 }
1306 }
1307 }
1308 /* Only store appflags into LDAP if its different from the original app */
1309 if ($diff) {
1310 $attrs['gosaApplicationParameter'][] = "gosaApplicationFlags:".$entry['FLAGS'];
1311 }
1312 }
1314 foreach($entry['PARAMETER'] as $name => $value){
1315 $attrs['gosaApplicationParameter'][] = $name.":".$value;
1316 }
1317 if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1318 unset($attrs['gosaApplicationParameter']);
1319 }
1320 }
1321 break;
1322 case "FOLDER" :
1323 {
1324 $attrs['objectClass'] = array("gotoSubmenuEntry");
1325 $attrs['cn'] = $entry['NAME'];
1326 $attrs['gosaApplicationPriority'] = $prio;
1327 if($entry['STATUS'] != "ADDED"){
1328 $attrs['gosaApplicationIcon'] = array();
1329 }
1331 if(!empty($entry['ICON'])){
1332 $attrs['gosaApplicationIcon'] = $entry['ICON'];
1333 }
1334 }
1335 break;
1336 case "RELEASE" :
1337 {
1338 $attrs['ou'] = $entry['NAME'];
1339 $attrs['objectClass'] = array();
1340 $attrs['objectClass'][] = "top";
1341 $attrs['objectClass'][] = "organizationalUnit";
1342 $attrs['objectClass'][] = "FAIbranch";
1343 if(!empty($entry['FAIstate'])){
1344 $attrs['FAIstate'] = $entry['FAIstate'];
1345 }
1346 }
1347 break;
1348 }
1350 /* Append missing ObjectClasses, ... Tagging
1351 */
1352 if(isset($entry['LDAP_ATTRS'])){
1353 for($i = 0 ; $i < $entry['LDAP_ATTRS']['objectClass']['count']; $i ++){
1354 $oc = $entry['LDAP_ATTRS']['objectClass'][$i];
1355 if(!in_array($oc,$attrs['objectClass'])){
1356 $attrs['objectClass'][] = $oc;
1357 }
1358 }
1359 }
1361 /* Create an array containing all operations sorted by type. (add,remove...)
1362 */
1363 if($entry['STATUS'] == "LOADED"){
1364 continue;
1365 }
1366 if($entry['STATUS'] == "REMOVED"){
1367 if(isset($entry['DN'])){
1368 $Actions['Remove'][$entry['DN']] = $entry['DN'];
1369 }else{
1370 $Actions['Remove'][$cur_dn] = $cur_dn;
1371 }
1372 }
1373 if($entry['STATUS'] == "EDITED"){
1374 $Actions['Edit'][$cur_dn] = $attrs;
1375 }
1376 if($entry['STATUS'] == "ADDED"){
1377 $Actions['Add'][$cur_dn] = $attrs;
1378 }
1379 }
1381 /* First remove entries
1382 */
1383 $ldap = $this->config->get_ldap_link();
1384 $ldap->cd($this->config->current['BASE']);
1385 foreach($Actions['Remove'] as $dn){
1386 $ldap->cd($dn);
1387 $ldap->cat($dn);
1388 if($ldap->count()){
1389 $ldap->rmdir_recursive($dn);
1390 if (!$ldap->success()){
1391 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1392 }
1393 }
1394 }
1396 /* Add new entries
1397 */
1398 foreach($Actions['Add'] as $dn => $data){
1399 $this->tag_attrs($data,$dn,$this->gosaUnitTag);
1400 $ldap->cd($dn);
1401 $ldap->cat($dn);
1402 if(!$ldap->count()){
1403 $ldap->add($data);
1404 if (!$ldap->success()){
1405 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_ADD, get_class()));
1406 }
1407 }
1408 }
1410 /* Modify entries
1411 */
1412 foreach($Actions['Edit'] as $dn => $data){
1413 $this->tag_attrs($data,$dn,$this->gosaUnitTag);
1414 $ldap->cd($dn);
1415 $ldap->cat($dn);
1416 if($ldap->count()){
1417 $ldap->modify($data);
1418 if (!$ldap->success()){
1419 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_MOD, get_class()));
1420 }
1421 }
1422 }
1424 $this->_load_menu_structure();
1425 }
1428 /*! \brief Return plugin informations for acl handling
1429 @return Array containing all plugin ACL informations
1430 */
1431 static function plInfo()
1432 {
1433 return (array(
1434 "plShortName" => _("Applications"),
1435 "plDescription" => _("Group applications"),
1436 "plSelfModify" => FALSE,
1437 "plDepends" => array(),
1438 "plPriority" => 7,
1439 "plSection" => array("administration"),
1440 "plCategory" => array("groups"),
1441 "plProvidedAcls"=> array(
1442 "gosaMemberApplication" => _("Application"),
1443 "FAIrelease" => _("Release"),
1444 "gosaApplicationParameter" => _("Application parameter"),
1445 "placeOnDesktop" => _("Place icon on members desktop"), // D
1446 "placeOnKicker" => _("Place entry in members launch bar"), // L
1447 "placeInStartmenu" => _("Place entry in members startmenu") // M
1448 )));
1449 }
1452 /* \brief Prepare this plugin to be copied.
1453 Adapt all required attributes from the source object.
1454 In this case, update the menu structure too, mark all elements
1455 as newly added, so they will be saved in save();
1456 */
1457 function PrepareForCopyPaste($source)
1458 {
1459 plugin::PrepareForCopyPaste($source);
1461 $tmp = new appgroup($this->config,$source['dn']);
1462 $this->is_account = TRUE;
1463 $this->a_Structure = $tmp->a_Structure;
1464 $all = $this->_get_all_entries();
1465 foreach($all as &$entry){
1466 if(isset($entry['STATUS'])){
1467 $entry['STATUS'] = "ADDED";
1468 }
1469 }
1470 }
1473 /*! \brief Save HTML posts in multiple edit mode
1474 */
1475 function multiple_save_object()
1476 {
1477 if(isset($_POST['group_apps_multi'])){
1478 $this->save_object();
1479 plugin::multiple_save_object();
1481 /* Get posts */
1482 foreach(array("apps") as $attr){
1483 if(isset($_POST['use_'.$attr])) {
1484 $this->multi_boxes[] = $attr;
1485 }
1486 }
1487 }
1488 }
1491 /*! \brief Return values used in multiple edit mode.
1492 Some values can be modified for multiple
1493 groups at the same time.
1494 @return Array All values that support multiple edit.
1495 */
1496 function get_multi_edit_values()
1497 {
1498 $ret = plugin::get_multi_edit_values();
1500 if(in_array("apps",$this->multi_boxes)){
1501 $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1502 $ret['Categories'] = $this->Categories;
1503 $ret['gosaMemberApplication'] = $this->gosaMemberApplication;
1504 $ret['FAIrelease'] = $this->FAIrelease;
1505 $ret['appoption'] = $this->appoption;
1506 }
1507 return($ret);
1508 }
1509 }
1510 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1511 ?>