Code

Fixed script listing
[gosa.git] / gosa-plugins / fai / admin / fai / class_faiScript.inc
1 <?php
3 class faiScript extends plugin
4 {
5   /* attribute list for save action */
6   var $ignore_account   = TRUE;
8   /* Attributes for this Object */
9   var $attributes       = array("cn","description");
11   /* ObjectClasses for this Object*/
12   var $objectclasses    = array("top","FAIclass","FAIscript");
14   /* Class name of the Ldap ObjectClass for the Sub Object */
15   var $subClass         = "FAIscriptEntry";
16   var $subClasses       = array("top","FAIclass","FAIscriptEntry");
18   /* Class name of the php class which allows us to edit a Sub Object */
19   var $subClassName     = "faiScriptEntry";      
21   /* Attributes to initialise for each subObject */
22   var $subAttributes    = array("cn","description","FAIpriority"); 
23   var $sub_Load_Later   = array("FAIscript");
24   var $sub64coded       = array();
25   var $subBinary        = array("FAIscript");
27   /* Specific attributes */
28   var $cn               = "";       // The class name for this object
29   var $description      = "";       // The description for this set of partitions
30   var $is_dialog        = false;    // specifies which buttons will be shown to save or abort
31   var $SubObjects       = array();  // All leafobjects of this object
33   var $FAIstate         = "branch";
34   var $sort_by          = "name";
35   var $sort_order       = "up";
37   var $view_logged = FALSE;
38   var $ui;
40   function faiScript (&$config, $dn= NULL)
41   {
42     /* Load Attributes */
43     plugin::plugin ($config, $dn);
45     /* If "dn==new" we try to create a new entry
46      * Else we must read all objects from ldap which belong to this entry.
47      * First read SubObjects from ldap ... and then the partition definitions for the SubObjects.
48      */
49     if($dn != "new"){
50       $this->dn =$dn;
52       /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
53        */
54       $res = FAI::get_all_objects_for_given_base($this->dn,"(&(objectClass=FAIclass)(objectClass=".$this->subClass."))");
55       foreach($res as $obj){
57         /* Skip not relevant objects */
58         if(!preg_match("/".preg_quote($this->dn, '/')."$/i",$obj['dn'])) continue;
60         $objects = array();
61         $objects['status']      = "FreshLoaded";
62         $objects['dn']          = $obj['dn'];
63         $objects                = $this->get_object_attributes($objects,$this->subAttributes);
64         $this->SubObjects[$objects['cn']] = $objects;
65       }
66     }
68     $this->is_new = FALSE;
69     if($this->dn == "new"){
70       $this->is_new =TRUE;
71     }
72  
73     $this->ui = get_userinfo();
75     $this->scriptListWidget= new sortableListing($this->convertList(TRUE), $this->convertList());
76     $this->scriptListWidget->setDeleteable(true);
77     $this->scriptListWidget->setInstantDelete(false);
78     $this->scriptListWidget->setEditable(true);
79     $this->scriptListWidget->setWidth("100%");
80     $this->scriptListWidget->setHeight("70px");
81     $this->scriptListWidget->setHeader(array(_("Name"),_("Description")));
82   }
84   function convertList($type = FALSE)
85   {
86     $data = array();
87     foreach($this->SubObjects as $cn => $entry){
88       if($entry['status'] == "delete") continue;
89       if($type){
90         $data[$cn] = $entry;
91       }else{
92         $data[$cn] = array('data' => array($entry['cn'], $entry['description']));
93       }
94     }
95     return($data);
96   }
99   /* Reload some attributes */
100   function get_object_attributes($object,$attributes)
101   {
102     $ldap = $this->config->get_ldap_link();
103     $ldap->cd($this->config->current['BASE']);
104     $ldap->cat($object['dn'],$attributes);
105     $tmp  = $ldap->fetch();
107     foreach($attributes as $attrs){
108       if(isset($tmp[$attrs][0])){
109         $var = $tmp[$attrs][0];
111         /* Check if we must decode some attributes */
112         if(in_array_ics($attrs,$this->sub64coded)){
113           $var = postDecode($var);
114         }
116         /*  check if this is a binary entry */
117         if(in_array_ics($attrs,$this->subBinary)){
118           $var = $ldap->get_attribute($object['dn'], $attrs,$r_array=0);
119         }
121         /* Fix slashes */
122         $var = addslashes($var);
123         $object[$attrs] = $var;
124       }
125     }
126     return($object);
127   }
129   
130   /* Return a valid dn to fetch acls. Because 'new' will not work. */
131   function acl_base_for_current_object($dn)
132   {
133     if($dn == "new" || $dn == ""){
134       if($this->dn == "new"){
135         $dn= $this->parent->parent->acl_base;
136       }else{
137         $dn = $this->dn;
138       }
139     }
140     return($dn);
141   }
144   function execute()
145   {
146     /* Call parent execute */
147     plugin::execute();
149     if($this->is_account && !$this->view_logged){
150       $this->view_logged = TRUE;
151       new log("view","fai/".get_class($this),$this->dn);
152     }
154     /* Fill templating stuff */
155     $smarty= get_smarty();
156     $display= "";
158     /* Add new sub object */
159     if(isset($_POST['AddSubObject']) && !preg_match("/freeze/i",$this->FAIstate)){
160       $this->dialog= new $this->subClassName($this->config,"new");
161       $this->dialog->FAIstate = $this->FAIstate;
162       $this->dialog->set_acl_base($this->acl_base);
163       $this->dialog->set_acl_category("fai");
164       $this->dialog->parent = &$this;
165       $this->is_dialog=true;
166     }
168     if($this->dn != "new"){
169       set_object_info($this->dn);
170     }
172     /* Handle posts */
173     $s_action = $s_entry = "";
174     foreach($_POST as $name => $value){
175       if(preg_match("/^download_/",$name)){
176         $s_entry = postDecode(preg_replace("/^download_/","",$name));
177         $obj = $this->SubObjects[$s_entry];
178         $obj  = $this->get_object_attributes($obj,$this->sub_Load_Later);
179         send_binary_content(stripslashes($obj['FAIscript']),$obj['cn'].".FAIscript"); 
180         break;
181       }
182     }
184     $this->scriptListWidget->setAcl($this->getacl(""));
185     $this->scriptListWidget->save_object();
186     $action = $this->scriptListWidget->getAction();
187     if($action['action'] =="edit"){
188       $s_entry = $this->scriptListWidget->getKey($action['targets'][0]);
189       if(isset($this->SubObjects[$s_entry])){ 
191         $obj  = $this->SubObjects[$s_entry];
192         if($obj['status'] == "FreshLoaded"){
193           $obj  = $this->get_object_attributes($obj,$this->sub_Load_Later);
194         }
196         /* Create new dialog and set acl attributes  */
197         $this->dialog= new $this->subClassName($this->config,$this->dn,$obj);
198         $this->dialog->FAIstate = $this->FAIstate;
199         $this->dialog->set_acl_base($this->acl_base_for_current_object($obj['dn']));
200         $this->dialog->set_acl_category("fai");
202         /* Assign some additional dialog informations like headline and parent  */
203         set_object_info($obj['dn']);
204         $this->dialog->parent = &$this;
205         $this->is_dialog=true;
206       }
207     }
209     /* Check acls, are we allowed to delete an entry */
210     if($action['action'] =="delete"){
211       $s_entry = $this->scriptListWidget->getKey($action['targets'][0]);
212       if(isset($this->SubObjects[$s_entry])){ 
213         $entry = $this->SubObjects[$s_entry];  
214         $acl = $this->ui->get_permissions($this->acl_base_for_current_object($entry['dn']),"fai/faiScriptEntry")  ;
215         if(preg_match("/d/",$acl)){
216           $status = $entry['status'];
217           if($status == "edited" || $status == "FreshLoaded"){
218             $this->SubObjects[$s_entry]['status']= "delete";
219           }else{
220             unset($this->SubObjects[$s_entry]);
221           }
222         }
223       }
224     }
227     /* Save the edited entry */
228     if(isset($_POST['SaveSubObject'])){
230       /* Check if there are still errors remaining that must be fixed before saving */
231       $this->dialog->save_object();
232       $msgs = $this->dialog->check();
233       if(count($msgs)>0){
234         foreach($msgs as $msg){
235           msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
236         }
237       }else{
239         /* Get return object */
240         $obj = $this->dialog->save();
242         /* If we have renamed the script entry, we must remove the old entry */
243         if(isset($obj['remove'])){
245           /* Get old entry values */
246           $old_stat = $this->SubObjects[$obj['remove']['from']]['status'];
248           /* Depending on status, set new status */
249           if($old_stat == "edited" || $old_stat == "FreshLoaded"){
250             $this->SubObjects[$obj['remove']['from']]['status'] = "delete";
251           }elseif($this->SubObjects[$obj['remove']['from']]['status']=="new"){
252             unset($this->SubObjects[$obj['remove']['from']]);
253           }
255           /* Append the new entry */
256           $obj['status'] = "new";
257           $this->SubObjects[$obj['remove']['to']] = $obj;
258           unset($this->SubObjects[$obj['remove']['to']]['remove']);
259         }else{
260   
261           /* Set new status and append the entry */
262           if($obj['status'] == "FreshLoaded"){
263             $obj['status'] = "edited";
264           }
265           $this->SubObjects[$obj['cn']]=$obj;
266         }
267         $this->is_dialog=false;
268         unset($this->dialog);
269         $this->dialog=FALSE;
271       }
272     }
274     /* Cancel Dialog */
275     if(isset($_POST['CancelSubObject'])){
276       $this->is_dialog=false; 
277       unset($this->dialog);
278       $this->dialog=FALSE;
279     }
281     /* Print dialog if $this->dialog is set */
282     if(is_object($this->dialog)){
283       $this->dialog->save_object();
284       $display = $this->dialog->execute();
285       return($display);
286     }
288     $this->scriptListWidget->setListData($this->convertList(TRUE), $this->convertList());
289     $this->scriptListWidget->update();
290     $smarty->assign("Entry_divlist",$this->scriptListWidget->render());
292     /* Magic quotes GPC, escapes every ' " \, to solve some security risks
293      * If we post the escaped strings they will be escaped again
294      */
295     foreach($this->attributes as $attrs){
296       if(get_magic_quotes_gpc()){
297         $smarty->assign($attrs,stripslashes($this->$attrs));
298       }else{
299         $smarty->assign($attrs,($this->$attrs));
300       }
301     }
303     $dn = $this->acl_base_for_current_object($this->dn);
304     $smarty->assign("sub_object_is_addable",  
305         preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiScriptEntry")) && 
306         !preg_match("/freeze/",$this->FAIstate));
308     $tmp = $this->plInfo();
309     foreach($tmp['plProvidedAcls'] as $name => $translated){
310       $smarty->assign($name."ACL",$this->getacl($name));
311     }
313     $display.= $smarty->fetch(get_template_path('faiScript.tpl', TRUE));
314     return($display);
315   }
318   /* Generate listbox friendly SubObject list
319    */
320   function getList($use_dns=false){
321     $a_return=array();
322     foreach($this->SubObjects as $obj){
323       if($obj['status'] != "delete"){
325         $cn   = stripslashes($obj['cn']);
326         $desc = "";
328         if((isset($obj['description']))&&(!empty($obj['description']))){
329           $desc = " [".stripslashes($obj['description'])."]";
330         }
332         if($use_dns){
333           $a_return[$obj['cn']]['name']= $cn.$desc;
334           $a_return[$obj['cn']]['dn']= $obj['dn'];
335           $a_return[$obj['cn']]['FAIpriority']= $obj['FAIpriority'];
336         }else{
337           $a_return[$obj['cn']] =  $cn.$desc;
338         }
339       }
340     }
341     return($a_return);
342   }
345   /* Delete me, and all my subtrees
346    */
347   function remove_from_parent()
348   {
349     if($this->acl_is_removeable()){
350       $ldap = $this->config->get_ldap_link();
351       $ldap->cd ($this->dn);
352       $release = $this->parent->parent->fai_release;
353       $use_dn = preg_replace("/".preg_quote(FAI::get_release_dn($this->dn), '/')."/i", $release, $this->dn);
354       new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
355       FAI::prepare_to_save_FAI_object($use_dn,array(),true);
356  
357       foreach($this->SubObjects as $name => $obj){
358         $use_dn = preg_replace("/".preg_quote(FAI::get_release_dn($this->dn), '/')."/i", $release, $obj['dn']);
359         FAI::prepare_to_save_FAI_object($use_dn,array(),true);
360       }
361       $this->handle_post_events("remove");
362     }
363   }
366   /* Save data to object 
367    */
368   function save_object()
369   {
370     if((isset($_POST['FAIscript_posted'])) && !preg_match("/freeze/", $this->FAIstate)){
371       plugin::save_object();
372     }
373     
374     /* Get sort order */
375     if(isset($_GET['sort']) && in_array($_GET['sort'],array("name","priority"))){
376       if($this->sort_by == $_GET['sort']){
377         if($this->sort_order == "up"){
378           $this->sort_order = "down";
379         }elseif($this->sort_order == "down"){
380           $this->sort_order = "up";
381         }
382       }
383       $this->sort_by = $_GET['sort'];
384     }
385   }
388   /* Check supplied data */
389   function check()
390   {
391     /* Call common method to give check the hook */
392     $message= plugin::check();
394     /* Ensure that we do not overwrite an allready existing entry 
395      */
396     if($this->is_new){
397       $release = $this->parent->parent->fai_release;
398       $new_dn= 'cn='.$this->cn.",".get_ou('faiScriptRDN').get_ou('faiBaseRDN').$release;
399       $res = faiManagement::check_class_name("FAIscript",$this->cn,$new_dn);
400       if(isset($res[$this->cn])){
401         $message[] = msgPool::duplicated(_("Name"));
402       }
403     }
405     return ($message);
406   }
409   /* Save to LDAP */
410   function save()
411   {
412     plugin::save();
414     $ldap = $this->config->get_ldap_link();
416     FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
418     if($this->initially_was_account){
419       new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
420     }else{
421       new log("create","fai/".get_class($this),$this->dn,$this->attributes);
422     }
424     /* Prepare FAIscriptEntry to write it to ldap
425      * First sort array.
426      *  Because we must delete old entries first.
427      * After deletion, we perform add and modify 
428      */
429     $Objects = array();
431     /* We do not need to save untouched objects */
432     foreach($this->SubObjects as $name => $obj){
433       if($obj['status'] == "FreshLoaded"){
434         unset($this->SubObjects[$name]);
435       }
436     }
438     foreach($this->SubObjects as $name => $obj){
439       if($obj['status'] == "delete"){
440         $Objects[$name] = $obj; 
441       }
442     }
443     foreach($this->SubObjects as $name => $obj){
444       if($obj['status'] != "delete"){
445         $Objects[$name] = $obj; 
446       }
447     }
449     foreach($Objects as $name => $obj){
451       foreach($this->sub64coded as $codeIt){
452         $obj[$codeIt]=postEncode(stripslashes($obj[$codeIt]));
453       }
455       $tmp = array();
456       $attributes = array_merge($this->sub_Load_Later,$this->subAttributes);
457       foreach($attributes as $attrs){
458         if(!isset($obj[$attrs])) continue; 
459         if($obj[$attrs] == ""){
460           $obj[$attrs] = array();
461         }
462         if(!is_array($obj[$attrs])){
463           $tmp[$attrs] = stripslashes($obj[$attrs]);
464         }else{
465           $tmp[$attrs] = $obj[$attrs];
466         }
467       }    
469       $tmp['objectClass'] = $this->subClasses;
471       $sub_dn = "cn=".$obj['cn'].",".$this->dn;
473       if($obj['status']=="new"){
474         $ldap->cat($sub_dn,array("objectClass"));
475         if($ldap->count()){
476           $obj['status']="edited";
477         }
478       }
480       if(empty($tmp['FAIpriority'])){
481         $tmp['FAIpriority']  ="0";
482       }
484       /* Tag object */
485       $this->tag_attrs($tmp, $sub_dn, $this->gosaUnitTag);
487       if($obj['status'] == "delete"){
488         FAI::prepare_to_save_FAI_object($sub_dn,array(),true);
489         $this->handle_post_events("remove");
490       }elseif($obj['status'] == "edited"){
491         FAI::prepare_to_save_FAI_object($sub_dn,$tmp);
492         $this->handle_post_events("modify");
493       }elseif($obj['status']=="new"){
494         FAI::prepare_to_save_FAI_object($sub_dn,$tmp);
495         $this->handle_post_events("add");
496       }
497     }
498   }
501   function PrepareForCopyPaste($source)
502   {
503     plugin::PrepareForCopyPaste($source);
505     /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
506      */
507     $res = FAI::get_all_objects_for_given_base($source['dn'],"(&(objectClass=FAIclass)(objectClass=".$this->subClass."))");
508     foreach($res as $obj){
510       /* Skip not relevant objects */
511       if(!preg_match("/".preg_quote($source['dn'], '/')."$/i",$obj['dn'])) continue;
513       $objects = array();
514       $objects['status']      = "edited";
515       $objects['dn']          = $obj['dn'];
516       $objects                = $this->get_object_attributes($objects,$this->subAttributes);
517       $objects                = $this->get_object_attributes($objects,$this->sub_Load_Later);
518       $this->SubObjects[$objects['cn']] = $objects;
519     }
520   }
523   /*! \brief  Used for copy & paste.
524               Returns a HTML input mask, which allows to change the cn of this entry.
525       @param  Array   Array containing current status && a HTML template.
526    */
527   function getCopyDialog()
528   {
529     $vars = array("cn");
530     $smarty = get_smarty();
531     $smarty->assign("cn", htmlentities($this->cn));
532     $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
533     $ret = array();
534     $ret['string'] = $str;
535     $ret['status'] = "";
536     return($ret);
537   }
540   /*! \brief  Used for copy & paste.
541               Some entries must be renamed to avaoid duplicate entries.
542    */
543   function saveCopyDialog()
544   {
545     if(isset($_POST['cn'])){
546       $this->cn = get_post('cn');
547     }
548   }
549   
551   /* Return plugin informations for acl handling */ 
552   static function plInfo()
553   {
554     return (array( 
555           "plShortName" => _("Script"),
556           "plDescription" => _("FAI script"),
557           "plSelfModify"  => FALSE,
558           "plDepends"     => array(),
559           "plPriority"    => 18,
560           "plSection"     => array("administration"),
561           "plCategory"    => array("fai"),
562           "plProvidedAcls" => array(
563             "cn"                => _("Name")." ("._("Readonly").")",
564             "description"       => _("Description"))
565           ));
566   }
569 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
570 ?>