1 <?php
2 class appgroup2 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 public function __construct(&$config, $dn= NULL, $parent= NULL)
23 {
24 plugin::plugin($config,$dn,$parent);
25 $this->dn = $dn;
26 $this->_load_menu_structure();
27 $this->a_Structure_on_load = $this->a_Structure;
29 /* Check if we have relase mangement enabled and prepare group application for release management */
30 $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
31 if(!empty($tmp)){
32 $this->enableReleaseManagement = true;
33 }
35 /* Get required release informations */
36 if($this->enableReleaseManagement){
37 $this->Releases = $this->getReleases();
38 $this->FAIrelease = 0;
39 }
40 $this->curbase = $this->config->current['BASE'];
41 $this->reload();
42 }
45 function reload()
46 {
47 $ret = array();
48 $release_info = $this->Releases[$this->FAIrelease];
50 if(!isset($this->_cache['ReleaseApps'][$release_info['suffix']])){
52 $ldap = $this->config->get_ldap_link();
53 $ldap->cd($this->curbase);
54 $ldap->search("ou=apps",array("dn"));
55 $app_deps = array();
56 while($attrs = $ldap->fetch()){
57 $app_deps[] = $attrs['dn'];
58 }
60 foreach($app_deps as $dep){
61 $ldap->cd($dep);
62 $ldap->search("objectClass=FAIbranch",array("dn"));
63 while($attrs = $ldap->fetch()){
64 $app_deps[] = $attrs['dn'];
65 }
66 }
68 foreach($app_deps as $dep){
69 if(preg_match("/^".normalizePreg($release_info['suffix'])."/",$dep)){
70 $ret = array_merge($ret,get_list("(objectClass=gosaApplication)","application",$dep,array("*"),GL_NONE));
71 }
72 }
73 $this->_cache['ReleaseApps'][$release_info['suffix']] = $ret;
74 }
75 $this->apps = $this->_cache['ReleaseApps'][$release_info['suffix']];
76 }
79 function getReleases()
80 {
81 /* Only display those releases that we are able to read */
82 $dn = $this->config->current['BASE'];
83 $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
84 $res = get_list($filter,"application", $dn, array("ou"), GL_SUBSEARCH);
86 $ret =array(array("name" => "/" , "parts" => array(),"suffix" => get_ou('applicationou')));
87 foreach($res as $attrs){
88 if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
89 $bb = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
90 $parts = array_reverse(split("ou=",$bb));
92 $str ="";
93 foreach($parts as $key => $part){
94 if(empty($part)) {
95 unset($parts[$key]);
96 continue;
97 }
98 $part = str_replace(",","",$part);
99 $str .= $part."/";
100 $parts[$key] = $part;
101 }
102 $name = preg_replace("/\/$/","",$str);
103 if(empty($name)) {
104 $name ="/";
105 }
106 $ret[] = array("name" => $name , "dn" => $attrs['dn'], "parts" => $parts,"suffix" => $bb.get_ou('applicationou'));
107 }
108 }
109 return($ret);
110 }
113 function getReleases2()
114 {
115 $ret = array();
116 $ret['/'] = array("UNIQID" => 0, "NAME" => "/");
117 $tmp = $this->_get_all_entries();
118 foreach($tmp as $entry){
119 if($entry['TYPE'] == "RELEASE"){
120 unset($entry['ENTRIES']);
121 $ret[] = $entry;
122 }
123 }
124 return($ret);
125 }
128 function _load_menu_structure()
129 {
130 $this->a_Structure = array();
131 $ldap = $this->config->get_ldap_link();
132 $ldap->cd($this->dn);
133 $ldap->search("(|(objectClass=gotoSubmenuEntry)(objectClass=FAIbranch)(objectClass=gotoMenuEntry))",array("*"));
134 $parent_id = 0;
135 while($attrs = $ldap->fetch()){
136 $cur = &$this->a_Structure;
137 $sub_dn = preg_replace("/,".normalizePreg($this->dn)."$/","",$attrs['dn']);
138 $sub_dn_array = split("\,",$sub_dn);
139 for($i = (count($sub_dn_array)-1) ; $i >= 0 ; $i--){
140 $name = preg_replace("/^[^=]*+=/","",$sub_dn_array[$i]);
141 if($i != 0){
142 foreach($cur as $key => $entry){
143 if($entry['NAME'] == $name){
144 $cur = &$cur[$key]['ENTRIES'];
145 $parent_id = $entry['UNIQID'];
146 }
147 }
148 }else{
150 $priority = 1;
151 if(isset($attrs['gosaApplicationPriority'])){
152 $priority= $attrs['gosaApplicationPriority'][0];
153 }
154 while(isset($cur[$priority])){
155 $priority ++;
156 }
158 if(in_array("gotoSubmenuEntry",$attrs['objectClass'])){
159 $type = "FOLDER";
160 }elseif(in_array("gotoMenuEntry",$attrs['objectClass'])){
161 $type = "ENTRY";
162 }elseif(in_array("FAIbranch",$attrs['objectClass'])){
163 $type = "RELEASE";
164 }
166 $data = array();
167 $data['DN'] = $attrs['dn'];
168 $data['NAME'] = $name;
169 $data['TYPE'] = $type;
170 $data['PRIORITY'] = $priority;
171 $data['ENTRIES'] = array();
172 $data['UNIQID'] = uniqid();
173 $data['PARENT'] = $parent_id;
174 $cur[$priority] = $data;
175 ksort($cur);
176 }
177 }
178 }
179 }
182 function execute()
183 {
184 /* Call parent execute */
185 plugin::execute();
187 if(isset($_GET['r']))
188 $this->__construct($this->config,$this->dn);
190 $smarty = get_smarty();
192 /* Create application list */
193 $div = new divSelectBox("appgroup");
194 $div->SetHeight(300);
195 $departments = array();
196 $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
197 foreach($res as $value){
198 $fdn = $value['dn'];
199 $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
200 $fdn= @LDAP::fix($fdn);
201 if($value["description"][0]!=".."){
202 $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
203 }else{
204 $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
205 }
206 }
208 /* Create 'open' and 'add' links */
209 # if($this->acl_is_writeable("gosaMemberApplication",$this->no_release_acls)){
210 $linkadd = "<a href='?plug=".$_GET['plug']."&act=add&id=%s'>%s</a>";
211 # }else{
212 # $linkadd = "%s";
213 # }
214 $linkopen = "<a href='?plug=".$_GET['plug']."&act=depopen&depid=%s'>%s</a>";
216 /* Create base back entry */
217 $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
218 if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
219 $div->AddEntry(array(
220 array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
221 "attach"=>"style='border:0px;'")
222 ));
223 }
225 /* Append departments for current base */
226 foreach($departments as $key => $app){
227 $div->AddEntry(array(
228 array("string"=>"<img class='center' src='images/folder.png' alt='"._("department")."'> ".sprintf($linkopen,
229 base64_encode($key),$app),
230 "attach"=>"style='border:0px;'")
231 ));
232 }
235 /* Add applications found on this base */
236 $used_apps = $this->_get_used_entry_name();
237 foreach($this->apps as $key => $app){
238 if(in_array($app['cn'][0],$used_apps)){
239 continue;
240 }
241 if(!preg_match("/".get_ou('applicationou').normalizePreg($this->curbase)."$/",$app['dn'])){
242 continue;
243 }
245 $name = $app['cn'][0];
246 if(isset($app['description'])){
247 $name .= " [".$app['description'][0]."]";
248 }
249 $div->AddEntry(array(
250 array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
251 "<img class='center' src='images/select_application.png' alt='"._("application")."'> ".sprintf($linkadd,$key,$name),
252 "attach"=>"style='border:0px;'")
253 ));
254 }
257 $smarty->assign("FAIrelease",$this->FAIrelease);
258 $smarty->assign("app_list",$div->DrawList());
259 $smarty->assign("releases",$this->Releases);
260 $entries = $this->_get_entries_for_release($this->FAIrelease);
261 $smarty->assign("entries",$entries);
262 $display= $smarty->fetch (get_template_path('app_list.tpl', TRUE, dirname(__FILE__)));
263 return($display);
264 }
267 function _get_used_entry_name()
268 {
269 $data = $this->_get_entries_for_release($this->FAIrelease);
270 $ret = array();
271 foreach($data as $entry){
272 if($entry['TYPE'] == "ENTRY"){
273 $ret[] = $entry['NAME'];
274 }
275 }
276 return($ret);
277 }
279 function _get_entries_for_release($release,$cur = NULL)
280 {
281 $release_info = $this->Releases[$release];
282 $cur = &$this->a_Structure;
284 $found = FALSE;
285 foreach($release_info['parts'] as $name){
286 foreach($cur as $key => $obj){
287 if($obj['TYPE'] == "RELEASE" && $obj['NAME'] == $name){
288 $cur = &$cur[$key]['ENTRIES'];
289 $found = TRUE;
290 break;
291 }
292 $found = FALSE;
293 }
294 }
295 if($found){
296 return($this->_get_all_entries(TRUE,TRUE,$cur));
297 }else{
298 return(array());
299 }
300 }
303 function _edit_entry_edit($id)
304 {
305 }
308 function remove_from_parent()
309 {
310 }
313 function save()
314 {
315 }
318 function check()
319 {
320 }
324 /* !\brief Handle ui POSTS, like sort up/down/delete
325 */
326 function save_object()
327 {
328 foreach($_POST as $name => $value){
329 if(preg_match("/del_/",$name)){
330 $id = preg_replace("/^del_/","",$name);
331 $id = preg_replace("/_(x|y)$/","",$id);
332 $this->_remove_entry_id($id);
333 break;
334 }
335 if(preg_match("/edit_/",$name)){
336 $id = preg_replace("/^edit_/","",$name);
337 $id = preg_replace("/_(x|y)$/","",$id);
338 $this->_edit_entry_edit($id);
339 break;
340 }
341 if(preg_match("/up_/",$name)){
342 $id = preg_replace("/^up_/","",$name);
343 $id = preg_replace("/_(x|y)$/","",$id);
344 $this->_move_entry_up($id);
345 break;
346 }
347 if(preg_match("/down_/",$name)){
348 $id = preg_replace("/^down_/","",$name);
349 $id = preg_replace("/_(x|y)$/","",$id);
350 $this->_move_entry_down($id);
351 break;
352 }
353 }
354 if(isset($_POST['FAIrelease'])){
355 $this->FAIrelease = $_POST['FAIrelease'];
356 }
357 if(isset($_GET['act']) && $_GET['act'] == 'depopen'){
358 $this->curbase = base64_decode($_GET['depid']);
359 }
360 $this->reload();
361 }
364 /* !\brief Remove the given id from the menu structure.
365 @param String ID to of the entry we want to remove.
366 @return Boolean TRUE on success
367 */
368 function _remove_entry_id($id,$start = NULL)
369 {
370 if($start == NULL){
371 $start = &$this->a_Structure;
372 }
373 foreach($start as $name => $entry){
374 if($entry['UNIQID'] == $id){
375 unset($start[$name]);
376 return(TRUE);
377 }
378 if(isset($entry['ENTRIES']) && count($start[$name]['ENTRIES'])){
379 if($this->_remove_entry_id($id,&$start[$name]['ENTRIES'])){
380 return(TRUE);
381 }
382 }
383 }
384 return(FALSE);
385 }
388 /*! \brief move the object identified by the given ID one position up.
389 @param String The ID of the entry to be moved.
390 @return Boolean TRUE on success, else FALSE;
391 */
392 function _move_entry_up($id)
393 {
394 $all = $this->_get_all_entries(TRUE);
395 $parent = FALSE;
396 foreach($all as $entry){
397 if(isset($entry['UNIQID']) && $entry['UNIQID'] == $id){
398 if($parent != FALSE){
399 return($this->__switch_entries($id,"up",$parent));
400 }
401 }else{
402 if(in_array($entry['TYPE'],array("CLOSE","OPEN"))){
403 $parent = $entry['PARENT'];
404 }else{
405 $parent = $entry['UNIQID'];
406 }
407 }
408 }
409 return(FALSE);
410 }
413 /*! \brief move the object identified by the given ID one position down.
414 @param String The ID of the entry to be moved.
415 @return Boolean TRUE on success, else FALSE;
416 */
417 function _move_entry_down($id)
418 {
419 $all = $this->_get_all_entries(TRUE);
420 $found = FALSE;
421 foreach($all as $entry){
422 if(isset($entry['UNIQID']) && $entry['UNIQID'] == $id){
423 $found = TRUE;
424 continue;
425 }else{
426 if(in_array($entry['TYPE'],array("CLOSE","OPEN"))){
427 $parent = $entry['PARENT'];
428 }else{
429 $parent = $entry['UNIQID'];
430 }
431 if($found){
432 return($this->__switch_entries($id,"down",$parent));
433 }
434 }
435 }
436 return(FALSE);
437 }
440 /*! \brief Return all entries linear.
441 @param Boolean $add_tags If TRUE, OPEN/CLOSE Tags will be appended.
442 @param &Array Start here, Pointer to an array.
443 */
444 function _get_all_entries($add_tags = FALSE, $skip_release = FALSE, $cur = NULL)
445 {
446 $ret = array();
447 if($cur == NULL){
448 $cur = &$this->a_Structure;
449 }
450 foreach($cur as $key => $entry){
452 if($skip_release && $entry['TYPE'] == "RELEASE"){
453 continue;
454 }
456 $tmp = $entry;
457 if(!$add_tags){
458 $ret[$tmp['UNIQID']] = &$cur[$key];
459 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
460 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
461 }
462 }else{
463 if(isset($tmp['ENTRIES'])){
464 unset($tmp['ENTRIES']);
465 }
466 $ret[] = $tmp;
467 if(isset($entry['ENTRIES']) && count($entry['ENTRIES'])){
468 $ret[] = array("TYPE" => "OPEN", "PARENT" => $entry['UNIQID']);
469 $ret = array_merge($ret,$this->_get_all_entries($add_tags,$skip_release,&$cur[$key]['ENTRIES']));
470 $ret[] = array("TYPE" => "CLOSE" , "PARENT" => $entry['UNIQID']);
471 }
472 }
473 }
474 return($ret);
475 }
478 /* !\brief Switch one entry with another
479 @param String from The source ID.
480 @param String type "up"/"down" type switched.
481 @param String to The destination ID.
482 return Boolean TRUE on success
483 */
484 function __switch_entries($from,$type,$to)
485 {
486 $all = $this->_get_all_entries();
488 $o_to = &$all[$to];
489 $o_from = &$all[$from];
491 /***********************
492 * Source == Destination
493 * Move into next parent.
494 ************************/
495 if($to == $from){
496 $to = $o_to['PARENT'];
497 $o_to = &$all[$to];
498 }
500 /***********************
501 * Target is container
502 ************************/
503 if(in_array($o_to['TYPE'],array("FOLDER","RELEASE"))){
505 /***********************
506 * Move into parent folder
507 * + Target
508 * |-> Source
509 ************************/
510 if($to == $o_from['PARENT']){
512 /* Check if source is a folder object
513 */
514 $o_to_sub = &$all[$o_to['PARENT']];
515 if(in_array($o_to_sub['TYPE'],array("FOLDER","RELEASE"))){
517 /* Removing old */
518 $tmp = array();
519 foreach($o_to['ENTRIES'] as $key => $entry){
520 if($entry['UNIQID'] == $from){
521 if(!$this->_remove_entry_id($from)){
522 return(FALSE);
523 }
524 }
525 }
527 /* Adding new */
528 $tmp2 = array();
529 foreach($o_to_sub['ENTRIES'] as $key => $entry){
531 if($type == "up"){
532 if($entry['UNIQID'] == $to){
533 $o_from['PARENT'] = $o_to_sub['UNIQID'];
534 $tmp2[] = &$o_from;
535 }
536 $tmp2[] = &$o_to_sub['ENTRIES'][$key];
537 }else{
539 $tmp2[] = &$o_to_sub['ENTRIES'][$key];
540 if($entry['UNIQID'] == $to){
541 $o_from['PARENT'] = $o_to_sub['UNIQID'];
542 $tmp2[] = &$o_from;
543 }
544 }
545 }
546 $all[$o_to_sub['UNIQID']]['ENTRIES'] = $tmp2;
547 }
548 }else{
550 /***********************
551 * Target is NOT parent container
552 * + Parent Folder
553 * |-> Source
554 * + Destination
555 ************************/
557 /* Removing old */
558 $o_to = &$all[$to];
559 $o_from = &$all[$from];
560 $this->_remove_entry_id($from);
561 $o_from['PARENT'] = $to;
562 $o_to['ENTRIES'][] = $o_from;
564 }
565 }else{
567 /***********************
568 * Source and Destination in some Folder.
569 * + Parent folder
570 * |-> Source
571 * |-> Destination
572 ************************/
573 $o_to = &$all[$to];
574 $o_from = &$all[$from];
576 if($o_to['PARENT'] == $o_from['PARENT']){
577 $tmp = $all[$to];
578 $all[$to] = $o_from;
579 $all[$from] = $tmp;
580 }
581 }
582 }
585 /* Return plugin informations for acl handling */
586 static function plInfo()
587 {
588 return (array(
589 "plShortName" => _("Applications"),
590 "plDescription" => _("Group applications"),
591 "plSelfModify" => FALSE,
592 "plDepends" => array(),
593 "plPriority" => 0,
594 "plSection" => array("admin"),
595 "plCategory" => array("groups"),
596 "plProvidedAcls"=> array(
597 "gosaMemberApplication" => _("Application"),
598 "FAIrelease" => _("Release"),
599 "gosaApplicationParameter" => _("Application parameter"))
600 ));
601 }
604 function PrepareForCopyPaste($source)
605 {
606 }
609 function multiple_save_object()
610 {
611 if(isset($_POST['group_apps_multi'])){
612 $this->save_object();
613 plugin::multiple_save_object();
615 /* Get posts */
616 foreach(array("apps") as $attr){
617 if(isset($_POST['use_'.$attr])) {
618 $this->multi_boxes[] = $attr;
619 }
620 }
621 }
622 }
625 function get_multi_edit_values()
626 {
627 $ret = plugin::get_multi_edit_values();
629 if(in_array("apps",$this->multi_boxes)){
630 $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
631 $ret['Categories'] = $this->Categories;
632 $ret['gosaMemberApplication'] = $this->gosaMemberApplication;
633 $ret['FAIrelease'] = $this->FAIrelease;
634 $ret['appoption'] = $this->appoption;
635 }
636 return($ret);
637 }
638 }
639 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
640 ?>