0877b855fb5dfb6b1851057bc14c5e3080792bd3
1 <?php
2 class appgroup extends plugin
3 {
4 /* CLI vars */
5 var $cli_summary= "Manage application groups";
6 var $cli_description= "Some longer text\nfor help";
7 var $cli_parameters= array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
10 var $config;
11 var $curbase;
13 /* Contains the menu structure in an array.
14 */
15 var $a_Structure= array();
16 var $a_Structure_on_load = array();
17 var $Releases;
18 var $FAIrelease = 0;
19 var $apps = array();
20 var $_cache = array();
22 var $app_parameter = array();
23 var $edit_entry = array();
24 var $enableReleaseManagement = FALSE;
27 public function __construct(&$config, $dn= NULL, $parent= NULL)
28 {
29 plugin::plugin($config,$dn,$parent);
30 $this->dn = $dn;
31 $this->_load_menu_structure();
32 $this->a_Structure_on_load = $this->a_Structure;
34 /* Check if we have relase mangement enabled and prepare group application for release management */
35 $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
36 if(!empty($tmp)){
37 $this->enableReleaseManagement = true;
38 }
40 $this->Releases = $this->getReleases();
41 $this->FAIrelease = "/";
42 $this->curbase = $this->config->current['BASE'];
43 $this->reload();
45 $this->is_account = FALSE;
46 if(count($this->_get_all_entries()) > 1){
47 $this->is_account= TRUE;
48 }
49 $this->initially_was_account = $this->is_account;
50 }
53 /*! \brief Reload the list of applications for the currently selected release
54 */
55 function reload()
56 {
57 $ret = array();
58 $release_info = $this->Releases[$this->FAIrelease];
60 if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
62 $ldap = $this->config->get_ldap_link();
63 $ldap->cd($this->config->current['BASE']);
64 $ldap->search("ou=apps",array("dn"));
65 $app_deps = array();
66 while($attrs = $ldap->fetch()){
67 $app_deps[] = $attrs['dn'];
68 }
70 foreach($app_deps as $dep){
71 $ldap->cd($dep);
72 $ldap->search("objectClass=FAIbranch",array("dn"));
73 while($attrs = $ldap->fetch()){
74 $app_deps[] = $attrs['dn'];
75 }
76 }
78 foreach($app_deps as $dep){
79 if(preg_match("/^".normalizePreg($release_info['suffix'])."/",$dep)){
80 $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
81 }
82 }
83 $this->_cache['ReleaseApps'][$release_info['suffix']] = $ret;
84 }
85 $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
86 }
91 /*! \brief generate a list of available releases
92 @return return an array with all available releases.
93 */
94 function getReleases()
95 {
96 $ret =array("/" => array("name" => "/" , "parts" => array(),"suffix" => get_ou('applicationou')));
97 if($this->enableReleaseManagement){
99 /* Only display those releases that we are able to read */
100 $dn = $this->config->current['BASE'];
101 $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
102 $res = get_list($filter,"application", $dn, array("ou","FAIstate"), GL_SUBSEARCH);
104 foreach($res as $attrs){
105 if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
106 $bb = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
107 $parts = array_reverse(split("ou=",$bb));
109 $str ="";
110 foreach($parts as $key => $part){
111 if(empty($part)) {
112 unset($parts[$key]);
113 continue;
114 }
115 $part = str_replace(",","",$part);
116 $str .= $part."/";
117 $parts[$key] = $part;
118 }
119 $name = preg_replace("/\/$/","",$str);
120 if(empty($name)) {
121 $name ="/";
122 }
123 $FAIstate = "";
124 if(isset($attrs['FAIstate'])){
125 $FAIstate = $attrs['FAIstate'][0];
126 }
128 $ret[$name] = array("name" => $name,
129 "FAIstate" => $FAIstate,
130 "dn" => $attrs['dn'],
131 "parts" => $parts,"suffix" => $bb.get_ou('applicationou'));
132 }
133 }
134 }
135 ksort($ret);
136 return($ret);
137 }
140 /*! \brief Load the menu structure from ldap and create a multi dimensional array
141 */
142 function _load_menu_structure()
143 {
144 $this->a_Structure = array();
145 $ldap = $this->config->get_ldap_link();
146 $ldap->cd($this->dn);
147 $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
149 $base = array();
150 $base['UNIQID'] = uniqid();
151 $base['PARENT'] = 0;
152 $base['NAME'] = "";
153 $base['TYPE'] = "BASE";
154 $base['ENTRIES']= array();
155 $base['STATUS'] = "LOADED";
157 $this->a_Structure[0] = $base;
159 while($attrs = $ldap->fetch()){
160 $cur = &$this->a_Structure[0]['ENTRIES'];
161 $parent_id = $base['UNIQID'];
162 $sub_dn = preg_replace("/,".normalizePreg($this->dn)."$/","",$attrs['dn']);
163 $sub_dn_array = split("\,",$sub_dn);
166 for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
167 $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
168 if($i > 0){
169 foreach($cur as $key => $entry){
170 if($entry['NAME'] == $name){
171 $cur = &$cur[$key]['ENTRIES'];
172 $parent_id = $entry['UNIQID'];
173 }
174 }
175 }else{
177 $priority = 1;
178 if(isset($attrs['gosaApplicationPriority'])){
179 $priority= $attrs['gosaApplicationPriority'][0];
180 }
181 while(isset($cur[$priority])){
182 $priority ++;
183 }
185 $data = array();
186 if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
187 $type = "FOLDER";
189 $data['ICON'] = "";
190 if(isset($attrs['gosaApplicationIcon'])){
191 $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
192 }
194 }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
195 $type = "ENTRY";
196 $data['INFO'] = "";
197 $data['PARAMETER'] = array();
198 if(isset($attrs['gosaApplicationParameter'])){
199 for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
200 $tmp = split(":",$attrs['gosaApplicationParameter'][$p]);
201 $data['PARAMETER'][$tmp[0]] = $tmp[1];
202 }
203 }
204 }elseif(in_array("FAIbranch",$attrs['objectClass'])){
206 $type = "RELEASE";
207 if(isset($attrs['FAIstate'][0])){
208 $data['FAIstate'] = $attrs['FAIstate'][0];
209 }else{
210 $data['FAIstate'] = "";
211 }
212 }
214 $data['DN'] = $attrs['dn'];
215 $data['NAME'] = $name;
216 $data['TYPE'] = $type;
217 $data['PRIORITY'] = $priority;
218 $data['ENTRIES'] = array();
219 $data['UNIQID'] = uniqid();
220 $data['PARENT'] = $parent_id;
221 $data['STATUS'] = "LOADED";
222 $cur[$priority] = $data;
223 ksort($cur);
224 }
225 }
226 }
227 }
230 function execute()
231 {
232 /* Call parent execute */
233 plugin::execute();
235 if (isset($_POST['modify_state'])){
236 $this->is_account = !$this->is_account;
237 }
239 /* Do we represent a valid account? */
240 if (!$this->is_account){
241 $display= $this->show_enable_header(_("Add application extension"),
242 _("Application extension disabled. You can enable it by clicking below."));
243 return ($display);
244 }
246 $display = $this->show_enable_header(_("Remove application extension"),
247 _("Application extension enabled. You can disable it by clicking below."));
250 if(isset($_GET['send'])){
251 $id = $_GET['send'];
252 $all = $this->_get_all_entries();
253 if(isset($all[$id])){
254 send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
255 exit;
256 }
257 }
259 if(isset($_GET['r']))
260 $this->__construct($this->config,$this->dn);
262 if(count($this->edit_entry)){
263 if($this->edit_entry['TYPE'] == "ENTRY"){
264 $smarty = get_smarty();
265 $smarty->assign("type", "ENTRY");
266 $smarty->assign("entry",$this->edit_entry);
267 $smarty->assign("paras",$this->app_parameter);
268 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
269 return($display);
270 }
271 if($this->edit_entry['TYPE'] == "FOLDER"){
272 $smarty = get_smarty();
274 session::set("binarytype" , "image/jpeg");
275 session::set("binary" , $this->edit_entry['ICON']);
277 $smarty->assign("rand", microtime(TRUE));
278 $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0);
279 $smarty->assign("type", "FOLDER");
280 $smarty->assign("entry",$this->edit_entry);
281 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
282 return($display);
283 }
284 }
286 $smarty = get_smarty();
287 $smarty->assign("plug_id" , $_GET['plug']);
289 /* Create application list */
290 $div = new divSelectBox("appgroup");
291 $div->SetHeight(300);
292 $departments = array();
293 $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
294 foreach($res as $value){
295 $fdn = $value['dn'];
296 $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
297 $fdn= @LDAP::fix($fdn);
298 if($value["description"][0]!=".."){
299 $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
300 }else{
301 $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
302 }
303 }
305 $linkopen = "<a href='?plug=".$_GET['plug']."&act=depopen&depid=%s'>%s</a>";
307 /* Create base back entry */
308 $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
309 if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
310 $div->AddEntry(array(
311 array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
312 "attach"=>"style='border:0px;'")
313 ));
314 }
316 /* Append departments for current base */
317 foreach($departments as $key => $app){
318 $div->AddEntry(array(
319 array("string"=>"<img class='center' src='images/folder.png' alt='"._("department")."'> ".sprintf($linkopen,
320 base64_encode($key),$app),
321 "attach"=>"style='border:0px;'")
322 ));
323 }
326 /* Add applications found on this base */
327 $used_apps = $this->_get_used_entry_name();
328 foreach($this->apps as $key => $app){
329 if(in_array($app['cn'][0],$used_apps)){
330 continue;
331 }
332 if(!preg_match("/".get_ou('applicationou').normalizePreg($this->curbase)."$/",$app['dn'])){
333 continue;
334 }
336 $name = $app['cn'][0];
337 if(isset($app['description'])){
338 $name .= " [".$app['description'][0]."]";
339 }
340 $div->AddEntry(array(
341 array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
342 "<img class='center' src='images/select_application.png' alt='"._("application")."'> ".$name,
343 "attach"=>"style='border:0px;'")
344 ));
345 }
348 $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
349 $smarty->assign("FAIrelease",$this->FAIrelease);
350 $smarty->assign("app_list",$div->DrawList());
351 $smarty->assign("releases",$this->Releases);
352 $smarty->assign("folders" , $this->_get_folder_names());
353 $entries = $this->_get_entries_for_release($this->FAIrelease);
354 $smarty->assign("entries",$entries);
355 $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
356 return($display);
357 }
360 /*! \brief Returns all used folder names
361 @return Array All used folder names.
362 */
363 function _get_folder_names()
364 {
365 $data = $this->_get_entries_for_release($this->FAIrelease);
366 $ret = array("BASE" => ".");
367 foreach($data as $entry){
368 if($entry['TYPE'] == "FOLDER"){
369 $ret[$entry['UNIQID']] = $entry['NAME'];
370 }
371 }
372 return($ret);
373 }
376 /*! \brief return all used applications
377 @return Array All used applications.
378 */
379 function _get_used_entry_name()
380 {
381 $data = $this->_get_entries_for_release($this->FAIrelease);
382 $ret = array();
383 foreach($data as $entry){
384 if($entry['TYPE'] == "ENTRY"){
385 $ret[] = $entry['NAME'];
386 }
387 }
388 return($ret);
389 }
392 /*! \brief Returns all folder an entries for the selected release
393 @return Array Returns the complete menu structure for the given array.
394 */
395 function _get_entries_for_release($release,$cur = NULL)
396 {
397 $all = $this->_get_all_entries();
398 $key = $this->_get_release_key($release);
399 if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
400 $res = $this->_get_all_entries(TRUE,TRUE,&$all[$key]['ENTRIES']);
401 return($res);
402 }
403 return(array());
404 }
407 /*! \brief Save the currently edited entry */
408 function _save_entry_edit()
409 {
410 $all = $this->_get_all_entries();
411 $entry = $this->edit_entry;
412 $r_entry= &$all[$entry['UNIQID']];
414 if($entry['TYPE'] == "ENTRY"){
415 $r_entry['PARAMETER'] = $this->app_parameter;
416 $r_entry['STATUS'] = "EDITED";
417 }
418 if($entry['TYPE'] == "FOLDER"){
419 $r_entry['ICON'] = $this->edit_entry['ICON'];
420 $r_entry['STATUS'] = "EDITED";
421 }
422 $this->dialog = FALSE;
423 $this->edit_entry = array();
424 }
427 /*! \brief prepare the entry with the given ID, to be edited.
428 */
429 function _edit_entry_edit($id)
430 {
431 $all = $this->_get_all_entries();
432 $entry = $all[$id];
434 $this->app_parameter = array();
435 if($entry['TYPE'] == "ENTRY"){
436 $found = FALSE;
437 foreach($this->apps as $id => $app){
439 if($app['cn'][0] == $entry['NAME']){
440 $found = TRUE;
441 break;
442 }
443 }
444 if($found){
446 /* Create a list of editable parameter */
447 if(isset($app['gosaApplicationParameter'])){
448 for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
449 $para = $app['gosaApplicationParameter'][$i];
450 $tmp = split(":",$para);
451 $this->app_parameter[$tmp[0]] = $tmp[1];
452 }
453 }
455 /* Overwrite parameters with entry parameters */
456 foreach($entry['PARAMETER'] as $name => $value){
457 $this->app_parameter[$name] = $value;
458 }
460 $this->dialog = TRUE;
461 $this->edit_entry = $entry;
462 }
463 }
465 if($entry['TYPE'] == "FOLDER"){
466 $this->dialog = TRUE;
467 $this->edit_entry = $entry;
468 }
469 }
472 function remove_from_parent()
473 {
474 $ldap = $this->config->get_ldap_link();
475 $ldap->cd($this->dn);
476 $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
477 $a_remove = array();
478 while($attrs = $ldap->fetch()){
479 $a_remove[] = $attrs['dn'];
480 }
481 foreach($a_remove as $remove){
482 $ldap->rmdir_recursive($remove);
483 show_ldap_error($ldap->get_error(),
484 sprintf(_("Removing of group/application account with dn '%s' failed, could not remove '%s'."),
485 $this->dn,$remove));
486 }
487 $this->_load_menu_structure();
488 }
491 function check()
492 {
493 }
496 /*! \brief Create missing releases, if there is a release selected \
497 that is currently not part of the menu structure \
498 then create this entry
499 */
500 function _check_missing_release($release)
501 {
502 $release_info = $this->Releases[$release];
504 $parent_id = $this->a_Structure[0]['UNIQID'];
505 $cur = &$this->a_Structure[0]['ENTRIES'];
506 for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
507 $part = $release_info['parts'][$i];
508 $found = FALSE;
509 foreach($cur as $key => $name){
510 if($name['NAME'] == $part){
511 $parent_id = $cur[$key]['UNIQID'];
512 $cur = &$cur[$key]['ENTRIES'];
514 $found =TRUE;
515 break;
516 }
517 }
518 if(!$found){
519 $release = array();
520 $release['UNIQID'] = uniqid();
521 $release['PARENT'] = $parent_id;
522 $release['NAME'] = $part;
523 $release['TYPE'] = "RELEASE";
524 $release['ENTRIES']= array();
525 $release['STATUS'] = "ADDED";
526 $release['FAIstate'] = $release_info['FAIstate'];
527 $cur[] = $release;
528 $i --;
529 }
530 }
531 }
535 function _move_entry($id,$dir)
536 {
537 $all = $this->_get_all_entries();
538 if($dir == "down"){
539 $to = $this->_get_next($id);
540 }
541 if($dir == "up"){
542 $to = $this->_get_last($id);
543 }
545 if(!$to){
546 return;
547 }
549 $o_to = $all[$to];
550 $o_from = $all[$id];
552 if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
553 $to = $this->_get_next($to,$o_from['PARENT']);
554 $o_to = $all[$to];
555 }
558 /* Target is ENTRY && same BASE, just switch */
559 if($o_to['PARENT'] == $o_from['PARENT'] ){
560 $parent = $all[$o_to['PARENT']];
561 $pos = 0;
562 foreach($parent['ENTRIES'] as $entry){
563 $pos ++;
564 if($entry['UNIQID'] == $to){
565 break;
566 }
567 }
568 if($dir == "up" && $pos > 0){
569 $pos --;
570 }
571 $this->_add_entry($parent['UNIQID'],$o_from,$pos);
572 $this->_remove_entry_id($id);
573 return(TRUE);
574 }
575 return(FALSE);
576 }
580 function _get_last($id)
581 {
582 $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
583 for($i = 0 ; $i < count($all_l) ; $i ++){
584 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
585 $i++;
586 break;
587 }
588 }
589 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
590 $i++;
591 }
593 if(!isset($all_l[$i])){
594 return(FALSE);
595 }
597 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
598 return($all_l[$i]['PARENT']);
599 }
601 return($all_l[$i]['UNIQID']);
602 }
605 function _get_next($id,$parent = 0)
606 {
607 $all_l = $this->_get_entries_for_release($this->FAIrelease);
608 for($i = 0 ; $i < count($all_l) ; $i ++){
609 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
610 $i++;
611 break;
612 }
613 }
614 if($parent != 0){
615 while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
616 $i++;
617 }
618 }else{
619 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
620 $i++;
621 }
622 }
623 if(!isset($all_l[$i])){
624 return(FALSE);
625 }
626 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
627 return($all_l[$i]['PARENT']);
628 }
629 return($all_l[$i]['UNIQID']);
630 }
635 /* !\brief Handle ui POSTS, like sort up/down/delete
636 */
637 function save_object()
638 {
639 foreach($_POST as $name => $value){
640 if(preg_match("/del_/",$name)){
641 $id = preg_replace("/^del_/","",$name);
642 $id = preg_replace("/_(x|y)$/","",$id);
643 $this->_remove_entry_id($id);
644 break;
645 }
646 if(preg_match("/app_entry_edit/",$name)){
647 $id = preg_replace("/^app_entry_edit/","",$name);
648 $id = preg_replace("/_(x|y)$/","",$id);
649 $this->_edit_entry_edit($id);
650 break;
651 }
652 if(preg_match("/up_/",$name)){
653 $id = preg_replace("/^up_/","",$name);
654 $id = preg_replace("/_(x|y)$/","",$id);
655 $this->_move_entry($id,"up");
656 break;
657 }
658 if(preg_match("/down_/",$name)){
659 $id = preg_replace("/^down_/","",$name);
660 $id = preg_replace("/_(x|y)$/","",$id);
661 $this->_move_entry($id,"down");
662 break;
663 }
664 if(preg_match("/^parameter_/",$name) &&
665 count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
666 $name = preg_replace("/^parameter_/","",$name);
667 $this->app_parameter[$name] = $value;
668 }
669 }
670 if(isset($_POST['FAIrelease'])){
671 $this->FAIrelease = $_POST['FAIrelease'];
672 $this->_check_missing_release($this->FAIrelease);
673 }
674 if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
675 $this->curbase = base64_decode($_GET['depid']);
676 }
677 if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
678 $folder = $_POST['folder'];
679 foreach($_POST as $name => $value){
680 if(preg_match("/^AddApp_[0-9]*$/",$name)){
681 $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));
682 }
683 }
684 }
685 if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
686 $folder = $_POST['menu_folder'];
687 $name = $_POST['menu_folder_name'];
688 if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
689 $this->_add_sub_folder($folder,$name);
690 }
691 }
692 if(isset($_POST['app_entry_save'])){
693 $this->_save_entry_edit();
694 }
696 if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
697 if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
698 $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
699 }
700 }
702 if(isset($_POST['edit_reset_image'])){
703 $this->edit_entry['ICON'] = "";
704 }
706 if(isset($_POST['app_entry_cancel'])){
707 $this->edit_entry = array();
708 $this->dialog = FALSE;
709 }
710 $this->reload();
711 }
714 /*! \brief Returns the UNIQID of the currently selected release
715 */
716 function _get_release_key($release,$add_if_missing = FALSE)
717 {
718 $release_info = $this->Releases[$release];
720 if($release_info['name'] == "/"){
721 return($this->a_Structure['0']['UNIQID']);
722 }
724 $cur = &$this->a_Structure[0]['ENTRIES'];
725 $s_key = "";
726 $found = FALSE;
727 foreach($release_info['parts'] as $name){
728 foreach($cur as $key => $obj){
729 if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
730 $s_key = $cur[$key]['UNIQID'];
731 $cur = &$cur[$key]['ENTRIES'];
732 $found = TRUE;
733 break;
734 }
735 $found = FALSE;
736 }
737 }
738 if($found){
739 return($s_key);
740 }
741 return(FALSE);
742 }
745 /*! \brief Add a new folder folder to the specified folder id
746 @param String $folder The folder id in where we want to add the new folder.
747 @param String $name The name of the new folder.
748 */
749 function _add_sub_folder($folder,$name)
750 {
751 $all = $this->_get_all_entries();
752 if($folder == "BASE"){
753 $folder = $this->_get_release_key($this->FAIrelease,TRUE);
754 }
756 if(isset($all[$folder])){
757 $a_folder = array();
758 $a_folder['STATUS'] = "ADDED";
759 $a_folder['NAME'] = $name;
760 $a_folder['UNIQID'] = uniqid();
761 $a_folder['ENTRIES']= array();
762 $a_folder['PARENT'] = $folder;
763 $a_folder['TYPE'] = "FOLDER";
764 $a_folder['ICON'] = "";
765 $all[$folder]['ENTRIES'][] = $a_folder;
766 }
767 }
770 /* !\brief Remove the given id from the menu structure.
771 @param String ID to of the entry we want to remove.
772 @return Boolean TRUE on success
773 */
774 function _remove_entry_id($id)
775 {
776 $all = $this->_get_all_entries();
777 if(isset($all[$id])){
778 $all[$id]['STATUS'] = "REMOVED";
779 return(TRUE);
780 }
781 return(FALSE);
782 }
785 /* !\brief Remove the given id from the menu structure.
786 @param String ID to of the entry we want to remove.
787 @return Boolean TRUE on success
788 */
789 function _add_entry($folder_id,$entry,$pos = 0)
790 {
791 $all = $this->_get_all_entries();
793 /* Do not add removed */
794 if($entry['STATUS'] == "REMOVED"){
795 return;
796 }
798 if(isset($all[$folder_id])){
800 $folder = &$all[$folder_id];
801 $entries = $entry['ENTRIES'];
803 $entry['UNIQID'] = uniqid();
804 $entry['PARENT'] = $folder_id;
805 $entry['ENTRIES']= array();
806 $entry['STATUS'] = "ADDED";
808 $cnt = 0;
809 $new = array();
810 $added =FALSE;
811 foreach($folder['ENTRIES'] as $key => $obj){
812 if($obj['STATUS'] == "LOADED"){
813 $obj['STATUS'] = "EDITED";
814 }
815 if($pos == $cnt){
816 $new[] = $entry;
817 $added = TRUE;
818 }
819 $cnt ++;
820 $new[] = $obj;
821 }
822 if(!$added){
823 $new[] = $entry;
824 }
826 $all[$folder_id]['ENTRIES'] = $new;
827 foreach($entries as $sub){
828 $this->_add_entry($entry['UNIQID'],$sub,-1);
829 }
830 return(TRUE);
831 }
832 return(FALSE);
833 }
836 /*! \brief Add the application identified by $app_id to folder $folder_id
837 @param String folder_id The UNIQID of the folder where we want to add the new folder.
838 @param Integer app_id The ID of the application which should be added.
839 */
840 function _add_app_id($folder_id,$app_id)
841 {
842 $all = $this->_get_all_entries();
843 if($folder_id == "BASE"){
844 $folder_id = $this->_get_release_key($this->FAIrelease);
845 }
846 if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
848 $new = array();
849 $new['TYPE'] = "ENTRY";
850 $new['NAME'] = $this->apps[$app_id]['cn'][0];
851 $new['UNIQID']= uniqid();
852 $new['PARENT']= $folder_id;
853 $new['PARAMETER']= array();
854 if(isset($this->apps[$app_id]['description'][0])){
855 $new['INFO'] = $this->apps[$app_id]['description'][0];
856 }else{
857 $new['INFO'] = "";
858 }
859 $new['STATUS']= "ADDED";
860 $all[$folder_id]['ENTRIES'][] = $new;
861 }
862 }
865 /*! \brief Return all entries linear.
866 @param Boolean $add_tags If TRUE, OPEN/CLOSE Tags will be appended.
867 @param &Array Start here, Pointer to an array.
868 */
869 function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, $cur = NULL)
870 {
871 $ret = array();
872 if($cur == NULL){
873 $cur = &$this->a_Structure;
874 }
875 foreach($cur as $key => $entry){
877 if($skip_release && $entry['TYPE'] == "RELEASE"){
878 continue;
879 }
880 if($entry['TYPE'] == "ENTRY"){
881 $found = FALSE;
882 foreach($this->apps as $app){
883 if($app['cn'][0] == $entry['NAME']){
884 $found = TRUE;
885 if(isset($app['description'][0])){
886 $entry['INFO'] = "[".$app['description'][0]."]";
887 }
888 break;
889 }
890 }
891 if(!$found){
892 $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
893 }
894 }
897 $tmp = $entry;
898 if(!$add_tags){
899 $ret[$tmp['UNIQID']] = &$cur[$key];
900 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
901 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
902 }
903 }else{
905 if(isset($tmp['ENTRIES'])){
906 unset($tmp['ENTRIES']);
907 }
908 if($tmp['STATUS'] != "REMOVED"){
909 $ret[] = $tmp;
910 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
911 $add = false;
912 foreach($entry['ENTRIES'] as $entry){
913 if($entry['STATUS'] != "REMOVED"){
914 $add = TRUE;
915 break;
916 }
917 }
919 if($add){
920 $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
921 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
922 $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
923 }
924 }
925 }
926 }
927 }
928 return($ret);
929 }
932 function save()
933 {
934 $ldap = $this->config->get_ldap_link();
935 $all = $this->_get_all_entries();
936 $prio = 0;
937 $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
939 foreach($all as $entry){
940 $prio ++;
941 $cur = $entry;
942 $dn = "";
944 do{
945 if($cur['TYPE'] == "ENTRY"){
946 $dn.= "cn=".$cur['NAME'].",";
947 }elseif($cur['TYPE'] == "FOLDER"){
948 $dn.= "cn=".$cur['NAME'].",";
949 }elseif($cur['TYPE'] == "RELEASE"){
950 $dn.= "ou=".$cur['NAME'].",";
951 }elseif($cur['TYPE'] == "BASE"){
952 }
953 if(!isset($all[$cur['PARENT']])){
954 $cur = NULL;
955 }else{
956 $cur = $all[$cur['PARENT']];
957 }
958 }while(is_array($cur));
960 $cur_dn = $dn.$this->dn;
962 $attrs = array();
963 switch($entry['TYPE']){
964 case "ENTRY" :
965 {
966 $attrs['objectClass'] = "gotoMenuEntry";
967 $attrs['cn'] = $entry['NAME'];
968 $attrs['gosaApplicationPriority'] = $prio;
969 $attrs['gosaApplicationParameter'] = array();
972 foreach($entry['PARAMETER'] as $name => $value){
973 $attrs['gosaApplicationParameter'][] = $name.":".$value;
974 }
975 if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
976 unset($attrs['gosaApplicationParameter']);
977 }
978 }
979 break;
980 case "FOLDER" :
981 {
982 $attrs['objectClass'] = "gotoSubmenuEntry";
983 $attrs['cn'] = $entry['NAME'];
984 $attrs['gosaApplicationPriority'] = $prio;
985 if($entry['STATUS'] != "ADDED"){
986 $attrs['gosaApplicationIcon'] = array();
987 }
989 if(!empty($entry['ICON'])){
990 $attrs['gosaApplicationIcon'] = $entry['ICON'];
991 }
992 }
993 break;
994 case "RELEASE" :
995 {
996 $attrs['ou'] = $entry['NAME'];
997 $attrs['objectClass'] = array();
998 $attrs['objectClass'][] = "top";
999 $attrs['objectClass'][] = "organizationalUnit";
1000 $attrs['objectClass'][] = "FAIbranch";
1001 if(!empty($entry['FAIstate'])){
1002 $attrs['FAIstate'] = $entry['FAIstate'];
1003 }
1004 }
1005 break;
1006 }
1008 if($entry['STATUS'] == "LOADED"){
1009 continue;
1010 }
1011 if($entry['STATUS'] == "REMOVED"){
1012 $Actions['Remove'][$cur_dn] = $cur_dn;
1013 }
1014 if($entry['STATUS'] == "EDITED"){
1015 $Actions['Edit'][$cur_dn] = $attrs;
1016 }
1017 if($entry['STATUS'] == "ADDED"){
1018 $Actions['Add'][$cur_dn] = $attrs;
1019 }
1020 }
1022 $ldap = $this->config->get_ldap_link();
1023 $ldap->cd($this->config->current['BASE']);
1024 foreach($Actions['Remove'] as $dn){
1025 $ldap->cd($dn);
1026 $ldap->cat($dn);
1027 if($ldap->count()){
1028 $ldap->rmdir_recursive($dn);
1029 show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1030 }
1031 }
1032 foreach($Actions['Add'] as $dn => $data){
1033 $ldap->cd($dn);
1034 $ldap->cat($dn);
1035 if(!$ldap->count()){
1036 $ldap->add($data);
1037 show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1038 }
1039 }
1040 foreach($Actions['Edit'] as $dn => $data){
1041 $ldap->cd($dn);
1042 $ldap->cat($dn);
1043 if($ldap->count()){
1044 $ldap->modify($data);
1045 show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1046 }
1047 }
1048 $this->_load_menu_structure();
1049 }
1052 /* Return plugin informations for acl handling */
1053 static function plInfo()
1054 {
1055 return (array(
1056 "plShortName" => _("Applications"),
1057 "plDescription" => _("Group applications"),
1058 "plSelfModify" => FALSE,
1059 "plDepends" => array(),
1060 "plPriority" => 0,
1061 "plSection" => array("admin"),
1062 "plCategory" => array("groups"),
1063 "plProvidedAcls"=> array(
1064 "gosaMemberApplication" => _("Application"),
1065 "FAIrelease" => _("Release"),
1066 "gosaApplicationParameter" => _("Application parameter"))
1067 ));
1068 }
1071 function PrepareForCopyPaste($source)
1072 {
1073 }
1076 function multiple_save_object()
1077 {
1078 if(isset($_POST['group_apps_multi'])){
1079 $this->save_object();
1080 plugin::multiple_save_object();
1082 /* Get posts */
1083 foreach(array("apps") as $attr){
1084 if(isset($_POST['use_'.$attr])) {
1085 $this->multi_boxes[] = $attr;
1086 }
1087 }
1088 }
1089 }
1092 function get_multi_edit_values()
1093 {
1094 $ret = plugin::get_multi_edit_values();
1096 if(in_array("apps",$this->multi_boxes)){
1097 $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1098 $ret['Categories'] = $this->Categories;
1099 $ret['gosaMemberApplication'] = $this->gosaMemberApplication;
1100 $ret['FAIrelease'] = $this->FAIrelease;
1101 $ret['appoption'] = $this->appoption;
1102 }
1103 return($ret);
1104 }
1105 }
1106 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1107 ?>