Code

d47ed33c3decee0e89045fea91066c6086163f9d
[gosa.git] / gosa-plugins / fai / admin / fai / class_faiScript.inc
1 <?php
3 class faiScript extends plugin
4 {
5   /* CLI vars */
6   var $cli_summary      = "Manage server basic objects";
7   var $cli_description  = "Some longer text\nfor help";
8   var $cli_parameters   = array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser");
10   /* attribute list for save action */
11   var $ignore_account   = TRUE;
13   /* Attributes for this Object */
14   var $attributes       = array("cn","description");
16   /* ObjectClasses for this Object*/
17   var $objectclasses    = array("top","FAIclass","FAIscript");
19   /* Class name of the Ldap ObjectClass for the Sub Object */
20   var $subClass         = "FAIscriptEntry";
21   var $subClasses       = array("top","FAIclass","FAIscriptEntry");
23   /* Class name of the php class which allows us to edit a Sub Object */
24   var $subClassName     = "faiScriptEntry";      
26   /* Attributes to initialise for each subObject */
27   var $subAttributes    = array("cn","description","FAIpriority"); 
28   var $sub_Load_Later   = array("FAIscript");
29   var $sub64coded       = array();
30   var $subBinary        = array("FAIscript");
32   /* Specific attributes */
33   var $cn               = "";       // The class name for this object
34   var $description      = "";       // The description for this set of partitions
35   var $is_dialog        = false;    // specifies which buttons will be shown to save or abort
36   var $SubObjects       = array();  // All leafobjects of this object
38   var $FAIstate         = "";
39   var $sort_by          = "name";
40   var $sort_order       = "up";
42   var $view_logged = FALSE;
43   var $ui;
45   function faiScript (&$config, $dn= NULL)
46   {
47     /* Load Attributes */
48     plugin::plugin ($config, $dn);
50     /* If "dn==new" we try to create a new entry
51      * Else we must read all objects from ldap which belong to this entry.
52      * First read SubObjects from ldap ... and then the partition definitions for the SubObjects.
53      */
54     if($dn != "new"){
56       $this->dn =$dn;
58       /* Get FAIstate
59        */
60       if(isset($this->attrs['FAIstate'][0])){
61         $this->FAIstate = $this->attrs['FAIstate'][0];
62       }
64       /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
65        */
66       $ldap     = $this->config->get_ldap_link();
67       $ldap->cd ($this->dn);
68       
69       $attrs_to_search = $this->subAttributes;
70       $attrs_to_search[] = "FAIstate";
71       $ldap->search("(&(objectClass=FAIclass)(objectClass=".$this->subClass."))",$attrs_to_search);
73       while($object = $ldap->fetch()){
75         /* Skip objects, that are tagged as removed */
76         if(isset($object['FAIstate'][0])){
77           if(preg_match("/removed$/",$object['FAIstate'][0])){
78             continue;
79           }
80         }
82         /* Set status for save management */
83         $objects = array();
84         $objects['status']      = "FreshLoaded";
85         $objects['dn']          = $object['dn'];
86         $objects                = $this->get_object_attributes($objects,$this->subAttributes);
87         $this->SubObjects[$objects['cn']] = $objects;
88       }
89     
90     }
91     $this->ui = get_userinfo();
92   }
95   /* Reload some attributes */
96   function get_object_attributes($object,$attributes)
97   {
98     $ldap = $this->config->get_ldap_link();
99     $ldap->cd($this->config->current['BASE']);
100     $ldap->cat($object['dn'],$attributes);
101     $tmp  = $ldap->fetch();
103     foreach($attributes as $attrs){
104       if(isset($tmp[$attrs][0])){
105         $var = $tmp[$attrs][0];
107         /* Check if we must decode some attributes */
108         if(in_array_ics($attrs,$this->sub64coded)){
109           $var = base64_decode($var);
110         }
112         /*  check if this is a binary entry */
113         if(in_array_ics($attrs,$this->subBinary)){
114           $var = $ldap->get_attribute($object['dn'], $attrs,$r_array=0);
115         }
117         /* Fix slashes */
118         $var = addslashes($var);
119         $object[$attrs] = $var;
120       }
121     }
122     return($object);
123   }
125   
126   /* Return a valid dn to fetch acls. Because 'new' will not work. */
127   function acl_base_for_current_object($dn)
128   {
129     if($dn == "new"){
130       if($this->dn == "new"){
131         $dn= "cn=dummy,".session::get('CurrentMainBase');
132       }else{
133         $dn = $this->dn;
134       }
135     }
136     return($dn);
137   }
140   function execute()
141   {
142     /* Call parent execute */
143     plugin::execute();
145     if($this->is_account && !$this->view_logged){
146       $this->view_logged = TRUE;
147       new log("view","fai/".get_class($this),$this->dn);
148     }
150     /* Fill templating stuff */
151     $smarty= get_smarty();
152     $display= "";
154     /* Add new sub object */
155     if(isset($_POST['AddSubObject'])){
156       $this->dialog= new $this->subClassName($this->config,"new");
157       $this->dialog->set_acl_base($this->acl_base);
158       $this->dialog->set_acl_category("fai");
159       $this->dialog->parent = &$this;
160       $this->is_dialog=true;
161     }
163     if($this->dn != "new"){
164       session::set('objectinfo',$this->dn);
165     }
167     /* File download requested */
168     if(isset($_GET['getFAIscript'])){
169       if(isset($this->SubObjects[$_GET['getFAIscript']])){
170         $obj = $this->SubObjects[$_GET['getFAIscript']];
171         $obj  = $this->get_object_attributes($obj,$this->sub_Load_Later);
172         send_binary_content($obj['FAIscript'],$obj['cn'].".FAIscript"); 
173       }
174     }
175     
176     /* Handle posts */
177     $s_action = $s_entry = "";
178     foreach($_POST as $name => $value){
180       /* Edit script posted */
181       if(preg_match("/^editscript_/",$name)){
182         $s_action = "edit";
183         $s_entry = preg_replace("/^editscript_/","",$name);
184         $s_entry = base64_decode(preg_replace("/_.*/","",$s_entry));
185         break;
186       }
188       /* Delete script requested */
189       if(preg_match("/^deletescript_/",$name)){
190         $s_action = "remove";
191         $s_entry = preg_replace("/^deletescript_/","",$name);
192         $s_entry = base64_decode(preg_replace("/_.*/","",$s_entry));
193         break;
194       }
195     }
197     if(isset($_GET['act']) && $_GET['act'] == "edit" && isset($_GET['id'])){
198       $s_entry = $_GET['id'];
199       if(isset($this->SubObjects[$s_entry])){
200         $s_action = "edit";
201       }
202     }
204     if($s_action =="edit" && isset($this->SubObjects[$s_entry])){
206       /* Get object, and load missing entry values */
207       $obj  = $this->SubObjects[$s_entry];
208       if($obj['status'] == "FreshLoaded"){
209         $obj  = $this->get_object_attributes($obj,$this->sub_Load_Later);
210       }
212       /* Create new dialog and set acl attributes  */
213       $this->dialog= new $this->subClassName($this->config,$this->dn,$obj);
214       $this->dialog->set_acl_base($this->acl_base_for_current_object($obj['dn']));
215       $this->dialog->set_acl_category("fai");
217       /* Assign some additional dialog informations like headline and parent  */
218       session::set('objectinfo',$obj['dn']);
219       $this->dialog->parent = &$this;
220       $this->is_dialog=true;
221     }
223     /* Check acls, are we allowed to delete an entry */
224     if($s_action == "remove" && isset($this->SubObjects[$s_entry])){
225       $entry = $this->SubObjects[$s_entry];  
226       $acl = $this->ui->get_permissions($this->acl_base_for_current_object($entry['dn']),"fai/faiScriptEntry")  ;
227       if(preg_match("/d/",$acl)){
228         $status = $entry['status'];
229         if($status == "edited" || $status == "FreshLoaded"){
230           $this->SubObjects[$s_entry]['status']= "delete";
231         }else{
232           unset($this->SubObjects[$s_entry]);
233         }
234       }
235     }
237       /* Save the edited entry */
238     if(isset($_POST['SaveSubObject'])){
240       /* Check if there are still errors remaining that must be fixed before saving */
241       $this->dialog->save_object();
242       $msgs = $this->dialog->check();
243       if(count($msgs)>0){
244         foreach($msgs as $msg){
245           print_red($msg);
246         }
247       }else{
249         /* Get return object */
250         $obj = $this->dialog->save();
252         /* If we have renamed the script entry, we must remove the old entry */
253         if(isset($obj['remove'])){
255           /* Get old entry values */
256           $old_stat = $this->SubObjects[$obj['remove']['from']]['status'];
258           /* Depending on status, set new status */
259           if($old_stat == "edited" || $old_stat == "FreshLoaded"){
260             $this->SubObjects[$obj['remove']['from']]['status'] = "delete";
261           }elseif($this->SubObjects[$obj['remove']['from']]['status']=="new"){
262             unset($this->SubObjects[$obj['remove']['from']]);
263           }
265           /* Append the new entry */
266           $obj['status'] = "new";
267           $this->SubObjects[$obj['remove']['to']] = $obj;
268           unset($this->SubObjects[$obj['remove']['to']]['remove']);
269         }else{
270   
271           /* Set new status and append the entry */
272           if($obj['status'] == "FreshLoaded"){
273             $obj['status'] = "edited";
274           }
275           $this->SubObjects[$obj['cn']]=$obj;
276         }
277         $this->is_dialog=false;
278         unset($this->dialog);
279         $this->dialog=FALSE;
281       }
282     }
284     /* Sort entries */
285     $tmp = $keys = array();
287     if($this->sort_by == "name"){
288       foreach($this->SubObjects as $key => $entry){
289         $keys[$key]=$entry['cn'];
290       }
291     }elseif($this->sort_by == "priority"){
292       foreach($this->SubObjects as $key => $entry){
293         $keys[$key]=$entry['FAIpriority'];
294       }
295     }
297     natcasesort($keys);
299     if($this->sort_order == "down"){
300       $keys =array_reverse($keys);
301     }
303     foreach($keys as $key => $order_var){
304       $tmp[$key]=$this->SubObjects[$key];
305     }
306     $this->SubObjects = $tmp;
308     /* Cancel Dialog */
309     if(isset($_POST['CancelSubObject'])){
310       $this->is_dialog=false; 
311       unset($this->dialog);
312       $this->dialog=FALSE;
313     }
315     /* Print dialog if $this->dialog is set */
316     if(is_object($this->dialog)){
317       $this->dialog->save_object();
318       $display = $this->dialog->execute();
319       return($display);
320     }
322     /* Divlist            added 23.02.2006 
323        Containing FAIscripts 
324      */
325     $divlist = new divlist("FAIscripts");
326     $divlist->SetEntriesPerPage(0);
327     $plug = $_GET['plug'];
328    
329     if($this->sort_order == "up"){
330       $dir = "<img src='images/sort_up.png' title='"._("Sort direction")."' alt='\/' border=0>";
331     }else{
332       $dir = "<img src='images/sort_down.png' title='"._("Sort direction")."' alt='/\' border=0>";
333     }
334  
335     if($this->sort_by == "name"){
336       $sort_name = $dir;
337       $sort_prio = "";
338     }else{
339       $sort_name = "";
340       $sort_prio = $dir;
341     }
343     $divlist->SetHeader(array(  array("string"=>"<a href='?plug=".$plug."&amp;sort=name'>"._("Name").$sort_name."</a>"),
344                                 array("string"=>"<a href='?plug=".$plug."&amp;sort=priority'>".$sort_prio._("Priority")."</a>",
345                                       "attach"=>"style='width:100px;'"),
346                                 array("string"=>_("Download"),
347                                       "attach"=>"style='width:100px;'"),
348                                 array("string"=>_("Action"),
349                                       "attach"=>"style='border-right: 0px;width:100px;text-align:right;'")));
350     $divlist->SetHeight(300);
351     $divlist->SetWidth("100%");
352     foreach($this->getList(true) as $key => $name){
354       $dn= $this->acl_base_for_current_object($name['dn']);
355       $acl = $this->ui->get_permissions($dn,"fai/faiScriptEntry")  ;
356       $act = "";
357       
358       /* Hide delete icon if this object is freezed */
359       if($this->FAIstate == "freeze"){
360         $act .= "<input type='image' src='images/edit.png'      name='editscript_%s'    title='"._("edit")."' alt='"._("edit")."'>";
361       }else{
362         $act .= "<input type='image' src='images/edit.png'      name='editscript_%s'    title='"._("edit")."' alt='"._("edit")."'>";
363         if(preg_match("/d/",$acl)){
364           $act .="<input type='image' src='images/edittrash.png' name='deletescript_%s'  title='"._("delete")."' alt='"._("delete")."'>";
365         }
366       }
368       /* Check acls for download icon */
369       $s_acl = $this->ui->get_permissions($dn,"fai/faiScriptEntry","FAIscript")  ;
370       if(($this->SubObjects[$key]['status'] == "new") || ($this->SubObjects[$key]['dn'] == "new") || !preg_match("/r/",$s_acl)){
371         $down = "";
372       }else{
373         $down = "<a href='?plug=".$_GET['plug']."&getFAIscript=".$key."'>
374           <img src='images/save.png' alt='"._("Download")."' title='"._("Download")."' border=0>
375           </a>"; 
376       } 
378       /* Check if we are allowed to view this object */
379       $s_acl = $this->ui->get_permissions($dn,"fai/faiScriptEntry","cn")  ;
380       if(preg_match("/r/",$s_acl)){
381         $divlist->AddEntry(array( array("string"=>"<a href='?plug=".$_GET['plug']."&amp;act=edit&amp;id=".$key."'>".$name['name']."</a>"),
382               array("string"=>$name['FAIpriority'] , "attach" => "style='width:100px;'"),
383               array("string"=>$down , "attach" => "style='width:100px;'"),
384               array("string"=>str_replace("%s",base64_encode($key),$act),
385                 "attach"=>"style='border-right: 0px;width:100px;text-align:right;'")));
386       }
387     }
388     $smarty->assign("Entry_divlist",$divlist->DrawList());
391     /* Magic quotes GPC, escapes every ' " \, to solve some security risks
392      * If we post the escaped strings they will be escaped again
393      */
394     foreach($this->attributes as $attrs){
395       if(get_magic_quotes_gpc()){
396         $smarty->assign($attrs,stripslashes($this->$attrs));
397       }else{
398         $smarty->assign($attrs,($this->$attrs));
399       }
400     }
402     $dn = $this->acl_base_for_current_object($this->dn);
403     $smarty->assign("sub_object_is_addable",  
404         preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiScriptEntry")) && 
405         !preg_match("/freeze/",$this->FAIstate));
407     $tmp = $this->plInfo();
408     foreach($tmp['plProvidedAcls'] as $name => $translated){
409       $smarty->assign($name."ACL",$this->getacl($name));
410     }
412     $display.= $smarty->fetch(get_template_path('faiScript.tpl', TRUE));
413     return($display);
414   }
416   /* Generate listbox friendly SubObject list
417    */
418   function getList($use_dns=false){
419     $a_return=array();
420     foreach($this->SubObjects as $obj){
421       if($obj['status'] != "delete"){
422         if($use_dns){
423           if((isset($obj['description']))&&(!empty($obj['description']))){
424             $a_return[$obj['cn']]['name']= $obj['cn']." [".stripslashes($obj['description'])."]";
425           }else{
426             $a_return[$obj['cn']]['name']= $obj['cn'];
427           }
428           $a_return[$obj['cn']]['dn']= $obj['dn'];
429           $a_return[$obj['cn']]['FAIpriority']= $obj['FAIpriority'];
430         }else{
431           if((isset($obj['description']))&&(!empty($obj['description']))){
432             $a_return[$obj['cn']]= $obj['cn']." [".stripslashes($obj['description'])."]";
433           }else{
434             $a_return[$obj['cn']]= $obj['cn'];
435           }
436         }
437       }
438     }
439     return($a_return);
440   }
442   /* Delete me, and all my subtrees
443    */
444   function remove_from_parent()
445   {
446     if($this->acl_is_removeable()){
447       $ldap = $this->config->get_ldap_link();
448       $ldap->cd ($this->dn);
449       $faifilter = session::get('faifilter');
450       $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $faifilter['branch'], $this->dn);
451       if($faifilter['branch'] == "main"){
452         $use_dn = $this->dn;
453       }
454    
455       new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
456  
457       FAI::prepare_to_save_FAI_object($use_dn,array(),true);
458       
459       foreach($this->SubObjects as $name => $obj){
460         $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $faifilter['branch'], $obj['dn']);
461         if($faifilter['branch'] == "main"){
462           $use_dn = $obj['dn'];
463         }
464         FAI::prepare_to_save_FAI_object($use_dn,array(),true);
465       }
466       $this->handle_post_events("remove");
467     }
468   }
471   /* Save data to object 
472    */
473   function save_object()
474   {
475     if((isset($_POST['FAIscript_posted'])) && ($this->FAIstate != "freeze")){
476       plugin::save_object();
477       foreach($this->attributes as $attrs){
478         if(isset($_POST[$attrs])){
479           $this->$attrs = $_POST[$attrs];
480         }
481       }
482     }
483     
484     /* Get sort order */
485     if(isset($_GET['sort']) && in_array($_GET['sort'],array("name","priority"))){
486       if($this->sort_by == $_GET['sort']){
487         if($this->sort_order == "up"){
488           $this->sort_order = "down";
489         }elseif($this->sort_order == "down"){
490           $this->sort_order = "up";
491         }
492       }
493       $this->sort_by = $_GET['sort'];
494     }
495   }
498   /* Check supplied data */
499   function check()
500   {
501     /* Call common method to give check the hook */
502     $message= plugin::check();
504     return ($message);
505   }
508   /* Save to LDAP */
509   function save()
510   {
511     plugin::save();
513     $ldap = $this->config->get_ldap_link();
515     FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
516     show_ldap_error($ldap->get_error(), sprintf(_("Creating of FAI/script with dn '%s' failed."),$this->dn));
518     if($this->initially_was_account){
519       new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
520     }else{
521       new log("create","fai/".get_class($this),$this->dn,$this->attributes);
522     }
524     /* Prepare FAIscriptEntry to write it to ldap
525      * First sort array.
526      *  Because we must delete old entries first.
527      * After deletion, we perform add and modify 
528      */
529     $Objects = array();
531     /* We do not need to save untouched objects */
532     foreach($this->SubObjects as $name => $obj){
533       if($obj['status'] == "FreshLoaded"){
534         unset($this->SubObjects[$name]);
535       }
536     }
538     foreach($this->SubObjects as $name => $obj){
539       if($obj['status'] == "delete"){
540         $Objects[$name] = $obj; 
541       }
542     }
543     foreach($this->SubObjects as $name => $obj){
544       if($obj['status'] != "delete"){
545         $Objects[$name] = $obj; 
546       }
547     }
549     foreach($Objects as $name => $obj){
551       foreach($this->sub64coded as $codeIt){
552         $obj[$codeIt]=base64_encode(stripslashes($obj[$codeIt]));
553       }
555       $tmp = array();
556       $attributes = array_merge($this->sub_Load_Later,$this->subAttributes);
557       foreach($attributes as $attrs){
559         if(empty($obj[$attrs])){
560           $obj[$attrs] = array();
561         }
562         if(!is_array($obj[$attrs])){
563           $tmp[$attrs] = stripslashes($obj[$attrs]);
564         }else{
565           $tmp[$attrs] = $obj[$attrs];
566         }
567       }    
569       $tmp['objectClass'] = $this->subClasses;
571       $sub_dn = "cn=".$obj['cn'].",".$this->dn;
573       if($obj['status']=="new"){
574         $ldap->cat($sub_dn,array("objectClass"));
575         if($ldap->count()){
576           $obj['status']="edited";
577         }
578       }
580       if(empty($tmp['FAIpriority'])){
581         $tmp['FAIpriority']  ="0";
582       }
584       /* Tag object */
585       $this->tag_attrs(&$tmp, $sub_dn, $this->gosaUnitTag);
587       if($obj['status'] == "delete"){
588         FAI::prepare_to_save_FAI_object($sub_dn,array(),true);
589         $this->handle_post_events("remove");
590       }elseif($obj['status'] == "edited"){
591         FAI::prepare_to_save_FAI_object($sub_dn,$tmp);
592         $this->handle_post_events("modify");
593       }elseif($obj['status']=="new"){
594         FAI::prepare_to_save_FAI_object($sub_dn,$tmp);
595         $this->handle_post_events("add");
596       }
597     }
598   }
601   function PrepareForCopyPaste($source)
602   {
603     plugin::PrepareForCopyPaste($source);
605     /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
606      */
607     $ldap     = $this->config->get_ldap_link();
608     $ldap->cd ($source['dn']);
610     $attrs_to_search = $this->subAttributes;
611     $attrs_to_search[] = "FAIstate";
612     $ldap->search("(&(objectClass=FAIclass)(objectClass=".$this->subClass."))",$attrs_to_search);
614     while($object = $ldap->fetch()){
616       /* Skip objects, that are tagged as removed */
617       if(isset($object['FAIstate'][0])){
618         if(preg_match("/removed$/",$object['FAIstate'][0])){
619           continue;
620         }
621       }
623       /* Set status for save management */
624       $objects = array();
625       $objects['status']      = "edited";
626       $objects['dn']          = $object['dn'];
627       $objects                = $this->get_object_attributes($objects,$this->subAttributes);
628       $objects                = $this->get_object_attributes($objects,$this->sub_Load_Later);
629   
630       $this->SubObjects[$objects['cn']] = $objects;
631     }
632   }
633   
635   /* Return plugin informations for acl handling */ 
636   static function plInfo()
637   {
638     return (array( 
639           "plShortName" => _("Script"),
640           "plDescription" => _("FAI script"),
641           "plSelfModify"  => FALSE,
642           "plDepends"     => array(),
643           "plPriority"    => 18,
644           "plSection"     => array("administration"),
645           "plCategory"    => array("fai"),
646           "plProvidedAcls" => array(
647             "cn"                => _("Name")." ("._("Readonly").")",
648             "description"       => _("Description"))
649           ));
650   }
653 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
654 ?>