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;
21 public function __construct(&$config, $dn= NULL, $parent= NULL)
22 {
23 plugin::plugin($config,$dn,$parent);
24 $this->dn = $dn;
25 $this->_load_menu_structure();
26 $this->a_Structure_on_load = $this->a_Structure;
28 /* Check if we have relase mangement enabled and prepare group application for release management */
29 $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
30 if(!empty($tmp)){
31 $this->enableReleaseManagement = true;
32 }
34 $this->Releases = $this->getReleases();
35 $this->FAIrelease = "/";
36 $this->curbase = $this->config->current['BASE'];
37 $this->reload();
39 $this->is_account = FALSE;
40 if(count($this->_get_all_entries()) > 1){
41 $this->is_account= TRUE;
42 }
43 $this->initially_was_account = $this->is_account;
44 }
47 /*! \brief Reload the list of applications for the currently selected release
48 */
49 function reload()
50 {
51 $ret = array();
52 $release_info = $this->Releases[$this->FAIrelease];
54 if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
56 $ldap = $this->config->get_ldap_link();
57 $ldap->cd($this->config->current['BASE']);
58 $ldap->search("ou=apps",array("dn"));
59 $app_deps = array();
60 while($attrs = $ldap->fetch()){
61 $app_deps[] = $attrs['dn'];
62 }
64 foreach($app_deps as $dep){
65 $ldap->cd($dep);
66 $ldap->search("objectClass=FAIbranch",array("dn"));
67 while($attrs = $ldap->fetch()){
68 $app_deps[] = $attrs['dn'];
69 }
70 }
72 foreach($app_deps as $dep){
73 if(preg_match("/^".normalizePreg($release_info['suffix'])."/",$dep)){
74 $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
75 }
76 }
78 $tmp = array();
79 foreach($ret as $key => $app){
80 $tmp[$key] = $app['cn'][0];
81 }
82 natcasesort($tmp);
83 $res = array();
84 foreach($tmp as $key => $app){
85 $res[] = $ret[$key];
86 }
88 $this->_cache['ReleaseApps'][$release_info['suffix']] = $res;
89 }
90 $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
91 }
96 /*! \brief generate a list of available releases
97 @return return an array with all available releases.
98 */
99 function getReleases()
100 {
101 $ret =array("/" => array("name" => "/", "found" => TRUE , "parts" => array(),"suffix" => get_ou('applicationou')));
102 if($this->enableReleaseManagement){
104 /* Only display those releases that we are able to read */
105 $dn = get_ou("applicationou").$this->config->current['BASE'];
106 $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
107 $res = get_sub_list($filter,array("application","fai"), array(get_ou("applicationou"),get_ou("faiou")),$dn, array("ou","FAIstate"), GL_SUBSEARCH);
110 foreach($res as $attrs){
111 if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
112 $bb = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
113 $parts = array_reverse(split("ou=",$bb));
115 $str ="";
116 foreach($parts as $key => $part){
117 if(empty($part)) {
118 unset($parts[$key]);
119 continue;
120 }
121 $part = str_replace(",","",$part);
122 $str .= $part."/";
123 $parts[$key] = $part;
124 }
125 $name = preg_replace("/\/$/","",$str);
126 if(empty($name)) {
127 $name ="/";
128 }
129 $FAIstate = "";
130 if(isset($attrs['FAIstate'])){
131 $FAIstate = $attrs['FAIstate'][0];
132 }
134 $all = $this->_get_all_entries();
135 $found = FALSE;
136 foreach($all as $entry){
137 if(isset($entry['DN']) && preg_match("/^".normalizePreg($bb)."/",$entry['DN'])){
138 $found =TRUE;
139 break;
140 }
141 }
143 $cnt = 0;
144 $ret[$name] = array("name" => $name,
145 "found" => $found,
146 "FAIstate" => $FAIstate,
147 "dn" => $attrs['dn'],
148 "parts" => $parts,"suffix" => $bb.get_ou('applicationou'));
149 }
150 }
151 }
152 ksort($ret);
153 return($ret);
154 }
157 /*! \brief Load the menu structure from ldap and create a multi dimensional array
158 */
159 function _load_menu_structure()
160 {
161 $this->a_Structure = array();
162 $ldap = $this->config->get_ldap_link();
163 $ldap->cd($this->dn);
164 $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
166 $base = array();
167 $base['UNIQID'] = uniqid();
168 $base['PARENT'] = 0;
169 $base['NAME'] = "";
170 $base['TYPE'] = "BASE";
171 $base['ENTRIES']= array();
172 $base['STATUS'] = "LOADED";
174 $this->a_Structure[0] = $base;
176 while($attrs = $ldap->fetch()){
177 $cur = &$this->a_Structure[0]['ENTRIES'];
178 $parent_id = $base['UNIQID'];
179 $sub_dn = preg_replace("/,".normalizePreg($this->dn)."$/","",$attrs['dn']);
180 $sub_dn_array = split("\,",$sub_dn);
182 $found = true;
183 for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
184 $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
186 if($i > 0){
187 $found =FALSE;
188 foreach($cur as $key => $entry){
189 if($entry['NAME'] == $name){
190 $cur = &$cur[$key]['ENTRIES'];
191 $parent_id = $entry['UNIQID'];
192 $found =true;
193 break;
194 }
195 }
196 }else{
198 if(!$found){
199 break;
200 }
201 $priority = 1;
202 if(isset($attrs['gosaApplicationPriority'])){
203 $priority= $attrs['gosaApplicationPriority'][0];
204 }
205 while(isset($cur[$priority])){
206 $priority ++;
207 }
209 $data = array();
210 if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
211 $type = "FOLDER";
213 $data['ICON'] = "";
214 if(isset($attrs['gosaApplicationIcon'])){
215 $data['ICON'] = $ldap->get_attribute($attrs['dn'],"gosaApplicationIcon");
216 }
218 }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
220 $type = "ENTRY";
221 $data['INFO'] = "";
222 $data['PARAMETER'] = array();
223 if(isset($attrs['gosaApplicationParameter'])){
224 for($p = 0 ; $p < $attrs['gosaApplicationParameter']['count'] ; $p ++){
225 if(preg_match("/:/",$attrs['gosaApplicationParameter'][$p])){
226 $tmp = split(":",$attrs['gosaApplicationParameter'][$p]);
227 $data['PARAMETER'][$tmp[0]] = $tmp[1];
228 }elseif($attrs['gosaApplicationParameter'][$p] == "*separator*"){
229 $type = "SEPERATOR";
230 $data['PARAMETER'] = array();
231 break;
232 }
233 }
234 }
235 }elseif(in_array("FAIbranch",$attrs['objectClass'])){
237 $type = "RELEASE";
238 if(isset($attrs['FAIstate'][0])){
239 $data['FAIstate'] = $attrs['FAIstate'][0];
240 }else{
241 $data['FAIstate'] = "";
242 }
243 }
245 $data['LDAP_ATTRS'] = $attrs;
246 $data['DN'] = $attrs['dn'];
247 $data['NAME'] = $name;
248 $data['TYPE'] = $type;
249 $data['PRIORITY'] = $priority;
250 $data['ENTRIES'] = array();
251 $data['UNIQID'] = uniqid();
252 $data['PARENT'] = $parent_id;
253 $data['STATUS'] = "LOADED";
254 $cur[$priority] = $data;
255 ksort($cur);
256 }
257 }
258 }
259 }
262 function execute()
263 {
264 /* Call parent execute */
265 plugin::execute();
267 if(isset($_GET['r'])) $this->__construct($this->config,$this->dn);
269 if (isset($_POST['modify_state'])){
270 $this->is_account = !$this->is_account;
271 }
273 /* Do we represent a valid account? */
274 if (!$this->is_account){
275 $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Menu")), msgPool::featuresDisabled(_("Menu")));
276 return ($display);
277 }
279 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Menu")), msgPool::featuresEnabled(_("Menu")));
281 if(isset($_GET['send'])){
282 $id = $_GET['send'];
283 $all = $this->_get_all_entries();
284 if(isset($all[$id])){
285 send_binary_content($all[$id]['ICON'],$id.".jpg","image/jpeg");
286 exit;
287 }
288 }
290 if(isset($_GET['r']))
291 $this->__construct($this->config,$this->dn);
293 if(count($this->edit_entry)){
294 if($this->edit_entry['TYPE'] == "ENTRY"){
295 $smarty = get_smarty();
296 $smarty->assign("type", "ENTRY");
297 $smarty->assign("entry",$this->edit_entry);
298 $smarty->assign("paras",$this->app_parameter);
299 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
300 return($display);
301 }
302 if($this->edit_entry['TYPE'] == "FOLDER"){
303 $smarty = get_smarty();
305 session::set("binarytype" , "image/jpeg");
306 session::set("binary" , $this->edit_entry['ICON']);
308 $smarty->assign("rand", microtime(TRUE));
309 $smarty->assign("image_set" , strlen($this->edit_entry['ICON']) > 0);
310 $smarty->assign("type", "FOLDER");
311 $smarty->assign("entry",$this->edit_entry);
312 $display= $smarty->fetch (get_template_path('edit_entry.tpl', TRUE, dirname(__FILE__)));
313 return($display);
314 }
315 }
317 $smarty = get_smarty();
318 $smarty->assign("plug_id" , $_GET['plug']);
320 /* Create application list */
321 $div = new divSelectBox("appgroup");
322 $div->SetHeight(300);
323 $departments = array();
324 $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
325 foreach($res as $value){
326 $fdn = $value['dn'];
327 $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
328 $fdn= @LDAP::fix($fdn);
329 if($value["description"][0]!=".."){
330 $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
331 }else{
332 $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
333 }
334 }
336 $linkopen = "<a href='?plug=".$_GET['plug']."&act=depopen&depid=%s'>%s</a>";
338 /* Create base back entry */
339 $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
340 if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
341 $div->AddEntry(array(
342 array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
343 "attach"=>"style='border:0px;'")
344 ));
345 }
347 /* Append departments for current base */
348 foreach($departments as $key => $app){
349 $div->AddEntry(array(
350 array("string"=>"<img class='center' src='images/lists/folder.png' alt='"._("department")."'> ".sprintf($linkopen,
351 base64_encode($key),$app),
352 "attach"=>"style='border:0px;'")
353 ));
354 }
357 /* Add applications found on this base */
358 $used_apps = $this->_get_used_entry_name();
359 foreach($this->apps as $key => $app){
360 if(in_array($app['cn'][0],$used_apps)){
361 continue;
362 }
363 if(!preg_match("/".get_ou('applicationou').normalizePreg($this->curbase)."$/",$app['dn'])){
364 continue;
365 }
367 $name = $app['cn'][0];
368 if(isset($app['description'])){
369 $name .= " [".$app['description'][0]."]";
370 }
371 $div->AddEntry(array(
372 array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
373 "<img class='center' src='images/select_application.png' alt='"._("application")."'> ".$name,
374 "attach"=>"style='border:0px;'")
375 ));
376 }
379 $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
380 $smarty->assign("FAIrelease",$this->FAIrelease);
381 $smarty->assign("app_list",$div->DrawList());
382 $smarty->assign("i",0);
383 $smarty->assign("releases",$this->Releases);
384 $smarty->assign("folders" , $this->_get_folder_names());
385 $entries = $this->_get_entries_for_release($this->FAIrelease);
386 $smarty->assign("entries",$entries);
387 $display.= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
388 return($display);
389 }
392 /*! \brief Returns all used folder names
393 @return Array All used folder names.
394 */
395 function _get_folder_names()
396 {
397 $data = $this->_get_entries_for_release($this->FAIrelease);
398 $all = $this->_get_all_entries();
399 $ret = array("BASE" => ".");
400 foreach($data as $entry){
402 if($entry['TYPE'] == "FOLDER"){
403 $str = $entry['NAME'];
404 $parent = $entry['PARENT'];
405 $i = 10;
406 while(isset($all[$parent]) && $i){
407 $i --;
408 $parent_o = $all[$parent];
409 $str = $parent_o['NAME']."/".$str;
410 $parent = $all[$parent_o['UNIQID']]['PARENT'];
411 }
412 $ret[$entry['UNIQID']] = $str;
413 }
414 }
415 return($ret);
416 }
419 /*! \brief return all used applications
420 @return Array All used applications.
421 */
422 function _get_used_entry_name()
423 {
424 $data = $this->_get_entries_for_release($this->FAIrelease);
425 $ret = array();
426 foreach($data as $entry){
427 if($entry['TYPE'] == "ENTRY"){
428 $ret[] = $entry['NAME'];
429 }
430 }
431 return($ret);
432 }
435 /*! \brief Returns all folder an entries for the selected release
436 @return Array Returns the complete menu structure for the given array.
437 */
438 function _get_entries_for_release($release,$cur = NULL)
439 {
440 $all = $this->_get_all_entries();
441 $key = $this->_get_release_key($release);
442 if(isset($all[$key]) && count($all[$key]['ENTRIES'])){
443 $res = $this->_get_all_entries(TRUE,TRUE,$all[$key]['ENTRIES']);
444 return($res);
445 }
446 return(array());
447 }
450 /*! \brief Save the currently edited entry */
451 function _save_entry_edit()
452 {
453 $all = $this->_get_all_entries();
454 $entry = $this->edit_entry;
455 $r_entry= &$all[$entry['UNIQID']];
457 if($entry['TYPE'] == "ENTRY"){
458 $r_entry['PARAMETER'] = $this->app_parameter;
459 $r_entry['STATUS'] = "EDITED";
460 }
461 if($entry['TYPE'] == "FOLDER"){
462 $r_entry['ICON'] = $this->edit_entry['ICON'];
463 $r_entry['STATUS'] = "EDITED";
464 }
465 $this->dialog = FALSE;
466 $this->edit_entry = array();
467 }
470 /*! \brief prepare the entry with the given ID, to be edited.
471 */
472 function _edit_entry_edit($id)
473 {
474 $all = $this->_get_all_entries();
475 $entry = $all[$id];
477 $this->app_parameter = array();
478 if($entry['TYPE'] == "ENTRY"){
479 $found = FALSE;
480 foreach($this->apps as $id => $app){
482 if($app['cn'][0] == $entry['NAME']){
483 $found = TRUE;
484 break;
485 }
486 }
487 if($found){
489 /* Create a list of editable parameter */
490 if(isset($app['gosaApplicationParameter'])){
491 for($i = 0 ; $i < $app['gosaApplicationParameter']['count'] ; $i++) {
492 $para = $app['gosaApplicationParameter'][$i];
493 $tmp = split(":",$para);
494 $this->app_parameter[$tmp[0]] = $tmp[1];
495 }
496 }
498 /* Overwrite parameters with entry parameters */
499 foreach($entry['PARAMETER'] as $name => $value){
500 $this->app_parameter[$name] = $value;
501 }
503 $this->dialog = TRUE;
504 $this->edit_entry = $entry;
505 }
506 }
508 if($entry['TYPE'] == "FOLDER"){
509 $this->dialog = TRUE;
510 $this->edit_entry = $entry;
511 }
512 }
515 function remove_from_parent()
516 {
517 $ldap = $this->config->get_ldap_link();
518 $ldap->cd($this->dn);
519 $ldap->ls("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",$this->dn,array("*"));
520 $a_remove = array();
521 while($attrs = $ldap->fetch()){
522 $a_remove[] = $attrs['dn'];
523 }
524 foreach($a_remove as $remove){
525 $ldap->rmdir_recursive($remove);
526 if (!$ldap->success()){
527 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
528 }
529 }
530 $this->_load_menu_structure();
531 }
534 function check()
535 {
536 $message = plugin::check();
537 return($message);
538 }
541 /*! \brief Create missing releases, if there is a release selected \
542 that is currently not part of the menu structure \
543 then create this entry
544 */
545 function _check_missing_release($release)
546 {
547 $release_info = $this->Releases[$release];
549 $parent_id = $this->a_Structure[0]['UNIQID'];
550 $cur = &$this->a_Structure[0]['ENTRIES'];
551 for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
552 $part = $release_info['parts'][$i];
553 $found = FALSE;
554 foreach($cur as $key => $name){
555 if($name['NAME'] == $part){
556 $parent_id = $cur[$key]['UNIQID'];
557 $cur = &$cur[$key]['ENTRIES'];
559 $found =TRUE;
560 break;
561 }
562 }
563 if(!$found){
564 $release = array();
565 $release['UNIQID'] = uniqid();
566 $release['PARENT'] = $parent_id;
567 $release['NAME'] = $part;
568 $release['TYPE'] = "RELEASE";
569 $release['ENTRIES']= array();
570 $release['STATUS'] = "ADDED";
571 $release['FAIstate'] = $release_info['FAIstate'];
572 $cur[] = $release;
573 $i --;
574 }
575 }
576 }
580 function _move_entry($id,$dir)
581 {
582 $all = $this->_get_all_entries();
583 if($dir == "down"){
584 $to = $this->_get_next($id);
585 }
586 if($dir == "up"){
587 $to = $this->_get_last($id);
588 }
590 if(!$to){
591 return;
592 }
594 $o_to = $all[$to];
595 $o_from = $all[$id];
597 if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
598 $to = $this->_get_next($to,$o_from['PARENT']);
599 $o_to = $all[$to];
600 }
603 /* Target is ENTRY && same BASE, just switch */
604 if($o_to['PARENT'] == $o_from['PARENT'] ){
605 $parent = $all[$o_to['PARENT']];
606 $pos = 0;
607 foreach($parent['ENTRIES'] as $entry){
608 $pos ++;
609 if($entry['UNIQID'] == $to){
610 break;
611 }
612 }
613 if($dir == "up" && $pos > 0){
614 $pos --;
615 }
616 $this->_add_entry($parent['UNIQID'],$o_from,$pos);
617 $this->_remove_entry_id($id);
618 return(TRUE);
619 }
620 return(FALSE);
621 }
625 function _get_last($id)
626 {
627 $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
628 for($i = 0 ; $i < count($all_l) ; $i ++){
629 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
630 $i++;
631 break;
632 }
633 }
634 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
635 $i++;
636 }
638 if(!isset($all_l[$i])){
639 return(FALSE);
640 }
642 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
643 return($all_l[$i]['PARENT']);
644 }
646 return($all_l[$i]['UNIQID']);
647 }
650 function _get_next($id,$parent = 0)
651 {
652 $all_l = $this->_get_entries_for_release($this->FAIrelease);
653 for($i = 0 ; $i < count($all_l) ; $i ++){
654 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
655 $i++;
656 break;
657 }
658 }
659 if($parent != 0){
660 while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
661 $i++;
662 }
663 }else{
664 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
665 $i++;
666 }
667 }
668 if(!isset($all_l[$i])){
669 return(FALSE);
670 }
671 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
672 return($all_l[$i]['PARENT']);
673 }
674 return($all_l[$i]['UNIQID']);
675 }
680 /* !\brief Handle ui POSTS, like sort up/down/delete
681 */
682 function save_object()
683 {
684 foreach($_POST as $name => $value){
685 if(preg_match("/del_/",$name)){
686 $id = preg_replace("/^del_/","",$name);
687 $id = preg_replace("/_(x|y)$/","",$id);
688 $this->_remove_entry_id($id);
689 break;
690 }
691 if(preg_match("/app_entry_edit/",$name)){
692 $id = preg_replace("/^app_entry_edit/","",$name);
693 $id = preg_replace("/_(x|y)$/","",$id);
694 $this->_edit_entry_edit($id);
695 break;
696 }
697 if(preg_match("/up_/",$name)){
698 $id = preg_replace("/^up_/","",$name);
699 $id = preg_replace("/_(x|y)$/","",$id);
700 $this->_move_entry($id,"up");
701 break;
702 }
703 if(preg_match("/down_/",$name)){
704 $id = preg_replace("/^down_/","",$name);
705 $id = preg_replace("/_(x|y)$/","",$id);
706 $this->_move_entry($id,"down");
707 break;
708 }
709 if(preg_match("/^parameter_/",$name) &&
710 count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
711 $name = preg_replace("/^parameter_/","",$name);
712 $this->app_parameter[$name] = $value;
713 }
714 }
715 if(isset($_POST['FAIrelease'])){
716 $this->FAIrelease = $_POST['FAIrelease'];
717 $this->_check_missing_release($this->FAIrelease);
718 }
719 if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
720 $this->curbase = base64_decode($_GET['depid']);
721 }
722 if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
723 $folder = $_POST['folder'];
724 foreach($_POST as $name => $value){
725 if(preg_match("/^AddApp_[0-9]*$/",$name)){
726 $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));
727 }
728 }
729 }
731 /* Add seperator */
732 if(isset($_POST['add_seperator']) && isset($_POST['menu_folder'])){
733 $folder = $_POST['menu_folder'];
734 $this->_add_seperator($folder);
735 }
737 if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
738 $folder = $_POST['menu_folder'];
739 $name = $_POST['menu_folder_name'];
740 if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
741 $this->_add_sub_folder($folder,$name);
742 }
743 }
744 if(isset($_POST['app_entry_save'])){
745 $this->_save_entry_edit();
746 }
748 if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
749 if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
750 $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
751 }
752 }
754 if(isset($_POST['edit_reset_image'])){
755 $this->edit_entry['ICON'] = "";
756 }
758 if(isset($_POST['app_entry_cancel'])){
759 $this->edit_entry = array();
760 $this->dialog = FALSE;
761 }
762 $this->reload();
763 }
766 /*! \brief Returns the UNIQID of the currently selected release
767 */
768 function _get_release_key($release,$add_if_missing = FALSE)
769 {
770 $release_info = $this->Releases[$release];
772 if($release_info['name'] == "/"){
773 return($this->a_Structure['0']['UNIQID']);
774 }
776 $cur = &$this->a_Structure[0]['ENTRIES'];
777 $s_key = "";
778 $found = FALSE;
779 foreach($release_info['parts'] as $name){
780 foreach($cur as $key => $obj){
781 if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
782 $s_key = $cur[$key]['UNIQID'];
783 $cur = &$cur[$key]['ENTRIES'];
784 $found = TRUE;
785 break;
786 }
787 $found = FALSE;
788 }
789 }
790 if($found){
791 return($s_key);
792 }
793 return(FALSE);
794 }
797 /*! \brief Add a new folder folder to the specified folder id
798 @param String $folder The folder id in where we want to add the new folder.
799 @param String $name The name of the new folder.
800 */
801 function _add_sub_folder($folder,$name)
802 {
803 $all = $this->_get_all_entries();
804 if($folder == "BASE"){
805 $folder = $this->_get_release_key($this->FAIrelease,TRUE);
806 }
808 if(isset($all[$folder])){
809 $a_folder = array();
810 $a_folder['STATUS'] = "ADDED";
811 $a_folder['NAME'] = $name;
812 $a_folder['UNIQID'] = uniqid();
813 $a_folder['ENTRIES']= array();
814 $a_folder['PARENT'] = $folder;
815 $a_folder['TYPE'] = "FOLDER";
816 $a_folder['ICON'] = "";
817 $all[$folder]['ENTRIES'][] = $a_folder;
818 }
819 }
822 /* !\brief Remove the given id from the menu structure.
823 @param String ID to of the entry we want to remove.
824 @return Boolean TRUE on success
825 */
826 function _remove_entry_id($id)
827 {
828 $all = $this->_get_all_entries();
829 if(isset($all[$id])){
830 $all[$id]['STATUS'] = "REMOVED";
831 $all[$id]['ENTRIES'] = array();
832 return(TRUE);
833 }
834 return(FALSE);
835 }
838 /* !\brief Remove the given id from the menu structure.
839 @param String ID to of the entry we want to remove.
840 @return Boolean TRUE on success
841 */
842 function _add_entry($folder_id,$entry,$pos = 0)
843 {
844 $all = $this->_get_all_entries();
846 /* Do not add removed */
847 if($entry['STATUS'] == "REMOVED"){
848 return;
849 }
851 if(isset($all[$folder_id])){
853 if(!isset($entry['ENTRIES'])){
854 $entries = array();
855 }else{
856 $entries = $entry['ENTRIES'];
857 }
859 $folder = &$all[$folder_id];
861 $entry['UNIQID'] = uniqid();
862 $entry['PARENT'] = $folder_id;
863 $entry['ENTRIES']= array();
864 $entry['STATUS'] = "ADDED";
866 $cnt = 0;
867 $new = array();
868 $added =FALSE;
869 foreach($folder['ENTRIES'] as $key => $obj){
870 if($obj['STATUS'] == "LOADED"){
871 $obj['STATUS'] = "EDITED";
872 }
873 if($pos == $cnt){
874 $new[] = $entry;
875 $added = TRUE;
876 }
877 $cnt ++;
878 $new[] = $obj;
879 }
880 if(!$added){
881 $new[] = $entry;
882 }
884 $all[$folder_id]['ENTRIES'] = $new;
885 foreach($entries as $sub){
886 $this->_add_entry($entry['UNIQID'],$sub,-1);
887 }
888 return(TRUE);
889 }
890 return(FALSE);
891 }
894 /*! \brief Add the application identified by $app_id to folder $folder_id
895 @param String folder_id The UNIQID of the folder where we want to add the new folder.
896 @param Integer app_id The ID of the application which should be added.
897 */
898 function _add_app_id($folder_id,$app_id)
899 {
900 $all = $this->_get_all_entries();
901 if($folder_id == "BASE"){
902 $folder_id = $this->_get_release_key($this->FAIrelease);
903 }
904 if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
906 $new = array();
907 $new['TYPE'] = "ENTRY";
908 $new['NAME'] = $this->apps[$app_id]['cn'][0];
909 $new['UNIQID']= uniqid();
910 $new['PARENT']= $folder_id;
911 $new['PARAMETER']= array();
912 if(isset($this->apps[$app_id]['description'][0])){
913 $new['INFO'] = $this->apps[$app_id]['description'][0];
914 }else{
915 $new['INFO'] = "";
916 }
917 $new['STATUS']= "ADDED";
918 $all[$folder_id]['ENTRIES'][] = $new;
919 }
920 }
923 /*! \brief Add the application identified by $app_id to folder $folder_id
924 @param String folder_id The UNIQID of the folder where we want to add the new folder.
925 @param Integer app_id The ID of the application which should be added.
926 */
927 function _add_seperator($folder_id)
928 {
929 $all = $this->_get_all_entries();
930 if($folder_id == "BASE"){
931 $folder_id = $this->_get_release_key($this->FAIrelease);
932 }
934 if(isset($all[$folder_id])){
935 $new = array();
936 $new['TYPE'] = "SEPERATOR";
937 $new['NAME'] = "SEPERATOR";
938 $new['UNIQID']= uniqid();
939 $new['PARENT']= $folder_id;
940 $new['PARAMETER']= array();
941 $new['STATUS']= "ADDED";
942 $all[$folder_id]['ENTRIES'][] = $new;
943 }
944 }
947 /*! \brief Return all entries linear.
948 @param Boolean $add_tags If TRUE, OPEN/CLOSE Tags will be appended.
949 @param &Array Start here, Pointer to an array.
950 */
951 function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, &$cur = NULL)
952 {
953 $ret = array();
954 if($cur == NULL){
955 $cur = &$this->a_Structure;
956 }
957 foreach($cur as $key => $entry){
959 if($skip_release && $entry['TYPE'] == "RELEASE"){
960 continue;
961 }
962 if($entry['TYPE'] == "ENTRY"){
963 $found = FALSE;
964 foreach($this->apps as $app){
965 if($app['cn'][0] == $entry['NAME']){
966 $found = TRUE;
967 if(isset($app['description'][0])){
968 $entry['INFO'] = "[".$app['description'][0]."]";
969 }
970 break;
971 }
972 }
973 if(!$found){
974 $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
975 }
976 }
979 $tmp = $entry;
980 if(!$add_tags){
981 $ret[$tmp['UNIQID']] = &$cur[$key];
982 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
983 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
984 }
985 }else{
987 if(isset($tmp['ENTRIES'])){
988 unset($tmp['ENTRIES']);
989 }
990 if($tmp['STATUS'] != "REMOVED"){
991 $ret[] = $tmp;
992 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
993 $add = false;
994 foreach($entry['ENTRIES'] as $entry){
995 if($entry['STATUS'] != "REMOVED"){
996 $add = TRUE;
997 break;
998 }
999 }
1001 if($add){
1002 $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
1003 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1004 $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
1005 }
1006 }
1007 }
1008 }
1009 }
1010 return($ret);
1011 }
1014 function save()
1015 {
1016 $ldap = $this->config->get_ldap_link();
1017 $all = $this->_get_all_entries();
1018 $prio = 0;
1019 $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
1021 $sep_id = 0;
1022 foreach($all as $entry){
1023 $prio ++;
1024 $cur = $entry;
1025 $dn = "";
1027 do{
1028 if($cur['TYPE'] == "SEPERATOR"){
1029 $sep_id ++;
1030 $dn.= "cn=seperator_".$sep_id.",";
1031 }elseif($cur['TYPE'] == "ENTRY"){
1032 $dn.= "cn=".$cur['NAME'].",";
1033 }elseif($cur['TYPE'] == "FOLDER"){
1034 $dn.= "cn=".$cur['NAME'].",";
1035 }elseif($cur['TYPE'] == "RELEASE"){
1036 $dn.= "ou=".$cur['NAME'].",";
1037 }elseif($cur['TYPE'] == "BASE"){
1038 }
1039 if(!isset($all[$cur['PARENT']])){
1040 $cur = NULL;
1041 }else{
1042 $cur = $all[$cur['PARENT']];
1043 }
1044 }while(is_array($cur));
1046 $cur_dn = $dn.$this->dn;
1048 $attrs = array();
1050 switch($entry['TYPE']){
1051 case "SEPERATOR" :
1052 {
1053 $attrs['objectClass'] = array("gotoMenuEntry");
1054 $attrs['cn'] = "seperator_".$sep_id;
1055 $attrs['gosaApplicationPriority'] = $prio;
1056 $attrs['gosaApplicationParameter'] = "*separator*";
1057 }
1058 break;
1059 case "ENTRY" :
1060 {
1061 $attrs['objectClass'] = array("gotoMenuEntry");
1062 $attrs['cn'] = $entry['NAME'];
1063 $attrs['gosaApplicationPriority'] = $prio;
1064 $attrs['gosaApplicationParameter'] = array();
1067 foreach($entry['PARAMETER'] as $name => $value){
1068 $attrs['gosaApplicationParameter'][] = $name.":".$value;
1069 }
1070 if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1071 unset($attrs['gosaApplicationParameter']);
1072 }
1073 }
1074 break;
1075 case "FOLDER" :
1076 {
1077 $attrs['objectClass'] = array("gotoSubmenuEntry");
1078 $attrs['cn'] = $entry['NAME'];
1079 $attrs['gosaApplicationPriority'] = $prio;
1080 if($entry['STATUS'] != "ADDED"){
1081 $attrs['gosaApplicationIcon'] = array();
1082 }
1084 if(!empty($entry['ICON'])){
1085 $attrs['gosaApplicationIcon'] = $entry['ICON'];
1086 }
1087 }
1088 break;
1089 case "RELEASE" :
1090 {
1091 $attrs['ou'] = $entry['NAME'];
1092 $attrs['objectClass'] = array();
1093 $attrs['objectClass'][] = "top";
1094 $attrs['objectClass'][] = "organizationalUnit";
1095 $attrs['objectClass'][] = "FAIbranch";
1096 if(!empty($entry['FAIstate'])){
1097 $attrs['FAIstate'] = $entry['FAIstate'];
1098 }
1099 }
1100 break;
1101 }
1103 /* Append missing ObjectClasses, ... Tagging */
1104 if(isset($entry['LDAP_ATTRS'])){
1105 for($i = 0 ; $i < $entry['LDAP_ATTRS']['objectClass']['count']; $i ++){
1106 $oc = $entry['LDAP_ATTRS']['objectClass'][$i];
1107 if(!in_array($oc,$attrs['objectClass'])){
1108 $attrs['objectClass'][] = $oc;
1109 }
1110 }
1111 }
1114 if($entry['STATUS'] == "LOADED"){
1115 continue;
1116 }
1117 if($entry['STATUS'] == "REMOVED"){
1118 if(isset($entry['DN'])){
1119 $Actions['Remove'][$entry['DN']] = $entry['DN'];
1120 }else{
1121 $Actions['Remove'][$cur_dn] = $cur_dn;
1122 }
1123 }
1124 if($entry['STATUS'] == "EDITED"){
1125 $Actions['Edit'][$cur_dn] = $attrs;
1126 }
1127 if($entry['STATUS'] == "ADDED"){
1128 $Actions['Add'][$cur_dn] = $attrs;
1129 }
1130 }
1132 $ldap = $this->config->get_ldap_link();
1133 $ldap->cd($this->config->current['BASE']);
1134 foreach($Actions['Remove'] as $dn){
1135 $ldap->cd($dn);
1136 $ldap->cat($dn);
1137 if($ldap->count()){
1138 $ldap->rmdir_recursive($dn);
1139 if (!$ldap->success()){
1140 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1141 }
1142 }
1143 }
1144 foreach($Actions['Add'] as $dn => $data){
1145 $ldap->cd($dn);
1146 $ldap->cat($dn);
1147 if(!$ldap->count()){
1148 $ldap->add($data);
1149 if (!$ldap->success()){
1150 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1151 }
1152 }
1153 }
1154 foreach($Actions['Edit'] as $dn => $data){
1155 $ldap->cd($dn);
1156 $ldap->cat($dn);
1157 if($ldap->count()){
1158 $ldap->modify($data);
1159 if (!$ldap->success()){
1160 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1161 }
1162 }
1163 }
1165 $this->_load_menu_structure();
1166 }
1169 /* Return plugin informations for acl handling */
1170 static function plInfo()
1171 {
1172 return (array(
1173 "plShortName" => _("Applications"),
1174 "plDescription" => _("Group applications"),
1175 "plSelfModify" => FALSE,
1176 "plDepends" => array(),
1177 "plPriority" => 0,
1178 "plSection" => array("admin"),
1179 "plCategory" => array("groups"),
1180 "plProvidedAcls"=> array(
1181 "gosaMemberApplication" => _("Application"),
1182 "FAIrelease" => _("Release"),
1183 "gosaApplicationParameter" => _("Application parameter"))
1184 ));
1185 }
1188 function PrepareForCopyPaste($source)
1189 {
1190 plugin::PrepareForCopyPaste($source);
1192 $tmp = new appgroup($this->config,$source['dn']);
1193 $this->is_account = TRUE;
1194 $this->a_Structure = $tmp->a_Structure;
1195 $all = $this->_get_all_entries();
1196 foreach($all as &$entry){
1197 if(isset($entry['STATUS'])){
1198 $entry['STATUS'] = "ADDED";
1199 }
1200 }
1201 }
1204 function multiple_save_object()
1205 {
1206 if(isset($_POST['group_apps_multi'])){
1207 $this->save_object();
1208 plugin::multiple_save_object();
1210 /* Get posts */
1211 foreach(array("apps") as $attr){
1212 if(isset($_POST['use_'.$attr])) {
1213 $this->multi_boxes[] = $attr;
1214 }
1215 }
1216 }
1217 }
1220 function get_multi_edit_values()
1221 {
1222 $ret = plugin::get_multi_edit_values();
1224 if(in_array("apps",$this->multi_boxes)){
1225 $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1226 $ret['Categories'] = $this->Categories;
1227 $ret['gosaMemberApplication'] = $this->gosaMemberApplication;
1228 $ret['FAIrelease'] = $this->FAIrelease;
1229 $ret['appoption'] = $this->appoption;
1230 }
1231 return($ret);
1232 }
1233 }
1234 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1235 ?>