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");
9 /* Appgroup attributes */
10 var $gosaMemberApplication= array();
12 /* Helpers */
13 var $departments = ""; // All departments within $this->curbase;
14 var $apps = array(); // All available applications
15 var $used_apps = array(); // Specifies which applications are currently assigned
17 var $option_name = array();
18 var $option_value = array();
19 var $appoption = array();
21 var $table = "";
22 var $curbase = "";
23 var $curCatDir ;
24 var $curCatDepth =0; //
25 var $Categories;
27 /* attribute list for save action */
28 var $attributes = array("gosaMemberApplication","gosaApplicationParameter");
29 var $objectclasses = array("gosaApplicationGroup");
31 var $FAIrelease = "/";
32 var $InitialFAIrelease = "/";
33 var $Releases = array();
34 var $enableReleaseManagement = false;
36 var $AllAppsForRelease = array();
37 var $AllAppsForReleaseParameter = array();
38 var $view_logged = FALSE;
39 var $CopyPasteVars = array("Categories");
40 var $gosaApplicationParameter ;
41 var $ui = NULL;
42 var $no_release_acls = false;
44 var $multiple_support = TRUE;
46 function appgroup (&$config, $dn= NULL, $parent= NULL)
47 {
49 /* Check if we have relase mangement enabled and prepare group application for release management */
50 $tmp = $config->search("faiManagement", "CLASS",array('menu','tabs'));
51 if(!empty($tmp)){
52 $this->enableReleaseManagement = true;
53 $this->objectclasses [] = "FAIreleaseTag";
54 $this->attributes [] = "FAIrelease";
55 }
57 plugin::plugin ($config, $dn, $parent);
59 /* set userinfo object */
60 $this->ui = get_userinfo();
62 /* Compatibility check
63 In some case of old applikations with old release tag saving,
64 we must reassign is_account state.
65 (Or if release management wasn't activated before creating this app) */
66 if($this->enableReleaseManagement){
68 /* Release management is activated && this is a valid group app account,
69 but no release class was found, so activate is_account flag */
70 if(isset($this->attrs['objectClass'])){
71 if($dn != "new" && ( in_array("gosaApplicationGroup",$this->attrs['objectClass'])) &&
72 (!in_array("FAIreleaseTag",$this->attrs['objectClass']))){
73 $this->is_account =true;
74 }
75 }
76 }
78 /* Load member applications */
79 if (isset ($this->attrs["gosaMemberApplication"][0])){
80 $this->gosaMemberApplication = array();
81 for ($i= 0; $i<$this->attrs["gosaMemberApplication"]["count"]; $i++){
82 $this->gosaMemberApplication[]=
83 $this->attrs["gosaMemberApplication"][$i];
84 }
85 }
87 /* Load application options */
88 if (isset($this->attrs['gosaApplicationParameter'])){
89 for ($i= 0; $i<$this->attrs['gosaApplicationParameter']['count']; $i++){
90 $option= preg_replace('/^[^:]+:/', '',
91 $this->attrs['gosaApplicationParameter'][$i]);
92 $name= preg_replace('/:.*$/', '',
93 $this->attrs['gosaApplicationParameter'][$i]);
94 $this->appoption[$name]= $option;
95 }
96 }
98 /* Parse MemberApplication*/
99 $tmp = array();
100 $tmp2 = array();
101 $prios = array();
102 $cats = array();
104 foreach($this->gosaMemberApplication as $memberApp){
105 if(preg_match("/\|/i",$memberApp)){
107 $tmp = split("\|",$memberApp);
109 if(!empty($tmp[0])){
110 $tmp2[$tmp[1]][$tmp[2]] = array("App"=>$tmp[0]);
111 }
112 if(!empty($tmp[1])){
113 $n = split("/",$tmp[1]);
114 $c = count($n);
115 $cats [$tmp[1]] = $n[$c-1];
116 }
117 $prios[$tmp[1]][$tmp[2]] = $tmp[2];
118 }else{
119 $tmp2[]['App'] = $memberApp;
120 }
121 }
123 /* Assign collected category and application settings */
124 $this->Categories = $cats;
125 $this->gosaMemberApplication = $tmp2;
127 /* Sort application by category */
128 $cats[""]="";
129 foreach($cats as $cat ){
130 if((isset($prios[$cat]))&&(count($prios[$cat]))){
131 $max = max($prios[$cat]);
132 $min = 1;//min($prios[$cat]);
133 $last = false;
134 for($i = $min ; $i < $max ; $i++){
135 if(!isset($prios[$cat][$i])){
136 if($last == false){
137 $this->gosaMemberApplication[$cat][$i]['App'] = "__SEPARATOR__".$i;
139 $last = true;
140 }
141 }else{
142 $last = false;
143 }
144 }
145 }
146 }
148 /* Sort application by priority */
149 $tmp = array();
150 foreach($this->gosaMemberApplication as $key => $entries){
151 ksort ($entries);
152 foreach($entries as $entry){
153 $tmp[$key][]= $entry;
154 }
155 }
156 $this->gosaMemberApplication = $tmp;
157 $this->curbase = $this->config->current['BASE'];
159 /* Get required release informations */
160 if($this->enableReleaseManagement){
161 $this->InitialFAIrelease = $this->FAIrelease;
162 $this->Releases = $this->getReleases();
163 }
165 }
168 /* Combine new array */
169 function combineArrays($ar0,$ar1,$ar2)
170 {
171 $ret = array();
172 if(is_array($ar0))
173 foreach($ar0 as $ar => $a){
174 $ret[$ar]=$a;
175 }
176 if(is_array($ar1))
177 foreach($ar1 as $ar => $a){
178 $ret[$ar]=$a;
179 }
180 if(is_array($ar2))
181 foreach($ar2 as $ar => $a){
182 $ret[$ar]=$a;
183 }
184 return($ret);
185 }
187 /* Returns element position within given array */
188 function getpos($atr,$attrs)
189 {
190 $i = 0;
191 foreach($attrs as $attr => $name) {
192 $i++;
193 if($attr == $atr){
194 return($i);
195 }
196 }
197 return(-1);
198 }
201 /* Check current combination of application && release
202 Are all application available?, application parameter changed? ... */
203 function diffAppsInReleases()
204 {
205 /* Only diff if it is required */
206 $ret =array();
208 /* If current release has changed */
209 if($this->FAIrelease != $this->InitialFAIrelease){
211 /* Walk through all apps which are currently displayed */
212 if(isset($this->gosaMemberApplication[$this->curCatDir])){
214 foreach($this->gosaMemberApplication[$this->curCatDir] as $entry){
216 /* If application is also available in new release, check if parameter differs */
217 if(in_array($entry['App'],$this->AllAppsForRelease)){
219 $old = array(); // Old application parameter
220 $new = array(); // New parameters
222 /* There are possibly no parameters specified */
223 if(isset($this->AllAppsForReleaseParameter[$this->InitialFAIrelease][$entry['App']])){
224 $old = $this->AllAppsForReleaseParameter[$this->InitialFAIrelease][$entry['App']];
225 }
227 if(isset($this->AllAppsForReleaseParameter[$this->FAIrelease][$entry['App']])){
228 $new = $this->AllAppsForReleaseParameter[$this->FAIrelease][$entry['App']];
229 }
231 /* Both (old & new) have no gosaApplicationParameter
232 */
233 if((!isset($old['gosaApplicationParameter'])) && (!isset($new['gosaApplicationParameter']))){
234 $ret[$entry['App']] = false;
236 /* Both got gosaApplicationParameter */
237 }elseif((isset($old['gosaApplicationParameter'])) && (isset($new['gosaApplicationParameter']))){
238 if(array_differs($old['gosaApplicationParameter'],$new['gosaApplicationParameter'])){
239 $ret[$entry['App']] = true;
240 }else{
241 $ret[$entry['App']] = false;
242 }
243 }
244 /* Initially had gosaApplicationParameter bot in new release not */
245 }elseif((isset($old['gosaApplicationParameter'])) && (!isset($new['gosaApplicationParameter']))){
246 $ret[$entry['App']] = true;
248 /* Old release had no gosaApplicationParameter but new got some */
249 }elseif((!isset($old['gosaApplicationParameter'])) && (isset($new['gosaApplicationParameter']))){
250 $ret[$entry['App']] = true;
251 }
252 }
253 }
254 }
255 return($ret);
256 }
258 /* TRansports the geiven Arraykey one position up*/
259 function ArrayUp($atr,$attrs)
260 {
261 $ret = $attrs;
262 $pos = $this->getpos($atr,$attrs) ;
263 $cn = count($attrs);
264 if(!(($pos == -1)||($pos == 1))){
265 $before = array_slice($attrs,0,($pos-2));
266 $mitte = array_reverse(array_slice($attrs,($pos-2),2));
267 $unten = array_slice($attrs,$pos);
268 $ret = array();
269 $ret = $this->combineArrays($before,$mitte,$unten);
270 }
271 return($ret);
272 }
275 /* TRansports the geiven Arraykey one position up*/
276 function ArrayDown($atr,$attrs)
277 {
278 $ret = $attrs;
279 $pos = $this->getpos($atr,$attrs) ;
280 $cn = count($attrs);
281 if(!(($pos == -1)||($pos == $cn))){
282 $before = array_slice($attrs,0,($pos-1));
283 $mitte = array_reverse(array_slice($attrs,($pos-1),2));
284 $unten = array_slice($attrs,($pos+1));
285 $ret = array();
286 $ret = $this->combineArrays($before,$mitte,$unten);
287 }
288 return($ret);
289 }
292 /* Sort category on position up */
293 function catUp($id)
294 {
295 /* Get all cats depinding on current dir */
296 $cats = $this->GetSubdirs($this->curCatDir);
297 $newcats =$this->ArrayUp($id,$cats);
298 foreach($newcats as $cat => $name){
299 unset($this->Categories[$cat]);
300 }
301 foreach($newcats as $cat => $name){
302 $this->Categories[$cat]=$name;
303 }
304 }
307 /* Sort category on position down */
308 function catDown($id)
309 {
310 /* Get all cats depinding on current dir */
311 $cats = $this->GetSubdirs($this->curCatDir);
312 $newcats =$this->ArrayDown($id,$cats);
313 foreach($newcats as $cat => $name){
314 unset($this->Categories[$cat]);
315 }
316 foreach($newcats as $cat => $name){
317 $this->Categories[$cat]=$name;
318 }
319 }
322 /* Increase application priority */
323 function getOneUp($appl)
324 {
325 $cat = $this->curCatDir;
326 $apps = $this->gosaMemberApplication[$cat];
327 $appsA = array();
328 foreach ($apps as $appkey => $name){
329 $appsA[$name['App']] =$name['App'];
330 }
331 $result = $this->ArrayUp($appl,$appsA);
332 $ret = array();
333 foreach($result as $app){
334 $ret[]=array("App"=>$app);
335 }
336 $this->gosaMemberApplication[$cat] = $ret;
337 }
340 /* Decrease application priority */
341 function getOneDown($appl)
342 {
343 $cat = $this->curCatDir;
344 $apps = $this->gosaMemberApplication[$cat];
345 $appsA = array();
346 foreach ($apps as $appkey => $name){
347 $appsA[$name['App']] =$name['App'];
348 }
349 $result = $this->ArrayDown($appl,$appsA);
350 $ret = array();
351 foreach($result as $app){
352 $ret[]=array("App"=>$app);
353 }
354 $this->gosaMemberApplication[$cat] = $ret;
355 }
358 /* Add seperator to application list */
359 function AddSeperator($id)
360 {
361 $found = false;
362 $cat = "";
363 $tmp = array();
364 foreach($this->gosaMemberApplication[$this->curCatDir] as $appID => $app){
365 $tmp[] = $app;
366 if(($app['App'] == $id)&&(!$found)){
367 $cnt = count($this->gosaMemberApplication[$this->curCatDir]);
368 $tmp[] = array("App" => "__SEPARATOR__".($cnt+1));
369 $found = true;
370 }
371 }
372 if($found){
373 $this->gosaMemberApplication[$this->curCatDir]=$tmp;
374 }
375 }
378 /* Check if application acls are readable */
379 function check_acls()
380 {
381 return(count($this->ui->get_module_departments("application")));
382 }
385 function execute()
386 {
387 /* Call parent execute */
388 plugin::execute();
389 $display = "";
391 /* Log view */
392 if($this->is_account && !$this->view_logged){
393 $this->view_logged = TRUE;
394 new log("view","groups/".get_class($this),$this->dn);
395 }
397 /* Account state settings - Skip if we are editing multiple entries */
398 if(!$this->multiple_support_active){
400 /* Do we need to flip is_account state? */
401 if(isset($_POST['modify_state'])){
402 if($this->is_account && $this->acl_is_removeable()){
403 $this->is_account= FALSE;
404 }elseif(!$this->is_account && $this->acl_is_createable()){
405 $this->is_account= TRUE;
406 }
407 }
409 /* Do we represent a valid group? */
410 if (!$this->is_account && $this->parent === NULL){
411 $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\"> <b>".
412 _("This 'dn' is no appgroup.")."</b>";
413 return ($display);
414 }
416 /* Show tab dialog headers */
417 $display= "";
418 if ($this->parent !== NULL){
419 if ($this->is_account){
420 $display= $this->show_disable_header(_("Remove applications"),
421 _("This group has application features enabled. You can disable them by clicking below."));
422 } else {
423 $display.= $this->show_enable_header(_("Create applications"),
424 _("This group has application features disabled. You can enable them by clicking below."));
425 return ($display);
426 }
427 }
428 }
430 /* Check acl, applications must be readable */
431 if(!$this->check_acls()){
432 $display .= "<img src='images/button_cancel.png' alt='"._("ACL")."' class='center'>
433 <b>"._("Insufficient permissions")."</b>
434 <p>".
435 _("You do not have permission to query application entries. All your changes will not be saved.").
436 "</p><p class='seperator'> </p>";
437 $this->no_release_acls = true;
438 }
439 /* Check if department was selected */
440 if((isset($_GET['act']))&&($_GET['act']=="depopen")){
441 $dep = base64_decode($_GET['depid']);
442 $this->curbase =$dep;
443 }
445 /* Check if category was selected */
446 if((isset($_GET['act']))&&($_GET['act']=="open") && (empty($_GET['id']) || isset($this->Categories[base64_decode($_GET['id'])]))){
447 $this->curCatDir = base64_decode($_GET['id']);
448 }
453 /* Add Categorie */
454 if((isset($_POST['AddCat']))&&(isset($_POST['CatName']))&&(!empty($_POST['CatName']))){
456 /* Only allow adding a category, if it is allowed */
457 if($this->acl_is_writeable("gosaMemberApplication",$this->no_release_acls)){
459 if(preg_match("/[\\\\\/]/i",$_POST['CatName'])){
460 print_red(_("Invalid character in category name."));
461 }elseif(!in_array($_POST['CatName'],$this->Categories)){
462 if(empty($this->curCatDir)){
463 $this->Categories[$_POST['CatName']]=$_POST['CatName'];
464 }else{
465 $this->Categories[$this->curCatDir."/".$_POST['CatName']]=$_POST['CatName'];
466 }
467 }else{
468 print_red(_("The specified category already exists."));
469 }
470 }
471 }
474 $this->reload();
475 $this->diffAppsInReleases();
477 /* Check POST variables for commands
478 to add/remove some applications */
479 $only_once = false;
480 if($this->acl_is_writeable("gosaMemberApplication",$this->no_release_acls)){
482 /* Walk through posts */
483 foreach($_POST as $name => $value){
485 /* Add a seperator to current category */
486 if((preg_match("/AddSep_/",$name))&&(!$only_once)){
487 $only_once = true;
488 $n = preg_replace("/AddSep_/","",$name);
489 $val= preg_replace("/_.*$/","",$n);
490 $this->AddSeperator($val);
491 }
493 /* Delete application | seperator entry */
494 if((preg_match("/DelApp_/",$name))&&(!$only_once)){
495 $only_once = true;
497 if(preg_match("/DelApp___SEPARATOR__/",$name)) {
498 $n= preg_replace("/DelApp___SEPARATOR__/","",$name);
499 $val= "__SEPARATOR__".preg_replace("/_.*$/","",$n);
500 }else{
501 $n = preg_replace("/DelApp_/","",$name);
502 $val= preg_replace("/_.*$/","",$n);
503 }
505 foreach($this->gosaMemberApplication as $key => $cat){
506 foreach($cat as $key2 => $app){
507 if($app['App'] == $val){
508 unset($this->gosaMemberApplication[$key][$key2]);
509 if(isset($this->used_apps[$val])){
510 foreach($this->getParameters($val) as $para){
511 if(isset($this->appoption[$para])){
512 unset($this->appoption[$para]);
513 }
514 }
515 unset($this->used_apps[$val]);
516 }
517 }
518 }
519 }
520 }
522 if(preg_match("/DelCat_/",$name) && !$only_once){
523 $only_once =TRUE;
524 $cat = preg_replace("/DelCat_/","",$name);
525 $cat = trim(base64_decode( preg_replace("/_.*$/","",$cat)));
527 $free_apps = array();
529 if(isset($this->gosaMemberApplication[$cat]) && is_array($this->gosaMemberApplication[$cat])){
530 foreach($this->gosaMemberApplication[$cat] as $app){
531 $free_apps[] = $app['App'];
532 }
533 unset($this->gosaMemberApplication[$cat]);
534 unset($this->Categories[$cat]);
535 }
536 foreach($this->Categories as $key => $name){
537 if(preg_match("/^".normalizePreg($cat)."\/.*/",$key)){
538 foreach($this->gosaMemberApplication[$key] as $app){
539 $free_apps[] = $app['App'];
540 }
541 unset($this->gosaMemberApplication[$key]);
542 unset($this->Categories[$key]);
543 }
544 }
545 foreach($free_apps as $app){
546 if(isset($this->used_apps[$app])){
547 unset($this->used_apps[$app]);
548 }
549 }
550 }
552 /* Edit application parameter */
553 if((preg_match("/EdiApp_/",$name))&&(!$only_once)){
555 $only_once = true;
556 $appname = $value;
557 $appname = preg_replace("/EdiApp_/","",$name);
558 $appname = preg_replace("/_.*$/","",$appname);
560 /* We've got the appname, get parameters from ldap */
561 $ldap= $this->config->get_ldap_link();
563 /* Check if we have release management enabled */
564 $tmp = $this->config->search("faiManagement", "CLASS",array('menu','tabs'));
565 if(!empty($tmp)){
567 /* Get application parameter from ldap */
568 $tmp = array_flip($this->Releases);
569 $base = $tmp[$this->FAIrelease];
570 $ldap->cd($base);
571 $ldap->search("(&(objectClass=gosaApplication)(cn=$appname))",array("gosaApplicationParameter"));
572 $found = "";
573 while($attrs = $ldap->fetch()) {
574 if(preg_match("/cn=".$appname.",".$base."/",$attrs['dn'])){
575 $found = $attrs['dn'];
576 }
577 }
578 $ldap->cat($found, array("gosaApplicationParameter"));
579 }else{
581 /* Get application parameter from ldap */
582 $ldap->cd($this->config->current['BASE']);
583 $ldap->search("(&(objectClass=gosaApplication)(cn=$appname))",array("gosaApplicationParameter"));
584 }
586 /* Check if this application is unique */
587 if ($ldap->count() != 1){
588 print_red (_("The selected application name is not uniq. Please check your LDAP."));
589 } else {
591 /* Get parameter */
592 $attrs= $ldap->fetch();
593 if(isset($attrs['gosaApplicationParameter'])){
594 $this->dialog= TRUE;
596 /* Fill name and value arrays */
597 for ($i= 0; $i<$attrs['gosaApplicationParameter']['count']; $i++){
598 $option= preg_replace('/^[^:]+:/', '',
599 $attrs['gosaApplicationParameter'][$i]);
600 $name= preg_replace('/:.*$/', '',
601 $attrs['gosaApplicationParameter'][$i]);
602 $this->option_name[$i]= $name;
604 /* Fill with values from application, default should be
605 loaded by the external scripts */
606 if (isset($this->appoption[$name])){
607 $this->option_value[$i]= $this->appoption[$name];
608 }
609 }
611 /* Create edit field */
612 $table= "<table summary=\"\">";
613 for ($i= 0; $i < count($this->option_name); $i++){
614 if (isset($this->option_value[$i])){
615 $value= $this->option_value[$i];
616 } else {
617 $value= "";
618 }
619 $table.="<tr><td>".$this->option_name[$i]."</td><td>".
620 "<input name=\"value$i\" size=60 maxlength=250 ".
621 "value=\"".$value."\"><br></td></tr>";
622 }
623 $table.= "</table>";
624 $this->table= $table;
625 } else {
626 print_red (_("The selected application has no options."));
627 }
628 }
629 }
630 }
631 }
633 /* Add multiple */
634 if(isset($_POST['AddApps'])){
635 foreach($_POST as $name => $value){
636 if(preg_match("/AddApp_/",$name)){
637 $app = preg_replace("/AddApp_/","",$name);
638 $this->addApp($app);
639 }
640 }
641 }
643 /* Add application with post */
644 if((isset($_GET['act']))&&($_GET['act']=="add")){
645 $this->used_apps[$_GET['id']]= $_GET['id'];
646 asort($this->used_apps);
647 $this->addApp($_GET['id']);
648 }
650 /* Cancel edit options? */
651 if (isset($_POST['edit_options_cancel'])){
652 $this->dialog= FALSE;
653 }
655 /* Finish edit options? */
656 if (isset($_POST['edit_options_finish'])){
657 $this->dialog= FALSE;
659 /* Save informations passed by the user */
660 $this->option_value= array();
661 for ($i= 0; $i<count($this->option_name); $i++){
662 $this->appoption[$this->option_name[$i]]= $_POST["value$i"];
663 $this->is_modified= TRUE;
664 }
665 }
667 /* Prepare templating stuff */
668 $smarty= get_smarty();
669 $smarty->assign("used_apps", $this->used_apps);
670 $apps= array();
671 foreach ($this->apps as $key => $value){
672 if (!array_key_exists($key, $this->used_apps)){
673 $apps["$key"]= "$value";
674 }
675 }
678 /* Create application list */
679 $div = new divSelectBox("appgroup");
680 $div->SetHeight(300);
681 $departments = array();
682 $res = get_list("(objectClass=gosaDepartment)", "application", $this->curbase,array("description","cn","ou"),GL_SIZELIMIT);
683 foreach($res as $value){
684 $fdn = $value['dn'];
685 $fdn = preg_replace("/".normalizePreg($this->curbase)."/","",$fdn);
686 $fdn= @LDAP::fix($fdn);
687 if($value["description"][0]!=".."){
688 $departments[$value['dn']]= convert_department_dn($fdn)." - [".$value["description"][0]."]";
689 }else{
690 $departments[$value['dn']]=convert_department_dn($fdn)." ["._("Back")."]";
691 }
692 }
694 /* Create 'open' and 'add' links */
695 if($this->acl_is_writeable("gosaMemberApplication",$this->no_release_acls)){
696 $linkadd = "<a href='?plug=".$_GET['plug']."&act=add&id=%s'>%s</a>";
697 }else{
698 $linkadd = "%s";
699 }
700 $linkopen = "<a href='?plug=".$_GET['plug']."&act=depopen&depid=%s'>%s</a>";
702 /* Create base back entry */
703 $base_back = preg_replace("/^[^,]+,/","",$this->curbase);
704 if((strlen($base_back)>= strlen($this->config->current['BASE']))&&($this->curbase!=$this->config->current['BASE'])){
705 $div->AddEntry(array(
706 array("string"=>sprintf($linkopen,base64_encode($base_back),".. ["._("back")."]"),
707 "attach"=>"style='border:0px;'")
708 ));
709 }
711 /* Append departments for current base */
712 foreach($departments as $key => $app){
713 $div->AddEntry(array(
714 array("string"=>"<img class='center' src='images/folder.png' alt='"._("department")."'> ".sprintf($linkopen,base64_encode($key),$app),
715 "attach"=>"style='border:0px;'")
716 ));
717 }
719 /* Add applications found on this base */
720 foreach($apps as $key => $app){
721 $div->AddEntry(array(
722 array("string"=>sprintf("<input class='center' type='checkbox' value='1' name='AddApp_%s'>",$key).
723 "<img class='center' src='images/select_application.png' alt='"._("application")."'> ".sprintf($linkadd,$key,$app),
724 "attach"=>"style='border:0px;'")
725 ));
726 }
728 /* Create list of used/assigned applications */
729 $div2 = new divSelectBox("appgroup");
730 $div2->SetHeight(300);
732 /* Check acls to create "edit/remove" category links */
733 if(!$this->acl_is_writeable("gosaMemberApplication",$this->no_release_acls)){
734 $linkopen = "<img class='center' src='images/folder.png' alt=\"\"> <a href='?plug=".$_GET['plug']."&act=open&id=%s'>%s</a>";
735 $catremove = " <img src='images/empty.png' alt=' '>";
736 $catupdown = "";
737 }else{
738 $linkopen = "<img class='center' src='images/folder.png' alt=\"\"> <a href='?plug=".$_GET['plug']."&act=open&id=%s'>%s</a>";
739 $catremove = " <input type='image' src='images/edittrash.png' title='"._("Delete entry")."' name='DelCat_%s' value='%s'>";
740 $catupdown = "<a href='?plug=".$_GET['plug']."&act=cat_up&id=%s'>".
741 "<img align='top' alt=\"\" src='images/sort_up.png' border=0 title='"._("Move up")."'>".
742 "</a> ".
743 "<a href='?plug=".$_GET['plug']."&act=cat_down&id=%s'>".
744 "<img alt=\"\" src='images/sort_down.png' title='"._("Move down")."' border=0>".
745 "</a>";
746 }
748 /* Add back category for current category */
749 if(empty($this->curCatDir)){
750 $cnt =0;
751 }else{
752 $cnt = count(split("/",$this->curCatDir));
753 $tmp = split("/",$this->curCatDir);
754 $bbk = "";
755 for($i = 0 ; $i < ($cnt -1 ) ; $i++){
756 $bbk .= $tmp[$i]."/";
757 }
758 $bbk = preg_replace("/\/$/","",$bbk);
759 $div2 ->AddEntry(array(array("string"=>sprintf($linkopen,base64_encode($bbk),".. ["._("Back")."]")),array("string"=>" ","attach"=>"style='border-right:0px;'")));
760 }
762 /* Add sub categories */
763 $this->GetSubdirs($this->curCatDir);
764 foreach($this->GetSubdirs($this->curCatDir) as $path => $name){
765 $div2 ->AddEntry(array(
766 array("string"=>sprintf($linkopen,base64_encode($path),$name)),
767 array("string"=>preg_replace("/%s/",base64_encode($path),$catupdown.$catremove),
768 "attach"=>"align='right' style='width:80px;border-right:0px;'")));
769 }
771 /* Create priority & seperator links */
772 $separator ="<hr size=1>";
773 if($this->acl_is_writeable("gosaMemberApplication",$this->no_release_acls)){
774 $sep = "<input type='image' src='images/back.png' title='"._("Insert seperator")."' value='%s' name='AddSep_%s'>";
775 $upudown = "<a href='?plug=".$_GET['plug']."&act=one_up&id=%s'>".
776 " <img alt='{t}sort{/t}' align='top' src='images/sort_up.png' title='"._("Move up")."' border=0>".
777 "</a> ".
778 "<a href='?plug=".$_GET['plug']."&act=one_down&id=%s'>".
779 " <img alt='{t}sort{/t}' src='images/sort_down.png' title='"._("Move down")."' border=0>".
780 "</a> ".
781 "<input type='image' src='images/edittrash.png' title='"._("Delete entry")."' name='DelApp_%s' value='%s' alt='{t}delete{/t}' >";
782 }else{
783 $sep = "";
784 $upudown = "";
785 }
787 /* Create edit link */
788 if($this->acl_is_writeable("gosaApplicationParameter",$this->no_release_acls)){
789 $edit= " <input type='image' src='images/edit.png' title='"._("Edit entry")."' name='EdiApp_%s' value='%s' alt='{t}edit{/t}' >";
790 }else{
791 $edit= "";
792 }
794 /* Get differences to mark those entries that have changed from last edit. */
795 $Differences = $this->diffAppsInReleases();
797 /* Walk through entries an append them to list */
798 if(isset($this->gosaMemberApplication[$this->curCatDir])){
799 foreach($this->gosaMemberApplication[$this->curCatDir] as $cat => $entry){
801 /* Add seperator */
802 if(preg_match("/__SEPARATOR__/",$entry['App'])){
803 $div2 ->AddEntry(array(array("string"=>$separator),
804 array("string"=>preg_replace("/\%s/",htmlentities($entry['App']),$upudown),"attach"=>"align='right' style='border-right:0px;'")));
805 }else{
807 /* Add application */
809 $image = "";
810 /* Check if application was available within selected release
811 * or application list if release management is not active
812 */
813 if(!in_array($entry['App'],$this->AllAppsForRelease)){
815 /* release managent is active
816 */
817 if(!$this->enableReleaseManagement){
818 $image = "<img class='center' alt='R' src='images/select_invalid_application.png'
819 title='"._("This application is no longer available.")."'> ";
820 }else{
821 $image = "<img class='center' alt='F' src='images/select_invalid_application.png'
822 title=\"".sprintf(_("This application is not available in any release named %s."),$this->FAIrelease)."\"> ";
823 }
825 }elseif(isset($Differences[$entry['App']]) && ($Differences[$entry['App']] == true)) {
826 $entry['App'].=" <i>["._("Check parameter")."]</i>";
827 $image = "<img class='center' src='images/select_invalid_application.png'
828 title='"._("This application has changed parameters.")."'> ";
829 }else{
830 $image = "<img class='center' src='images/select_application.png' alt=\"\"> ";
831 }
833 $div2->AddEntry(array(array("string"=>sprintf($image."%s",$entry['App'])),
834 array("string"=>preg_replace("/\%s/",htmlentities($entry['App']),$sep.$edit.$upudown),
835 "attach"=>"align='right' style='width:100px;border-right:0px;'")));
836 }
837 }
838 }
840 /* Assign created div lists to template */
841 $smarty->assign("UsedApps", $div2->DrawList());
842 $smarty->assign("List", $div->DrawList());
843 $smarty->assign("apps", $apps);
845 $smarty->assign("enableReleaseManagement",$this->enableReleaseManagement);
847 $smarty->assign("ReleaseSelectAble", false);
848 $smarty->assign("Release", $this->FAIrelease);
850 if($this->enableReleaseManagement){
851 $smarty->assign("FAIrelease", $this->FAIrelease);
852 $smarty->assign("Releases", $this->Releases);
854 if(!$this->no_release_acls && count($this->Releases)){
855 $smarty->assign("ReleaseSelectAble", true);
856 }
857 }
859 /* Set acls to template */
860 $tmp = $this->plInfo();
861 foreach($tmp['plProvidedAcls'] as $acl => $translation){
862 $smarty->assign($acl."ACL",$this->getacl($acl,$this->no_release_acls));
863 }
865 /* Assign multiple edit values */
866 foreach(array("apps") as $attr){
867 if(in_array($attr,$this->multi_boxes)){
868 $smarty->assign("use_".$attr,TRUE);
869 }else{
870 $smarty->assign("use_".$attr,FALSE);
871 }
872 }
873 $smarty->assign("multiple_support",$this->multiple_support_active);
875 /* Show main page */
876 if (($this->dialog)){
877 $smarty->assign("table", $this->table);
878 $display.= $smarty->fetch (get_template_path('application_options.tpl', TRUE,dirname(__FILE__)));
879 } else {
880 $display.= $smarty->fetch (get_template_path('application.tpl', TRUE,dirname(__FILE__)));
881 }
882 return ($display);
883 }
886 function getReleases()
887 {
888 /* Only display those releases that we are able to read */
889 $dn = $this->config->current['BASE'];
890 $filter = "(&(objectClass=organizationalUnit)(objectClass=FAIbranch))";
891 $res = get_list($filter,"application", $dn, array("ou"), GL_SUBSEARCH);
893 $ret =array();
894 foreach($res as $attrs){
895 if(preg_match("/".get_ou('applicationou')."/",$attrs['dn'])){
896 $bb = preg_replace("/".get_ou('applicationou').".*/","",$attrs['dn']);
897 $parts = array_reverse(split("ou=",$bb));
899 $str ="";
900 foreach($parts as $part){
901 if(empty($part)) {
902 continue;
903 }
904 $str .= str_replace(",","",$part)."/";
905 }
906 $name = preg_replace("/\/$/","",$str);
907 if(empty($name)) {
908 $name ="/";
909 }
910 $ret[$attrs['dn']] = $name;
911 }
912 }
913 natcasesort($ret);
914 return($ret);
915 }
917 function save_object()
918 {
920 /* Move category one position up or down */
921 if((isset($_GET['act']))&&(($_GET['act'] == "cat_up")||($_GET['act']=="cat_down"))){
922 if($_GET['act']=="cat_up"){
923 $this->catUp(base64_decode($_GET['id']));
924 }
925 if($_GET['act']=="cat_down"){
926 $this->catDown(base64_decode($_GET['id']));
927 }
928 }
930 /* Move application one position up or down */
931 if((isset($_GET['act']))&&(($_GET['act'] == "one_up")||($_GET['act']=="one_down"))){
932 if(isset($_GET['id'])){
933 $id = $_GET['id'];
934 $act = $_GET['act'];
936 if($act == "one_up"){
937 $this->getOneUp($id);
938 }elseif($act == "one_down") {
939 $this->getOneDown($id);
940 }
941 }
942 }
945 plugin::save_object();
946 }
949 function remove_from_parent()
950 {
951 if(!$this->initially_was_account){
952 return;
953 }
955 plugin::remove_from_parent();
957 $ldap= $this->config->get_ldap_link();
958 $ldap->cd($this->dn);
959 $this->cleanup();
961 $ldap->modify ($this->attrs);
962 new log("remove","group/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
963 show_ldap_error($ldap->get_error(), sprintf(_("Removing of groups/applications with dn '%s' failed."),$this->dn));
965 /* Optionally execute a command after we're done */
966 $this->handle_post_events("remove");
967 }
970 /* Save to LDAP */
971 function save()
972 {
973 /* Skip saving application settings, if we do not have release acls */
974 if($this->no_release_acls && $this->enableReleaseManagement){
975 new log("security","groups/".get_class($this),$this->dn,array(),"Skip saving group application extension. Caused by insufficient acls");
977 return;
978 }
980 plugin::save();
982 /* Copy members */
983 $tmp = array("" => "");
984 $tmp = array_merge($tmp,$this->Categories);
986 $this->attrs["gosaMemberApplication"]= array();
987 $this->attrs["gosaApplicationParameter"]= array();
988 $cat_id= 0 ;
989 foreach($tmp as $name => $cats){
990 $i =0;
991 if(isset($this->gosaMemberApplication[$name])){
992 foreach($this->gosaMemberApplication[$name] as $entry){
993 if(!preg_match("/__SEPARATOR__/",$entry['App'])){
994 $this->attrs["gosaMemberApplication"][]= $entry['App']."|".$name."|".$i;
995 $i ++;
996 }
997 }
998 }
999 if(($i==0)&&(!empty($name))){
1000 $this->attrs["gosaMemberApplication"][]= "|".$name."|".$cat_id;
1001 }
1002 $cat_id++;
1003 }
1007 /* Are there application parameters to be saved */
1008 $this->attrs['gosaApplicationParameter']= array();
1009 foreach($this->appoption as $name => $value){
1010 if ($value != ""){
1011 $this->attrs['gosaApplicationParameter'][]= "$name:$value";
1012 }
1013 }
1015 /* Write back to LDAP */
1016 $ldap= $this->config->get_ldap_link();
1017 $ldap->cd($this->dn);
1018 $this->cleanup();
1019 $ldap->modify ($this->attrs);
1021 if($this->initially_was_account){
1022 new log("modify","group/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1023 }else{
1024 new log("create","group/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
1025 }
1027 show_ldap_error($ldap->get_error(), sprintf(_("Saving of groups/applications with dn '%s' failed."),$this->dn));
1029 /* Optionally execute a command after we're done */
1030 if ($this->initially_was_account == $this->is_account){
1031 if ($this->is_modified){
1032 $this->handle_post_events("modify");
1033 }
1034 } else {
1035 $this->handle_post_events("add");
1036 }
1038 }
1040 function check()
1041 {
1042 /* Call common method to give check the hook */
1043 $message= plugin::check();
1045 return ($message);
1046 }
1049 function reload()
1050 {
1051 /* Generate applist */
1052 $this->apps= array();
1054 /* Special handling for release managed apps */
1055 $tmp = $this->config->search("faiManagement", "CLASS",array('menu','tabs'));
1056 if(!empty($tmp) && count($this->Releases)){
1057 $this->enableReleaseManagement = true;
1059 /* Check if release is available */
1060 $tmp = array_flip($this->Releases);
1061 if(isset($tmp[$this->FAIrelease])){
1062 $base = $tmp[$this->FAIrelease];
1063 }else{
1065 /* Release is not available, check if there is an alternative */
1066 $old_r = $this->FAIrelease;
1067 $k = key($tmp);
1069 if(isset($tmp[$k])){
1071 /* We have found an alternative release name */
1072 $r = $tmp[$k];
1073 $this->FAIrelease = $k;
1074 $base = $r;
1076 /* Display msg */
1077 if(!(!$this->initially_was_account && $old_r =="/")){
1078 print_red(sprintf(_("Can't resolve the release name '%s', setting release name to '%s'. Possibly the objects base has changed."),$old_r,$k));
1079 }
1080 }else{
1082 /* There are no releases available ... */
1083 print_red(_("There are no releases available. You will not be able to select another release."));
1084 return;
1085 }
1086 }
1088 /* Get applications for this release */
1089 $base = preg_replace("/".get_ou('applicationou').".*$/",get_ou('applicationou').$this->curbase,$base);
1090 $res = get_list("(objectClass=gosaApplication)","application",$base,array("*"));
1091 }else{
1093 /* Get applications for this base */
1094 $res = get_list("(objectClass=gosaApplication)","application",get_ou('applicationou').$this->curbase,array("*"));
1095 }
1097 /* Append applications */
1098 foreach($res as $attrs){
1099 if (isset($attrs["description"][0])){
1100 $this->apps[$attrs["cn"][0]]=
1101 $attrs["cn"][0]." (".
1102 $attrs["description"][0].")";
1103 } else {
1104 $this->apps[$attrs["cn"][0]]=
1105 $attrs["cn"][0];
1106 }
1107 }
1109 /* Get all apps ... */
1110 $res = get_list("objectClass=gosaApplication","application",$this->config->current['BASE'],array("gosaApplicationParameter","cn"),GL_SUBSEARCH);
1111 $tmp = $this->config->search("faiManagement", "CLASS",array('menu','tabs'));
1112 $this->AllAppsForRelease = array();
1113 if(!empty($tmp)){
1114 $tmp = array_flip($this->Releases);
1115 foreach($res as $attrs){
1117 $testdn = preg_replace("/".get_ou('applicationou').".*$/",get_ou('applicationou'),$attrs['dn']);
1118 $testdn = preg_replace("/^[^,]+/","",$testdn);
1119 $testdn = preg_replace("/^,/","",$testdn);
1121 if($testdn == preg_replace("/".get_ou('applicationou').".*$/",get_ou('applicationou'),$tmp[$this->FAIrelease])){
1122 $this->AllAppsForRelease[$attrs['dn']] = $attrs['cn'][0];
1123 $this->AllAppsForReleaseParameter[$this->FAIrelease][$attrs['cn'][0]] = $attrs;
1124 }
1125 }
1126 }else{
1127 foreach($res as $attrs){
1128 $this->AllAppsForRelease[$attrs['dn']] = $attrs['cn'][0];
1129 }
1130 }
1132 natcasesort ($this->apps);
1133 reset ($this->apps);
1135 if(is_array($this->gosaMemberApplication))
1136 foreach ($this->gosaMemberApplication as $cat){
1137 if(is_array($cat))
1138 foreach($cat as $entry){
1139 $this->used_apps[$entry['App']]= $entry['App'];
1140 }
1141 }
1142 }
1145 function addApp($cn)
1146 {
1147 if((isset($this->gosaMemberApplication[$this->curCatDir]))&&(is_array($this->gosaMemberApplication[$this->curCatDir]))){
1148 foreach($this->gosaMemberApplication[$this->curCatDir] as $entry){
1149 if($entry['App'] == $cn) return;
1150 }
1151 }
1152 $this->gosaMemberApplication[$this->curCatDir][]= array("App"=>$cn);
1153 $this->used_apps[$cn]=$cn;
1154 $this->is_modified= TRUE;
1155 }
1158 function removeApp($cn)
1159 {
1160 $temp= array();
1161 foreach ($this->gosaMemberApplication as $value){
1162 if ($value != $cn){
1163 $temp[]= $value;
1164 }
1165 }
1166 $this->gosaMemberApplication= $temp;
1167 $this->is_modified= TRUE;
1168 }
1170 function getParameters($app)
1171 {
1172 $tmp = $this->getReleases();
1173 $ret = array();
1174 if(in_array($this->FAIrelease,$tmp)){
1175 $tmp2 = array_flip($tmp);
1176 $base = $tmp2[$this->FAIrelease];
1177 $ldap = $this->config->get_ldap_link();
1178 $ldap->cd($this->config->current['BASE']);
1179 $ldap->search("(&(objectClass=gosaApplication)(cn=".$app.")(gosaApplicationParameter=*))",array("gosaApplicationParameter"));
1180 if($ldap->count()){
1181 $attrs = $ldap->fetch();
1182 for($i = 0 ; $i < $attrs['gosaApplicationParameter']['count'] ; $i ++ ){
1183 $name = preg_replace("/:.*$/","",$attrs['gosaApplicationParameter'][$i]);
1184 $ret[$name] = $name;
1185 }
1186 }
1187 }
1188 return($ret);
1189 }
1191 function GetSubdirs($dir)
1192 {
1193 $ret = array();
1194 $tmp1 = split("/",$this->curCatDir);
1196 foreach($this->Categories as $path=>$cat){
1197 $tmp2 = split("/",$path);
1199 if((empty($this->curCatDir))&&(!preg_match("/\//",$path))){
1200 $abort = false;
1201 }elseif(((count($tmp1))+1) == (count($tmp2))){
1202 $abort = false;
1203 for($i = 0 ; $i < count($tmp1) ; $i++){
1204 if($tmp1[$i] != $tmp2[$i]){
1205 $abort = true;
1206 }
1207 }
1208 }else{
1209 $abort= true;
1210 }
1211 if(!$abort){
1212 $ret[$path]=$cat;
1213 }
1214 }
1215 return($ret);
1216 }
1219 function PrepareForCopyPaste($source)
1220 {
1221 $s = new appgroup($this->config,$source['dn']);
1222 $this->FAIrelease = $this->InitialFAIrelease = $s->FAIrelease;
1223 $this->gosaMemberApplication = $s->gosaMemberApplication;
1224 $this->appoption = $s->appoption;
1225 $this->Categories = $s->Categories;
1226 }
1229 /* Return plugin informations for acl handling */
1230 static function plInfo()
1231 {
1232 return (array(
1233 "plShortName" => _("Applications"),
1234 "plDescription" => _("Group applications"),
1235 "plSelfModify" => FALSE,
1236 "plDepends" => array(),
1237 "plPriority" => 0,
1238 "plSection" => array("admin"),
1239 "plCategory" => array("groups"),
1240 "plProvidedAcls"=> array(
1241 "gosaMemberApplication" => _("Application"),
1242 "FAIrelease" => _("Release"),
1243 "gosaApplicationParameter" => _("Application parameter"))
1244 ));
1245 }
1248 function multiple_save_object()
1249 {
1250 if(isset($_POST['group_apps_multi'])){
1251 $this->save_object();
1252 plugin::multiple_save_object();
1254 /* Get posts */
1255 foreach(array("apps") as $attr){
1256 if(isset($_POST['use_'.$attr])) {
1257 $this->multi_boxes[] = $attr;
1258 }
1259 }
1260 }
1261 }
1263 function multiple_execute()
1264 {
1265 return($this->execute());
1266 }
1268 function init_multiple_support($attrs,$all)
1269 {
1270 // Do nothing here
1271 }
1273 function get_multi_edit_values()
1274 {
1275 $ret = plugin::get_multi_edit_values();
1277 if(in_array("apps",$this->multi_boxes)){
1278 $ret['gosaApplicationParameter'] = $this->gosaApplicationParameter;
1279 $ret['Categories'] = $this->Categories;
1280 $ret['gosaMemberApplication'] = $this->gosaMemberApplication;
1281 $ret['FAIrelease'] = $this->FAIrelease;
1282 $ret['appoption'] = $this->appoption;
1283 }
1284 return($ret);
1285 }
1286 }
1287 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1288 ?>