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