d522abcf3067190d8f31eb2caa6e44890c0dd48e
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/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 }
539 /*! \brief Create missing releases, if there is a release selected \
540 that is currently not part of the menu structure \
541 then create this entry
542 */
543 function _check_missing_release($release)
544 {
545 $release_info = $this->Releases[$release];
547 $parent_id = $this->a_Structure[0]['UNIQID'];
548 $cur = &$this->a_Structure[0]['ENTRIES'];
549 for($i = 0 ; $i < count($release_info['parts']) ; $i ++){
550 $part = $release_info['parts'][$i];
551 $found = FALSE;
552 foreach($cur as $key => $name){
553 if($name['NAME'] == $part){
554 $parent_id = $cur[$key]['UNIQID'];
555 $cur = &$cur[$key]['ENTRIES'];
557 $found =TRUE;
558 break;
559 }
560 }
561 if(!$found){
562 $release = array();
563 $release['UNIQID'] = uniqid();
564 $release['PARENT'] = $parent_id;
565 $release['NAME'] = $part;
566 $release['TYPE'] = "RELEASE";
567 $release['ENTRIES']= array();
568 $release['STATUS'] = "ADDED";
569 $release['FAIstate'] = $release_info['FAIstate'];
570 $cur[] = $release;
571 $i --;
572 }
573 }
574 }
578 function _move_entry($id,$dir)
579 {
580 $all = $this->_get_all_entries();
581 if($dir == "down"){
582 $to = $this->_get_next($id);
583 }
584 if($dir == "up"){
585 $to = $this->_get_last($id);
586 }
588 if(!$to){
589 return;
590 }
592 $o_to = $all[$to];
593 $o_from = $all[$id];
595 if($o_to['PARENT'] == $o_from['UNIQID'] && $dir == "down"){
596 $to = $this->_get_next($to,$o_from['PARENT']);
597 $o_to = $all[$to];
598 }
601 /* Target is ENTRY && same BASE, just switch */
602 if($o_to['PARENT'] == $o_from['PARENT'] ){
603 $parent = $all[$o_to['PARENT']];
604 $pos = 0;
605 foreach($parent['ENTRIES'] as $entry){
606 $pos ++;
607 if($entry['UNIQID'] == $to){
608 break;
609 }
610 }
611 if($dir == "up" && $pos > 0){
612 $pos --;
613 }
614 $this->_add_entry($parent['UNIQID'],$o_from,$pos);
615 $this->_remove_entry_id($id);
616 return(TRUE);
617 }
618 return(FALSE);
619 }
623 function _get_last($id)
624 {
625 $all_l = array_reverse($this->_get_entries_for_release($this->FAIrelease));
626 for($i = 0 ; $i < count($all_l) ; $i ++){
627 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
628 $i++;
629 break;
630 }
631 }
632 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER","CLOSE","OPEN")) && $i < count($all_l)){
633 $i++;
634 }
636 if(!isset($all_l[$i])){
637 return(FALSE);
638 }
640 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
641 return($all_l[$i]['PARENT']);
642 }
644 return($all_l[$i]['UNIQID']);
645 }
648 function _get_next($id,$parent = 0)
649 {
650 $all_l = $this->_get_entries_for_release($this->FAIrelease);
651 for($i = 0 ; $i < count($all_l) ; $i ++){
652 if(isset($all_l[$i]['UNIQID']) && $all_l[$i]['UNIQID'] == $id){
653 $i++;
654 break;
655 }
656 }
657 if($parent != 0){
658 while(isset($all_l[$i]) && $all_l[$i]['PARENT'] != $parent){
659 $i++;
660 }
661 }else{
662 while(isset($all_l[$i]) && !in_array($all_l[$i]['TYPE'],array("ENTRY","FOLDER")) && $i < count($all_l)){
663 $i++;
664 }
665 }
666 if(!isset($all_l[$i])){
667 return(FALSE);
668 }
669 if(in_array($all_l[$i]['TYPE'],array("CLOSE","OPEN"))){
670 return($all_l[$i]['PARENT']);
671 }
672 return($all_l[$i]['UNIQID']);
673 }
678 /* !\brief Handle ui POSTS, like sort up/down/delete
679 */
680 function save_object()
681 {
682 foreach($_POST as $name => $value){
683 if(preg_match("/del_/",$name)){
684 $id = preg_replace("/^del_/","",$name);
685 $id = preg_replace("/_(x|y)$/","",$id);
686 $this->_remove_entry_id($id);
687 break;
688 }
689 if(preg_match("/app_entry_edit/",$name)){
690 $id = preg_replace("/^app_entry_edit/","",$name);
691 $id = preg_replace("/_(x|y)$/","",$id);
692 $this->_edit_entry_edit($id);
693 break;
694 }
695 if(preg_match("/up_/",$name)){
696 $id = preg_replace("/^up_/","",$name);
697 $id = preg_replace("/_(x|y)$/","",$id);
698 $this->_move_entry($id,"up");
699 break;
700 }
701 if(preg_match("/down_/",$name)){
702 $id = preg_replace("/^down_/","",$name);
703 $id = preg_replace("/_(x|y)$/","",$id);
704 $this->_move_entry($id,"down");
705 break;
706 }
707 if(preg_match("/^parameter_/",$name) &&
708 count($this->edit_entry) && $this->edit_entry['TYPE'] == "ENTRY"){
709 $name = preg_replace("/^parameter_/","",$name);
710 $this->app_parameter[$name] = $value;
711 }
712 }
713 if(isset($_POST['FAIrelease'])){
714 $this->FAIrelease = $_POST['FAIrelease'];
715 $this->_check_missing_release($this->FAIrelease);
716 }
717 if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
718 $this->curbase = base64_decode($_GET['depid']);
719 }
720 if(isset($_POST['add_to_folder']) && isset($_POST['folder'])){
721 $folder = $_POST['folder'];
722 foreach($_POST as $name => $value){
723 if(preg_match("/^AddApp_[0-9]*$/",$name)){
724 $this->_add_app_id($folder,preg_replace("/^AddApp_/","",$name));
725 }
726 }
727 }
729 /* Add seperator */
730 if(isset($_POST['add_seperator']) && isset($_POST['menu_folder'])){
731 $folder = $_POST['menu_folder'];
732 $this->_add_seperator($folder);
733 }
735 if(isset($_POST['add_menu_to_folder']) && isset($_POST['menu_folder'])){
736 $folder = $_POST['menu_folder'];
737 $name = $_POST['menu_folder_name'];
738 if(strlen($name) > 0 && preg_match("/[a-z ]/i",$name)){
739 $this->_add_sub_folder($folder,$name);
740 }
741 }
742 if(isset($_POST['app_entry_save'])){
743 $this->_save_entry_edit();
744 }
746 if(isset($_FILES['folder_image']) && isset($_POST['folder_image_upload'])){
747 if($_FILES['folder_image']['error'] == 0 && $_FILES['folder_image']['size'] > 0){
748 $this->edit_entry['ICON'] = file_get_contents($_FILES['folder_image']['tmp_name']);
749 }
750 }
752 if(isset($_POST['edit_reset_image'])){
753 $this->edit_entry['ICON'] = "";
754 }
756 if(isset($_POST['app_entry_cancel'])){
757 $this->edit_entry = array();
758 $this->dialog = FALSE;
759 }
760 $this->reload();
761 }
764 /*! \brief Returns the UNIQID of the currently selected release
765 */
766 function _get_release_key($release,$add_if_missing = FALSE)
767 {
768 $release_info = $this->Releases[$release];
770 if($release_info['name'] == "/"){
771 return($this->a_Structure['0']['UNIQID']);
772 }
774 $cur = &$this->a_Structure[0]['ENTRIES'];
775 $s_key = "";
776 $found = FALSE;
777 foreach($release_info['parts'] as $name){
778 foreach($cur as $key => $obj){
779 if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
780 $s_key = $cur[$key]['UNIQID'];
781 $cur = &$cur[$key]['ENTRIES'];
782 $found = TRUE;
783 break;
784 }
785 $found = FALSE;
786 }
787 }
788 if($found){
789 return($s_key);
790 }
791 return(FALSE);
792 }
795 /*! \brief Add a new folder folder to the specified folder id
796 @param String $folder The folder id in where we want to add the new folder.
797 @param String $name The name of the new folder.
798 */
799 function _add_sub_folder($folder,$name)
800 {
801 $all = $this->_get_all_entries();
802 if($folder == "BASE"){
803 $folder = $this->_get_release_key($this->FAIrelease,TRUE);
804 }
806 if(isset($all[$folder])){
807 $a_folder = array();
808 $a_folder['STATUS'] = "ADDED";
809 $a_folder['NAME'] = $name;
810 $a_folder['UNIQID'] = uniqid();
811 $a_folder['ENTRIES']= array();
812 $a_folder['PARENT'] = $folder;
813 $a_folder['TYPE'] = "FOLDER";
814 $a_folder['ICON'] = "";
815 $all[$folder]['ENTRIES'][] = $a_folder;
816 }
817 }
820 /* !\brief Remove the given id from the menu structure.
821 @param String ID to of the entry we want to remove.
822 @return Boolean TRUE on success
823 */
824 function _remove_entry_id($id)
825 {
826 $all = $this->_get_all_entries();
827 if(isset($all[$id])){
828 $all[$id]['STATUS'] = "REMOVED";
829 $all[$id]['ENTRIES'] = array();
830 return(TRUE);
831 }
832 return(FALSE);
833 }
836 /* !\brief Remove the given id from the menu structure.
837 @param String ID to of the entry we want to remove.
838 @return Boolean TRUE on success
839 */
840 function _add_entry($folder_id,$entry,$pos = 0)
841 {
842 $all = $this->_get_all_entries();
844 /* Do not add removed */
845 if($entry['STATUS'] == "REMOVED"){
846 return;
847 }
849 if(isset($all[$folder_id])){
851 if(!isset($entry['ENTRIES'])){
852 $entries = array();
853 }else{
854 $entries = $entry['ENTRIES'];
855 }
857 $folder = &$all[$folder_id];
859 $entry['UNIQID'] = uniqid();
860 $entry['PARENT'] = $folder_id;
861 $entry['ENTRIES']= array();
862 $entry['STATUS'] = "ADDED";
864 $cnt = 0;
865 $new = array();
866 $added =FALSE;
867 foreach($folder['ENTRIES'] as $key => $obj){
868 if($obj['STATUS'] == "LOADED"){
869 $obj['STATUS'] = "EDITED";
870 }
871 if($pos == $cnt){
872 $new[] = $entry;
873 $added = TRUE;
874 }
875 $cnt ++;
876 $new[] = $obj;
877 }
878 if(!$added){
879 $new[] = $entry;
880 }
882 $all[$folder_id]['ENTRIES'] = $new;
883 foreach($entries as $sub){
884 $this->_add_entry($entry['UNIQID'],$sub,-1);
885 }
886 return(TRUE);
887 }
888 return(FALSE);
889 }
892 /*! \brief Add the application identified by $app_id to folder $folder_id
893 @param String folder_id The UNIQID of the folder where we want to add the new folder.
894 @param Integer app_id The ID of the application which should be added.
895 */
896 function _add_app_id($folder_id,$app_id)
897 {
898 $all = $this->_get_all_entries();
899 if($folder_id == "BASE"){
900 $folder_id = $this->_get_release_key($this->FAIrelease);
901 }
902 if(isset($all[$folder_id]) && isset($this->apps[$app_id])){
904 $new = array();
905 $new['TYPE'] = "ENTRY";
906 $new['NAME'] = $this->apps[$app_id]['cn'][0];
907 $new['UNIQID']= uniqid();
908 $new['PARENT']= $folder_id;
909 $new['PARAMETER']= array();
910 if(isset($this->apps[$app_id]['description'][0])){
911 $new['INFO'] = $this->apps[$app_id]['description'][0];
912 }else{
913 $new['INFO'] = "";
914 }
915 $new['STATUS']= "ADDED";
916 $all[$folder_id]['ENTRIES'][] = $new;
917 }
918 }
921 /*! \brief Add the application identified by $app_id to folder $folder_id
922 @param String folder_id The UNIQID of the folder where we want to add the new folder.
923 @param Integer app_id The ID of the application which should be added.
924 */
925 function _add_seperator($folder_id)
926 {
927 $all = $this->_get_all_entries();
928 if($folder_id == "BASE"){
929 $folder_id = $this->_get_release_key($this->FAIrelease);
930 }
932 if(isset($all[$folder_id])){
933 $new = array();
934 $new['TYPE'] = "SEPERATOR";
935 $new['NAME'] = "SEPERATOR";
936 $new['UNIQID']= uniqid();
937 $new['PARENT']= $folder_id;
938 $new['PARAMETER']= array();
939 $new['STATUS']= "ADDED";
940 $all[$folder_id]['ENTRIES'][] = $new;
941 }
942 }
945 /*! \brief Return all entries linear.
946 @param Boolean $add_tags If TRUE, OPEN/CLOSE Tags will be appended.
947 @param &Array Start here, Pointer to an array.
948 */
949 function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, &$cur = NULL)
950 {
951 $ret = array();
952 if($cur == NULL){
953 $cur = &$this->a_Structure;
954 }
955 foreach($cur as $key => $entry){
957 if($skip_release && $entry['TYPE'] == "RELEASE"){
958 continue;
959 }
960 if($entry['TYPE'] == "ENTRY"){
961 $found = FALSE;
962 foreach($this->apps as $app){
963 if($app['cn'][0] == $entry['NAME']){
964 $found = TRUE;
965 if(isset($app['description'][0])){
966 $entry['INFO'] = "[".$app['description'][0]."]";
967 }
968 break;
969 }
970 }
971 if(!$found){
972 $entry['INFO'] = "<font color='red'>"._("Not available in release.")."</font>";
973 }
974 }
977 $tmp = $entry;
978 if(!$add_tags){
979 $ret[$tmp['UNIQID']] = &$cur[$key];
980 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
981 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
982 }
983 }else{
985 if(isset($tmp['ENTRIES'])){
986 unset($tmp['ENTRIES']);
987 }
988 if($tmp['STATUS'] != "REMOVED"){
989 $ret[] = $tmp;
990 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
991 $add = false;
992 foreach($entry['ENTRIES'] as $entry){
993 if($entry['STATUS'] != "REMOVED"){
994 $add = TRUE;
995 break;
996 }
997 }
999 if($add){
1000 $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['PARENT']);
1001 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,$cur[$key]['ENTRIES']));
1002 $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['PARENT']);
1003 }
1004 }
1005 }
1006 }
1007 }
1008 return($ret);
1009 }
1012 function save()
1013 {
1014 $ldap = $this->config->get_ldap_link();
1015 $all = $this->_get_all_entries();
1016 $prio = 0;
1017 $Actions = array("Remove" => array(),"Edit" => array() , "Add" => array());
1019 $sep_id = 0;
1020 foreach($all as $entry){
1021 $prio ++;
1022 $cur = $entry;
1023 $dn = "";
1025 do{
1026 if($cur['TYPE'] == "SEPERATOR"){
1027 $sep_id ++;
1028 $dn.= "cn=seperator_".$sep_id.",";
1029 }elseif($cur['TYPE'] == "ENTRY"){
1030 $dn.= "cn=".$cur['NAME'].",";
1031 }elseif($cur['TYPE'] == "FOLDER"){
1032 $dn.= "cn=".$cur['NAME'].",";
1033 }elseif($cur['TYPE'] == "RELEASE"){
1034 $dn.= "ou=".$cur['NAME'].",";
1035 }elseif($cur['TYPE'] == "BASE"){
1036 }
1037 if(!isset($all[$cur['PARENT']])){
1038 $cur = NULL;
1039 }else{
1040 $cur = $all[$cur['PARENT']];
1041 }
1042 }while(is_array($cur));
1044 $cur_dn = $dn.$this->dn;
1046 $attrs = array();
1048 switch($entry['TYPE']){
1049 case "SEPERATOR" :
1050 {
1051 $attrs['objectClass'] = array("gotoMenuEntry");
1052 $attrs['cn'] = "seperator_".$sep_id;
1053 $attrs['gosaApplicationPriority'] = $prio;
1054 $attrs['gosaApplicationParameter'] = "*separator*";
1055 }
1056 break;
1057 case "ENTRY" :
1058 {
1059 $attrs['objectClass'] = array("gotoMenuEntry");
1060 $attrs['cn'] = $entry['NAME'];
1061 $attrs['gosaApplicationPriority'] = $prio;
1062 $attrs['gosaApplicationParameter'] = array();
1065 foreach($entry['PARAMETER'] as $name => $value){
1066 $attrs['gosaApplicationParameter'][] = $name.":".$value;
1067 }
1068 if($entry['STATUS'] == "ADDED" && !count($attrs['gosaApplicationParameter'])){
1069 unset($attrs['gosaApplicationParameter']);
1070 }
1071 }
1072 break;
1073 case "FOLDER" :
1074 {
1075 $attrs['objectClass'] = array("gotoSubmenuEntry");
1076 $attrs['cn'] = $entry['NAME'];
1077 $attrs['gosaApplicationPriority'] = $prio;
1078 if($entry['STATUS'] != "ADDED"){
1079 $attrs['gosaApplicationIcon'] = array();
1080 }
1082 if(!empty($entry['ICON'])){
1083 $attrs['gosaApplicationIcon'] = $entry['ICON'];
1084 }
1085 }
1086 break;
1087 case "RELEASE" :
1088 {
1089 $attrs['ou'] = $entry['NAME'];
1090 $attrs['objectClass'] = array();
1091 $attrs['objectClass'][] = "top";
1092 $attrs['objectClass'][] = "organizationalUnit";
1093 $attrs['objectClass'][] = "FAIbranch";
1094 if(!empty($entry['FAIstate'])){
1095 $attrs['FAIstate'] = $entry['FAIstate'];
1096 }
1097 }
1098 break;
1099 }
1101 /* Append missing ObjectClasses, ... Tagging */
1102 if(isset($entry['LDAP_ATTRS'])){
1103 for($i = 0 ; $i < $entry['LDAP_ATTRS']['objectClass']['count']; $i ++){
1104 $oc = $entry['LDAP_ATTRS']['objectClass'][$i];
1105 if(!in_array($oc,$attrs['objectClass'])){
1106 $attrs['objectClass'][] = $oc;
1107 }
1108 }
1109 }
1111 if($entry['STATUS'] == "LOADED"){
1112 continue;
1113 }
1114 if($entry['STATUS'] == "REMOVED"){
1115 if(isset($entry['DN'])){
1116 $Actions['Remove'][$entry['DN']] = $entry['DN'];
1117 }else{
1118 $Actions['Remove'][$cur_dn] = $cur_dn;
1119 }
1120 }
1121 if($entry['STATUS'] == "EDITED"){
1122 $Actions['Edit'][$cur_dn] = $attrs;
1123 }
1124 if($entry['STATUS'] == "ADDED"){
1125 $Actions['Add'][$cur_dn] = $attrs;
1126 }
1127 }
1129 $ldap = $this->config->get_ldap_link();
1130 $ldap->cd($this->config->current['BASE']);
1131 foreach($Actions['Remove'] as $dn){
1132 $ldap->cd($dn);
1133 $ldap->cat($dn);
1134 if($ldap->count()){
1135 $ldap->rmdir_recursive($dn);
1136 if (!$ldap->success()){
1137 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1138 }
1139 }
1140 }
1141 foreach($Actions['Add'] as $dn => $data){
1142 $ldap->cd($dn);
1143 $ldap->cat($dn);
1144 if(!$ldap->count()){
1145 $ldap->add($data);
1146 if (!$ldap->success()){
1147 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1148 }
1149 }
1150 }
1151 foreach($Actions['Edit'] as $dn => $data){
1152 $ldap->cd($dn);
1153 $ldap->cat($dn);
1154 if($ldap->count()){
1155 $ldap->modify($data);
1156 if (!$ldap->success()){
1157 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, LDAP_DEL, get_class()));
1158 }
1159 }
1160 }
1162 $this->_load_menu_structure();
1163 }
1166 /* Return plugin informations for acl handling */
1167 static function plInfo()
1168 {
1169 return (array(
1170 "plShortName" => _("Applications"),
1171 "plDescription" => _("Group applications"),
1172 "plSelfModify" => FALSE,
1173 "plDepends" => array(),
1174 "plPriority" => 0,
1175 "plSection" => array("admin"),
1176 "plCategory" => array("groups"),
1177 "plProvidedAcls"=> array(
1178 "gosaMemberApplication" => _("Application"),
1179 "FAIrelease" => _("Release"),
1180 "gosaApplicationParameter" => _("Application parameter"))
1181 ));
1182 }
1185 function PrepareForCopyPaste($source)
1186 {
1187 }
1190 function multiple_save_object()
1191 {
1192 if(isset($_POST['group_apps_multi'])){
1193 $this->save_object();
1194 plugin::multiple_save_object();
1196 /* Get posts */
1197 foreach(array("apps") as $attr){
1198 if(isset($_POST['use_'.$attr])) {
1199 $this->multi_boxes[] = $attr;
1200 }
1201 }
1202 }
1203 }
1206 function get_multi_edit_values()
1207 {
1208 $ret = plugin::get_multi_edit_values();
1210 if(in_array("apps",$this->multi_boxes)){
1211 $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1212 $ret['Categories'] = $this->Categories;
1213 $ret['gosaMemberApplication'] = $this->gosaMemberApplication;
1214 $ret['FAIrelease'] = $this->FAIrelease;
1215 $ret['appoption'] = $this->appoption;
1216 }
1217 return($ret);
1218 }
1219 }
1220 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1221 ?>