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 }
84 $tmp = array();
85 foreach($ret as $key => $app){
86 $tmp[$key] = $app['cn'][0];
87 }
88 natcasesort($tmp);
89 $res = array();
90 foreach($tmp as $key => $app){
91 $res[] = $ret[$key];
92 }
94 $this->_cache['ReleaseApps'][$release_info['suffix']] = $res;
95 }
96 $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
97 }
102 /*! \brief generate a list of available releases
103 @return return an array with all available releases.
104 */
105 function getReleases()
106 {
107 $ret =array("/" => array("name" => "/", "found" => TRUE , "parts" => array(),"suffix" => get_ou('applicationou')));
108 if($this->enableReleaseManagement){
110 /* Only display those releases that we are able to read */
111 $dn = $this->config->current['BASE'];
112 $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
113 $res = get_sub_list($filter,array("application","fai"), array(get_ou("applicationou"),get_ou("faiou")),$dn, array("ou","FAIstate"), GL_SUBSEARCH);
116 foreach($res as $attrs){
117 if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
118 $bb = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
119 $parts = array_reverse(split("ou=",$bb));
121 $str ="";
122 foreach($parts as $key => $part){
123 if(empty($part)) {
124 unset($parts[$key]);
125 continue;
126 }
127 $part = str_replace(",","",$part);
128 $str .= $part."/";
129 $parts[$key] = $part;
130 }
131 $name = preg_replace("/\/$/","",$str);
132 if(empty($name)) {
133 $name ="/";
134 }
135 $FAIstate = "";
136 if(isset($attrs['FAIstate'])){
137 $FAIstate = $attrs['FAIstate'][0];
138 }
140 $all = $this->_get_all_entries();
141 $found = FALSE;
142 foreach($all as $entry){
143 if(isset($entry['DN']) && preg_match("/^".normalizePreg($bb)."/",$entry['DN'])){
144 $found =TRUE;
145 break;
146 }
147 }
149 $cnt = 0;
150 $ret[$name] = array("name" => $name,
151 "found" => $found,
152 "FAIstate" => $FAIstate,
153 "dn" => $attrs['dn'],
154 "parts" => $parts,"suffix" => $bb.get_ou('applicationou'));
155 }
156 }
157 }
158 ksort($ret);
159 return($ret);
160 }
163 /*! \brief Load the menu structure from ldap and create a multi dimensional array
164 */
165 function _load_menu_structure()
166 {
167 $this->a_Structure = array();
168 $ldap = $this->config->get_ldap_link();
169 $ldap->cd($this->dn);
170 $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
172 $base = array();
173 $base['UNIQID'] = uniqid();
174 $base['PARENT'] = 0;
175 $base['NAME'] = "";
176 $base['TYPE'] = "BASE";
177 $base['ENTRIES']= array();
178 $base['STATUS'] = "LOADED";
180 $this->a_Structure[0] = $base;
182 while($attrs = $ldap->fetch()){
183 $cur = &$this->a_Structure[0]['ENTRIES'];
184 $parent_id = $base['UNIQID'];
185 $sub_dn = preg_replace("/,".normalizePreg($this->dn)."$/","",$attrs['dn']);
186 $sub_dn_array = split("\,",$sub_dn);
188 $found = true;
189 for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
190 $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
192 if($i > 0){
193 $found =FALSE;
194 foreach($cur as $key => $entry){
195 if($entry['NAME'] == $name){
196 $cur = &$cur[$key]['ENTRIES'];
197 $parent_id = $entry['UNIQID'];
198 $found =true;
199 break;
200 }
201 }
202 }else{
204 if(!$found){
205 break;
206 }
207 $priority = 1;
208 if(isset($attrs['gosaApplicationPriority'])){
209 $priority= $attrs['gosaApplicationPriority'][0];
210 }
211 while(isset($cur[$priority])){
212 $priority ++;
213 }
215 $data = array();
216 if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
217 $type = "FOLDER";
219 $data['ICON'] = "";
220 if(isset($attrs['gosaApplicationIcon'])){
221 $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
222 }
224 }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
225 $type = "ENTRY";
226 $data['INFO'] = "";
227 $data['PARAMETER'] = array();
228 if(isset($attrs['gosaApplicationParameter'])){
229 for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
230 $tmp = split(":",$attrs['gosaApplicationParameter'][$p]);
231 $data['PARAMETER'][$tmp[0]] = $tmp[1];
232 }
233 }
234 }elseif(in_array("FAIbranch",$attrs['objectClass'])){
236 $type = "RELEASE";
237 if(isset($attrs['FAIstate'][0])){
238 $data['FAIstate'] = $attrs['FAIstate'][0];
239 }else{
240 $data['FAIstate'] = "";
241 }
242 }
244 $data['DN'] = $attrs['dn'];
245 $data['NAME'] = $name;
246 $data['TYPE'] = $type;
247 $data['PRIORITY'] = $priority;
248 $data['ENTRIES'] = array();
249 $data['UNIQID'] = uniqid();
250 $data['PARENT'] = $parent_id;
251 $data['STATUS'] = "LOADED";
252 $cur[$priority] = $data;
253 ksort($cur);
254 }
255 }
256 }
257 }
260 function execute()
261 {
262 /* Call parent execute */
263 plugin::execute();
265 if (isset($_POST['modify_state'])){
266 $this->is_account = !$this->is_account;
267 }
269 /* Do we represent a valid account? */
270 if (!$this->is_account){
271 $display= $this->show_enable_header(_("Add application extension"),
272 _("Application extension disabled. You can enable it by clicking below."));
273 return ($display);
274 }
276 $display = $this->show_enable_header(_("Remove application extension"),
277 _("Application extension enabled. You can disable it by clicking below."));
280 if(isset($_GET['send'])){
281 $id = $_GET['send'];
282 $all = $this->_get_all_entries();
283 if(isset($all[$id])){
284 send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
285 exit;
286 }
287 }
289 if(isset($_GET['r']))
290 $this->__construct($this->config,$this->dn);
292 if(count($this->edit_entry)){
293 if($this->edit_entry['TYPE'] == "ENTRY"){
294 $smarty = get_smarty();
295 $smarty->assign("type", "ENTRY");
296 $smarty->assign("entry",$this->edit_entry);
297 $smarty->assign("paras",$this->app_parameter);
298 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
299 return($display);
300 }
301 if($this->edit_entry['TYPE'] == "FOLDER"){
302 $smarty = get_smarty();
304 session::set("binarytype" , "image/jpeg");
305 session::set("binary" , $this->edit_entry['ICON']);
307 $smarty->assign("rand", microtime(TRUE));
308 $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0);
309 $smarty->assign("type", "FOLDER");
310 $smarty->assign("entry",$this->edit_entry);
311 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
312 return($display);
313 }
314 }
316 $smarty = get_smarty();
317 $smarty->assign("plug_id" , $_GET['plug']);
319 /* Create application list */
320 $div = new divSelectBox("appgroup");
321 $div->SetHeight(300);
322 $departments = array();
323 $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
324 foreach($res as $value){
325 $fdn = $value['dn'];
326 $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
327 $fdn= @LDAP::fix($fdn);
328 if($value["description"][0]!=".."){
329 $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
330 }else{
331 $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
332 }
333 }
335 $linkopen = "<a href='?plug=".$_GET['plug']."&act=depopen&depid=%s'>%s</a>";
337 /* Create base back entry */
338 $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
339 if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
340 $div->AddEntry(array(
341 array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
342 "attach"=>"style='border:0px;'")
343 ));
344 }
346 /* Append departments for current base */
347 foreach($departments as $key => $app){
348 $div->AddEntry(array(
349 array("string"=>"<img class='center' src='images/folder.png' alt='"._("department")."'> ".sprintf($linkopen,
350 base64_encode($key),$app),
351 "attach"=>"style='border:0px;'")
352 ));
353 }
356 /* Add applications found on this base */
357 $used_apps = $this->_get_used_entry_name();
358 foreach($this->apps as $key => $app){
359 if(in_array($app['cn'][0],$used_apps)){
360 continue;
361 }
362 if(!preg_match("/".get_ou('applicationou').normalizePreg($this->curbase)."$/",$app['dn'])){
363 continue;
364 }
366 $name = $app['cn'][0];
367 if(isset($app['description'])){
368 $name .= " [".$app['description'][0]."]";
369 }
370 $div->AddEntry(array(
371 array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
372 "<img class='center' src='images/select_application.png' alt='"._("application")."'> ".$name,
373 "attach"=>"style='border:0px;'")
374 ));
375 }
378 $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
379 $smarty->assign("FAIrelease",$this->FAIrelease);
380 $smarty->assign("app_list",$div->DrawList());
381 $smarty->assign("i",0);
382 $smarty->assign("releases",$this->Releases);
383 $smarty->assign("folders" , $this->_get_folder_names());
384 $entries = $this->_get_entries_for_release($this->FAIrelease);
385 $smarty->assign("entries",$entries);
386 $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
387 return($display);
388 }
391 /*! \brief Returns all used folder names
392 @return Array All used folder names.
393 */
394 function _get_folder_names()
395 {
396 $data = $this->_get_entries_for_release($this->FAIrelease);
397 $all = $this->_get_all_entries();
398 $ret = array("BASE" => ".");
399 foreach($data as $entry){
401 if($entry['TYPE'] == "FOLDER"){
402 $str = $entry['NAME'];
403 $parent = $entry['PARENT'];
404 $i = 10;
405 while(isset($all[$parent]) && $i){
406 $i --;
407 $parent_o = $all[$parent];
408 $str = $parent_o['NAME']."/".$str;
409 $parent = $all[$parent_o['UNIQID']]['PARENT'];
410 }
411 $ret[$entry['UNIQID']] = $str;
412 }
413 }
414 return($ret);
415 }
418 /*! \brief return all used applications
419 @return Array All used applications.
420 */
421 function _get_used_entry_name()
422 {
423 $data = $this->_get_entries_for_release($this->FAIrelease);
424 $ret = array();
425 foreach($data as $entry){
426 if($entry['TYPE'] == "ENTRY"){
427 $ret[] = $entry['NAME'];
428 }
429 }
430 return($ret);
431 }
434 /*! \brief Returns all folder an entries for the selected release
435 @return Array Returns the complete menu structure for the given array.
436 */
437 function _get_entries_for_release($release,$cur = NULL)
438 {
439 $all = $this->_get_all_entries();
440 $key = $this->_get_release_key($release);
441 if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
442 $res = $this->_get_all_entries(TRUE,TRUE,&$all[$key]['ENTRIES']);
443 return($res);
444 }
445 return(array());
446 }
449 /*! \brief Save the currently edited entry */
450 function _save_entry_edit()
451 {
452 $all = $this->_get_all_entries();
453 $entry = $this->edit_entry;
454 $r_entry= &$all[$entry['UNIQID']];
456 if($entry['TYPE'] == "ENTRY"){
457 $r_entry['PARAMETER'] = $this->app_parameter;
458 $r_entry['STATUS'] = "EDITED";
459 }
460 if($entry['TYPE'] == "FOLDER"){
461 $r_entry['ICON'] = $this->edit_entry['ICON'];
462 $r_entry['STATUS'] = "EDITED";
463 }
464 $this->dialog = FALSE;
465 $this->edit_entry = array();
466 }
469 /*! \brief prepare the entry with the given ID, to be edited.
470 */
471 function _edit_entry_edit($id)
472 {
473 $all = $this->_get_all_entries();
474 $entry = $all[$id];
476 $this->app_parameter = array();
477 if($entry['TYPE'] == "ENTRY"){
478 $found = FALSE;
479 foreach($this->apps as $id => $app){
481 if($app['cn'][0] == $entry['NAME']){
482 $found = TRUE;
483 break;
484 }
485 }
486 if($found){
488 /* Create a list of editable parameter */
489 if(isset($app['gosaApplicationParameter'])){
490 for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
491 $para = $app['gosaApplicationParameter'][$i];
492 $tmp = split(":",$para);
493 $this->app_parameter[$tmp[0]] = $tmp[1];
494 }
495 }
497 /* Overwrite parameters with entry parameters */
498 foreach($entry['PARAMETER'] as $name => $value){
499 $this->app_parameter[$name] = $value;
500 }
502 $this->dialog = TRUE;
503 $this->edit_entry = $entry;
504 }
505 }
507 if($entry['TYPE'] == "FOLDER"){
508 $this->dialog = TRUE;
509 $this->edit_entry = $entry;
510 }
511 }
514 function remove_from_parent()
515 {
516 $ldap = $this->config->get_ldap_link();
517 $ldap->cd($this->dn);
518 $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
519 $a_remove = array();
520 while($attrs = $ldap->fetch()){
521 $a_remove[] = $attrs['dn'];
522 }
523 foreach($a_remove as $remove){
524 $ldap->rmdir_recursive($remove);
525 show_ldap_error($ldap->get_error(),
526 sprintf(_("Removing of group/application account with dn '%s' failed, could not remove '%s'."),
527 $this->dn,$remove));
528 }
529 $this->_load_menu_structure();
530 }
533 function check()
534 {
535 }
538 /*! \brief Create missing releases, if there is a release selected \
539 that is currently not part of the menu structure \
540 then create this entry
541 */
542 function _check_missing_release($release)
543 {
544 $release_info = $this->Releases[$release];
546 $parent_id = $this->a_Structure[0]['UNIQID'];
547 $cur = &$this->a_Structure[0]['ENTRIES'];
548 for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
549 $part = $release_info['parts'][$i];
550 $found = FALSE;
551 foreach($cur as $key => $name){
552 if($name['NAME'] == $part){
553 $parent_id = $cur[$key]['UNIQID'];
554 $cur = &$cur[$key]['ENTRIES'];
556 $found =TRUE;
557 break;
558 }
559 }
560 if(!$found){
561 $release = array();
562 $release['UNIQID'] = uniqid();
563 $release['PARENT'] = $parent_id;
564 $release['NAME'] = $part;
565 $release['TYPE'] = "RELEASE";
566 $release['ENTRIES']= array();
567 $release['STATUS'] = "ADDED";
568 $release['FAIstate'] = $release_info['FAIstate'];
569 $cur[] = $release;
570 $i --;
571 }
572 }
573 }
577 function _move_entry($id,$dir)
578 {
579 $all = $this->_get_all_entries();
580 if($dir == "down"){
581 $to = $this->_get_next($id);
582 }
583 if($dir == "up"){
584 $to = $this->_get_last($id);
585 }
587 if(!$to){
588 return;
589 }
591 $o_to = $all[$to];
592 $o_from = $all[$id];
594 if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
595 $to = $this->_get_next($to,$o_from['PARENT']);
596 $o_to = $all[$to];
597 }
600 /* Target is ENTRY && same BASE, just switch */
601 if($o_to['PARENT'] == $o_from['PARENT'] ){
602 $parent = $all[$o_to['PARENT']];
603 $pos = 0;
604 foreach($parent['ENTRIES'] as $entry){
605 $pos ++;
606 if($entry['UNIQID'] == $to){
607 break;
608 }
609 }
610 if($dir == "up" && $pos > 0){
611 $pos --;
612 }
613 $this->_add_entry($parent['UNIQID'],$o_from,$pos);
614 $this->_remove_entry_id($id);
615 return(TRUE);
616 }
617 return(FALSE);
618 }
622 function _get_last($id)
623 {
624 $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
625 for($i = 0 ; $i < count($all_l) ; $i ++){
626 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
627 $i++;
628 break;
629 }
630 }
631 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
632 $i++;
633 }
635 if(!isset($all_l[$i])){
636 return(FALSE);
637 }
639 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
640 return($all_l[$i]['PARENT']);
641 }
643 return($all_l[$i]['UNIQID']);
644 }
647 function _get_next($id,$parent = 0)
648 {
649 $all_l = $this->_get_entries_for_release($this->FAIrelease);
650 for($i = 0 ; $i < count($all_l) ; $i ++){
651 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
652 $i++;
653 break;
654 }
655 }
656 if($parent != 0){
657 while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
658 $i++;
659 }
660 }else{
661 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
662 $i++;
663 }
664 }
665 if(!isset($all_l[$i])){
666 return(FALSE);
667 }
668 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
669 return($all_l[$i]['PARENT']);
670 }
671 return($all_l[$i]['UNIQID']);
672 }
677 /* !\brief Handle ui POSTS, like sort up/down/delete
678 */
679 function save_object()
680 {
681 foreach($_POST as $name => $value){
682 if(preg_match("/del_/",$name)){
683 $id = preg_replace("/^del_/","",$name);
684 $id = preg_replace("/_(x|y)$/","",$id);
685 $this->_remove_entry_id($id);
686 break;
687 }
688 if(preg_match("/app_entry_edit/",$name)){
689 $id = preg_replace("/^app_entry_edit/","",$name);
690 $id = preg_replace("/_(x|y)$/","",$id);
691 $this->_edit_entry_edit($id);
692 break;
693 }
694 if(preg_match("/up_/",$name)){
695 $id = preg_replace("/^up_/","",$name);
696 $id = preg_replace("/_(x|y)$/","",$id);
697 $this->_move_entry($id,"up");
698 break;
699 }
700 if(preg_match("/down_/",$name)){
701 $id = preg_replace("/^down_/","",$name);
702 $id = preg_replace("/_(x|y)$/","",$id);
703 $this->_move_entry($id,"down");
704 break;
705 }
706 if(preg_match("/^parameter_/",$name) &&
707 count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
708 $name = preg_replace("/^parameter_/","",$name);
709 $this->app_parameter[$name] = $value;
710 }
711 }
712 if(isset($_POST['FAIrelease'])){
713 $this->FAIrelease = $_POST['FAIrelease'];
714 $this->_check_missing_release($this->FAIrelease);
715 }
716 if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
717 $this->curbase = base64_decode($_GET['depid']);
718 }
719 if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
720 $folder = $_POST['folder'];
721 foreach($_POST as $name => $value){
722 if(preg_match("/^AddApp_[0-9]*$/",$name)){
723 $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));
724 }
725 }
726 }
727 if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
728 $folder = $_POST['menu_folder'];
729 $name = $_POST['menu_folder_name'];
730 if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
731 $this->_add_sub_folder($folder,$name);
732 }
733 }
734 if(isset($_POST['app_entry_save'])){
735 $this->_save_entry_edit();
736 }
738 if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
739 if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
740 $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
741 }
742 }
744 if(isset($_POST['edit_reset_image'])){
745 $this->edit_entry['ICON'] = "";
746 }
748 if(isset($_POST['app_entry_cancel'])){
749 $this->edit_entry = array();
750 $this->dialog = FALSE;
751 }
752 $this->reload();
753 }
756 /*! \brief Returns the UNIQID of the currently selected release
757 */
758 function _get_release_key($release,$add_if_missing = FALSE)
759 {
760 $release_info = $this->Releases[$release];
762 if($release_info['name'] == "/"){
763 return($this->a_Structure['0']['UNIQID']);
764 }
766 $cur = &$this->a_Structure[0]['ENTRIES'];
767 $s_key = "";
768 $found = FALSE;
769 foreach($release_info['parts'] as $name){
770 foreach($cur as $key => $obj){
771 if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
772 $s_key = $cur[$key]['UNIQID'];
773 $cur = &$cur[$key]['ENTRIES'];
774 $found = TRUE;
775 break;
776 }
777 $found = FALSE;
778 }
779 }
780 if($found){
781 return($s_key);
782 }
783 return(FALSE);
784 }
787 /*! \brief Add a new folder folder to the specified folder id
788 @param String $folder The folder id in where we want to add the new folder.
789 @param String $name The name of the new folder.
790 */
791 function _add_sub_folder($folder,$name)
792 {
793 $all = $this->_get_all_entries();
794 if($folder == "BASE"){
795 $folder = $this->_get_release_key($this->FAIrelease,TRUE);
796 }
798 if(isset($all[$folder])){
799 $a_folder = array();
800 $a_folder['STATUS'] = "ADDED";
801 $a_folder['NAME'] = $name;
802 $a_folder['UNIQID'] = uniqid();
803 $a_folder['ENTRIES']= array();
804 $a_folder['PARENT'] = $folder;
805 $a_folder['TYPE'] = "FOLDER";
806 $a_folder['ICON'] = "";
807 $all[$folder]['ENTRIES'][] = $a_folder;
808 }
809 }
812 /* !\brief Remove the given id from the menu structure.
813 @param String ID to of the entry we want to remove.
814 @return Boolean TRUE on success
815 */
816 function _remove_entry_id($id)
817 {
818 $all = $this->_get_all_entries();
819 if(isset($all[$id])){
820 $all[$id]['STATUS'] = "REMOVED";
821 $all[$id]['ENTRIES'] = array();
822 return(TRUE);
823 }
824 return(FALSE);
825 }
828 /* !\brief Remove the given id from the menu structure.
829 @param String ID to of the entry we want to remove.
830 @return Boolean TRUE on success
831 */
832 function _add_entry($folder_id,$entry,$pos = 0)
833 {
834 $all = $this->_get_all_entries();
836 /* Do not add removed */
837 if($entry['STATUS'] == "REMOVED"){
838 return;
839 }
841 if(isset($all[$folder_id])){
843 if(!isset($entry['ENTRIES'])){
844 $entries = array();
845 }else{
846 $entries = $entry['ENTRIES'];
847 }
849 $folder = &$all[$folder_id];
851 $entry['UNIQID'] = uniqid();
852 $entry['PARENT'] = $folder_id;
853 $entry['ENTRIES']= array();
854 $entry['STATUS'] = "ADDED";
856 $cnt = 0;
857 $new = array();
858 $added =FALSE;
859 foreach($folder['ENTRIES'] as $key => $obj){
860 if($obj['STATUS'] == "LOADED"){
861 $obj['STATUS'] = "EDITED";
862 }
863 if($pos == $cnt){
864 $new[] = $entry;
865 $added = TRUE;
866 }
867 $cnt ++;
868 $new[] = $obj;
869 }
870 if(!$added){
871 $new[] = $entry;
872 }
874 $all[$folder_id]['ENTRIES'] = $new;
875 foreach($entries as $sub){
876 $this->_add_entry($entry['UNIQID'],$sub,-1);
877 }
878 return(TRUE);
879 }
880 return(FALSE);
881 }
884 /*! \brief Add the application identified by $app_id to folder $folder_id
885 @param String folder_id The UNIQID of the folder where we want to add the new folder.
886 @param Integer app_id The ID of the application which should be added.
887 */
888 function _add_app_id($folder_id,$app_id)
889 {
890 $all = $this->_get_all_entries();
891 if($folder_id == "BASE"){
892 $folder_id = $this->_get_release_key($this->FAIrelease);
893 }
894 if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
896 $new = array();
897 $new['TYPE'] = "ENTRY";
898 $new['NAME'] = $this->apps[$app_id]['cn'][0];
899 $new['UNIQID']= uniqid();
900 $new['PARENT']= $folder_id;
901 $new['PARAMETER']= array();
902 if(isset($this->apps[$app_id]['description'][0])){
903 $new['INFO'] = $this->apps[$app_id]['description'][0];
904 }else{
905 $new['INFO'] = "";
906 }
907 $new['STATUS']= "ADDED";
908 $all[$folder_id]['ENTRIES'][] = $new;
909 }
910 }
913 /*! \brief Return all entries linear.
914 @param Boolean $add_tags If TRUE, OPEN/CLOSE Tags will be appended.
915 @param &Array Start here, Pointer to an array.
916 */
917 function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, $cur = NULL)
918 {
919 $ret = array();
920 if($cur == NULL){
921 $cur = &$this->a_Structure;
922 }
923 foreach($cur as $key => $entry){
925 if($skip_release && $entry['TYPE'] == "RELEASE"){
926 continue;
927 }
928 if($entry['TYPE'] == "ENTRY"){
929 $found = FALSE;
930 foreach($this->apps as $app){
931 if($app['cn'][0] == $entry['NAME']){
932 $found = TRUE;
933 if(isset($app['description'][0])){
934 $entry['INFO'] = "[".$app['description'][0]."]";
935 }
936 break;
937 }
938 }
939 if(!$found){
940 $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
941 }
942 }
945 $tmp = $entry;
946 if(!$add_tags){
947 $ret[$tmp['UNIQID']] = &$cur[$key];
948 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
949 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
950 }
951 }else{
953 if(isset($tmp['ENTRIES'])){
954 unset($tmp['ENTRIES']);
955 }
956 if($tmp['STATUS'] != "REMOVED"){
957 $ret[] = $tmp;
958 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
959 $add = false;
960 foreach($entry['ENTRIES'] as $entry){
961 if($entry['STATUS'] != "REMOVED"){
962 $add = TRUE;
963 break;
964 }
965 }
967 if($add){
968 $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
969 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
970 $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
971 }
972 }
973 }
974 }
975 }
976 return($ret);
977 }
980 function save()
981 {
982 $ldap = $this->config->get_ldap_link();
983 $all = $this->_get_all_entries();
984 $prio = 0;
985 $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
987 foreach($all as $entry){
988 $prio ++;
989 $cur = $entry;
990 $dn = "";
992 do{
993 if($cur['TYPE'] == "ENTRY"){
994 $dn.= "cn=".$cur['NAME'].",";
995 }elseif($cur['TYPE'] == "FOLDER"){
996 $dn.= "cn=".$cur['NAME'].",";
997 }elseif($cur['TYPE'] == "RELEASE"){
998 $dn.= "ou=".$cur['NAME'].",";
999 }elseif($cur['TYPE'] == "BASE"){
1000 }
1001 if(!isset($all[$cur['PARENT']])){
1002 $cur = NULL;
1003 }else{
1004 $cur = $all[$cur['PARENT']];
1005 }
1006 }while(is_array($cur));
1008 $cur_dn = $dn.$this->dn;
1010 $attrs = array();
1011 switch($entry['TYPE']){
1012 case "ENTRY" :
1013 {
1014 $attrs['objectClass'] = "gotoMenuEntry";
1015 $attrs['cn'] = $entry['NAME'];
1016 $attrs['gosaApplicationPriority'] = $prio;
1017 $attrs['gosaApplicationParameter'] = array();
1020 foreach($entry['PARAMETER'] as $name => $value){
1021 $attrs['gosaApplicationParameter'][] = $name.":".$value;
1022 }
1023 if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1024 unset($attrs['gosaApplicationParameter']);
1025 }
1026 }
1027 break;
1028 case "FOLDER" :
1029 {
1030 $attrs['objectClass'] = "gotoSubmenuEntry";
1031 $attrs['cn'] = $entry['NAME'];
1032 $attrs['gosaApplicationPriority'] = $prio;
1033 if($entry['STATUS'] != "ADDED"){
1034 $attrs['gosaApplicationIcon'] = array();
1035 }
1037 if(!empty($entry['ICON'])){
1038 $attrs['gosaApplicationIcon'] = $entry['ICON'];
1039 }
1040 }
1041 break;
1042 case "RELEASE" :
1043 {
1044 $attrs['ou'] = $entry['NAME'];
1045 $attrs['objectClass'] = array();
1046 $attrs['objectClass'][] = "top";
1047 $attrs['objectClass'][] = "organizationalUnit";
1048 $attrs['objectClass'][] = "FAIbranch";
1049 if(!empty($entry['FAIstate'])){
1050 $attrs['FAIstate'] = $entry['FAIstate'];
1051 }
1052 }
1053 break;
1054 }
1056 if($entry['STATUS'] == "LOADED"){
1057 continue;
1058 }
1059 if($entry['STATUS'] == "REMOVED"){
1060 $Actions['Remove'][$cur_dn] = $cur_dn;
1061 }
1062 if($entry['STATUS'] == "EDITED"){
1063 $Actions['Edit'][$cur_dn] = $attrs;
1064 }
1065 if($entry['STATUS'] == "ADDED"){
1066 $Actions['Add'][$cur_dn] = $attrs;
1067 }
1068 }
1070 $ldap = $this->config->get_ldap_link();
1071 $ldap->cd($this->config->current['BASE']);
1072 foreach($Actions['Remove'] as $dn){
1073 $ldap->cd($dn);
1074 $ldap->cat($dn);
1075 if($ldap->count()){
1076 $ldap->rmdir_recursive($dn);
1077 show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1078 }
1079 }
1080 foreach($Actions['Add'] as $dn => $data){
1081 $ldap->cd($dn);
1082 $ldap->cat($dn);
1083 if(!$ldap->count()){
1084 $ldap->add($data);
1085 show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1086 }
1087 }
1088 foreach($Actions['Edit'] as $dn => $data){
1089 $ldap->cd($dn);
1090 $ldap->cat($dn);
1091 if($ldap->count()){
1092 $ldap->modify($data);
1093 show_ldap_error($ldap->get_error(), _("Could not save group application settings."));
1094 }
1095 }
1096 $this->_load_menu_structure();
1097 }
1100 /* Return plugin informations for acl handling */
1101 static function plInfo()
1102 {
1103 return (array(
1104 "plShortName" => _("Applications"),
1105 "plDescription" => _("Group applications"),
1106 "plSelfModify" => FALSE,
1107 "plDepends" => array(),
1108 "plPriority" => 0,
1109 "plSection" => array("admin"),
1110 "plCategory" => array("groups"),
1111 "plProvidedAcls"=> array(
1112 "gosaMemberApplication" => _("Application"),
1113 "FAIrelease" => _("Release"),
1114 "gosaApplicationParameter" => _("Application parameter"))
1115 ));
1116 }
1119 function PrepareForCopyPaste($source)
1120 {
1121 }
1124 function multiple_save_object()
1125 {
1126 if(isset($_POST['group_apps_multi'])){
1127 $this->save_object();
1128 plugin::multiple_save_object();
1130 /* Get posts */
1131 foreach(array("apps") as $attr){
1132 if(isset($_POST['use_'.$attr])) {
1133 $this->multi_boxes[] = $attr;
1134 }
1135 }
1136 }
1137 }
1140 function get_multi_edit_values()
1141 {
1142 $ret = plugin::get_multi_edit_values();
1144 if(in_array("apps",$this->multi_boxes)){
1145 $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1146 $ret['Categories'] = $this->Categories;
1147 $ret['gosaMemberApplication'] = $this->gosaMemberApplication;
1148 $ret['FAIrelease'] = $this->FAIrelease;
1149 $ret['appoption'] = $this->appoption;
1150 }
1151 return($ret);
1152 }
1153 }
1154 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1155 ?>