Code

Added a first set of reference changes - nearly untested
[gosa.git] / include / class_CopyPasteHandler.inc
1 <?php
3 define("LDAP_DUMP_PATH","/tmp/gosa");
5 class CopyPasteHandler {
7   var $config;
8   var $current;
10   /* This array contains all dns of the currently copyied objects */
11   var $queue       = array(); 
13   /* Attributes that should be overwritten */
14   var $setvar_array= array();
16   /* The dn of the last edited object */
17   var $lastdn      = "";
20   /* Create CP handler  */
21   function CopyPasteHandler(&$config)
22   {
23     $this->config = &$config;   
24     $this->current= NULL;
25     $this->queue  = array();
26     $this->setvar_array = array();
27   }
30   /* Entry entry to Copy & Paste queue.
31    * A Queue entry is represented as follows.
32    *  array['file_name']  - Position on hdd 
33    *  array['method']     - copy/cut
34    *  array['dn']         - the dn of the object added to the queue 
35    *  array['tab_class']  - Tab object that should be used to initialize the new object
36    *  array['tab_object'] - Tab object name used to initialize correct object Type like USERTABS
37    */
38   function add_to_queue($dn,$action,$tab_class,$tab_object,$tab_acl_category)
39   {
40     if(!class_exists($tab_class)){
41       trigger_error(sprintf("Specified class object '%s' does not exists.",$tab_class));
42       return(FALSE);
43     }
45     if(!isset($this->config->data['TABS'][$tab_object])){
46       trigger_error(sprintf("Specified tab object '%s' does not exists.",$tab_object));
47       return(FALSE);
48     }
50     if(!in_array($action,array("cut","copy"))){
51       trigger_error(sprintf("Specified action '%s' does not exists for copy & paste.",$action));
52       return(FALSE);
53     } 
55     if($file_name = $this->save_dn_attributes_to_hdd($dn)){
56       $tmp = array();
57       $tmp['file_name'] = $file_name;
58       $tmp['method']    = $action;  
59       $tmp['dn']        = $dn;
60       $tmp['tab_class'] = $tab_class;
61       $tmp['tab_object']= $tab_object;
62       $tmp['tab_acl_category']= $tab_acl_category;
63       $this->queue[]    = $tmp; 
64     }
65   }
68   /* This removes all objects from queue.
69    * Remove hdd dumps of current entries too.
70    * Remove entries older than 24 hours.
71    */
72   function cleanup_queue()
73   {
74     $this->current = FALSE;
75     $this->setvar_array = array();
77     /* Remove all entries from queue */  
78     foreach($this->queue as $key => $entry){
79       @rmdir($entry['file_name']);  
80       unset($this->queue[$key]);
81     }
83     /* Create patch if it doesn't exists */
84     if(!is_dir(LDAP_DUMP_PATH)){
85       @mkdir(LDAP_DUMP_PATH);
86     }    
87     
88     /* check if we are able to create a new file the given directory */
89     if(!is_writeable(LDAP_DUMP_PATH)){
90       print_red(sprintf(_("Could not cleanup copy & paste queue. We are not allowed to save ldap dump to '%s', please check permissions."),LDAP_DUMP_PATH));
91       new log("copy","all/all","copy & paste, event queue.",array(),
92           sprintf("Could not cleanup copy & paste queue. We are not allowed to save ldap dump to '%s', please check permissions.",LDAP_DUMP_PATH));
93       return(FALSE);
94     }
96     /* Remove entries from hdd that are older than24 hours */
97     $fp = opendir(LDAP_DUMP_PATH);
98     while($file = readdir($fp)){
99       if(is_file(LDAP_DUMP_PATH."/".$file) && !preg_match("/^\./",$file)){
100         $file_time = fileatime(LDAP_DUMP_PATH."/".$file);
101         if($file_time < (time() - (24* 60 *60))){
102           @unlink(LDAP_DUMP_PATH."/".$file);
103         }
104       }
105     }
106   }
109   /* To increase performance we save the ldap dump on hdd 
110    * This function automatically creates the dumps and returns 
111    *  the name of the dumpfile we created 
112    */
113   function save_dn_attributes_to_hdd($dn)
114   {
115     $filename = "Should not be returned";
116     $ldap = $this->config->get_ldap_link();
117     $ldap->cd($this->config->current['BASE']);
118     $res  = $ldap->cat($dn);
120     /* Check if given dn is valid and ldap search was succesfull */ 
121     if(!$res){
122       print_red(sprintf(_("Specified object '%s' is not a valid ldap object, please check copy & paste  methods.")));
123       new log("copy","all/all",$dn,array(),"Could not create dump of ldap object, given object is not present in the ldap database.");
124       return(FALSE);
125     }
127     /* Create data to save given ldap dump on the hdd */
128     $filename = "gosa_copy-paste_dump_".preg_replace("/[^0-9]/","",microtime());
129     $path     = LDAP_DUMP_PATH;
131     /* Create patch if it doesn't exists */
132     if(!is_dir($path)){
133       @mkdir($path);
134     }    
136     /* check if we are able to create a new file the given directory */
137     if(!is_writeable($path)){
138       print_red(sprintf(_("We are not allowed to save ldap dump to '%s', please check permissions."),$path));
139       new log("copy","all/all",$dn,array(), 
140           sprintf("We are not allowed to save ldap dump to '%s', please check permissions.",$path));
141       return(FALSE);
142     }  
144     /* Create file handle */
145     $fp = @fopen($path."/".$filename,"w+");
146     if(!$fp){
147       print_red(sprintf(_("We are not allowed to save ldap dump to '%s/%s', please check permissions."),$path,$filename));
148       new log("copy","all/all",$dn,array(), 
149           sprintf("We are not allowed to save ldap dump to '%s/%s', please check permissions.",$path,$filename));
150       return(FALSE);
151     }    
153     $data = serialize($ldap->fetch());
154     fwrite($fp,$data,strlen($data));
155     fclose($fp);
157     /* Only the webserver should be able to read those files */
158     @chmod($path."/".$filename,0600); 
159     return($path."/".$filename);
160   }
163   /* Check if there are still entries the object queue */
164   function entries_queued()
165   {
166     return( count($this->queue) >=1 || $this->current != FALSE);
167   }
170   /* Paste one entry from queue */
171   function load_entry_from_queue()
172   {
174     /* Save posted variables, handle dialog posts like 'cancel' */
175     $this->save_object();
177     /* If there is currently no object pasted 
178      *  create new object and prepare object to be pasted
179      */
180     if(!$this->current && $this->entries_queued()){
181       $key    = key($this->queue);
182       $entry  = $this->queue[$key];
183       $tab_c = $entry['tab_class'];
184       $tab_o = $entry['tab_object'];
185       $tab_a = $entry['tab_acl_category'];
187       if($entry['method'] == "copy"){
188         $entry['object']      = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],"new",$tab_a);
189       }else{
190         $entry['object']      = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],$entry['dn'],$tab_a);
191       }
193       $entry['source_data'] = $this->load_attributes_from_hdd($entry['file_name']);
195       if($entry['method'] == "copy"){
197         /* Prepare each plugin of this tab object to be posted */
198         foreach($entry['object']->by_object as $name => $obj){
200           /* Prepare every single class, to be copied  */
201           $entry['object']->by_object[$name]->PrepareForCopyPaste($entry['source_data']);
203           /* handle some special vars */
204           foreach(array("is_account") as $attr){
205             if(isset($entry['source_data'][$attr])){
206               $entry['object']->by_object[$name]->$attr = $entry['source_data'][$attr];
207             }
208           }
209         }
210       }
212       /* Assign created object as current */
213       $this->current = $entry;
214       unset($this->queue[$key]);
215     }
216   }
219   /* Load dumped ldap entry specified by $filename and 
220    *  return data an unserailized data array
221    */
222   function load_attributes_from_hdd($filename)
223   {
224     $fp = @fopen($filename,"r");
225     if(is_file($filename) && is_readable($filename) && $fp){
226       $data = "";
227       while($str = fgets($fp,512)){
228         $data .= $str;
229       }
230       return(unserialize($data));
231     }else{
232       print_red(sprintf(_("Could not load dumped file '%s', from hard disk drive."),$filename));
233       new log("copy","all/all",$dn,array(), 
234           sprintf(sprintf("Could not load dumped file '%s', from hard disk drive.",$filename)));
235       return(FALSE);
236     }
237   }
240   /* Displays a dialog which allows the user to fix all dependencies of this object.
241      Create unique names, ids, or what ever */
242   function execute()
243   {
244     $ui = get_userinfo();
245     $type = $this->current['method'];
246     if($type == "cut"){
247       if(isset($_POST['PerformCopyPaste'])){
248         while($this->entries_queued()){
249           $this->load_entry_from_queue();      
250           $this->_update_vars();
252           $msgs = $this->check();
253           $acl = $ui->get_category_permissions($this->current['dn'], $this->current['tab_acl_category']);
254  
255           /* Check permissions */ 
256           if(!preg_match("/((c|w)|(w|c))/",$acl)){
257             print_red(sprintf(_("You are not allowed to cut and paste the following object '%s'."),$this->current['dn']));
258           }elseif(count ($msgs) ){
259             foreach( $msgs as $msg){
260               print_red($msg);
261             }
262           }else{
264             /* Load next queue entry */
265             $this->lastdn = $this->current['object']->dn;
266             $this->current['object']->save();
267           }
269           $this->current =FALSE;
270         }
271       }
272       if($this->current){
274         $dns = $this->current['dn']."\n";
275         foreach($this->queue as $entry){
276           $dns .= $entry['dn']."\n";
277         }
279         $smarty = get_smarty();
280         $smarty->assign("type","cut");
281         $smarty->assign("Complete",false);
282         $smarty->assign("AttributesToFix","&nbsp;");
283         $smarty->assign("SubDialog",$this->current['object']->SubDialog);
284         $smarty->assign("objectDN"     ,$dns);
285         $smarty->assign("message", sprintf(_("You are going to paste the cutted entry '%s'."), "<pre>".$dns."</pre>"));
286         return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
287       }
288     }
289     if($type == "copy"){
290       if(isset($_POST['PerformCopyPaste'])){
291         $this->_update_vars();
292         $msgs = $this->check();
294         $acl = $ui->get_category_permissions($this->current['dn'], $this->current['tab_acl_category']);
295  
296         /* Check permissions */ 
297         if(!preg_match("/((c|w)|(w|c))/",$acl)){
298           print_red(sprintf(_("You are not allowed to copy and paste the following object '%s'."),$this->current['dn']));
299         }elseif(count ($msgs) ){
300           foreach( $msgs as $msg){
301             print_red($msg);
302           }
303         }else{
304           $this->current['object']->save();
305           $this->lastdn = $this->current['object']->dn;
306           $this->current =FALSE;
308           /* Load next queue entry */
309           $this->load_entry_from_queue();
310         }
311       }
312       if($this->current){
313         $smarty = get_smarty();
314         $smarty->assign("type","copy");
315         $smarty->assign("Complete",false);
316         $smarty->assign("AttributesToFix",$this->generateAttributesToFix());
317         $smarty->assign("SubDialog",$this->current['object']->SubDialog);
318         $smarty->assign("objectDN"     ,$this->current['source_data']['dn']);
319         $smarty->assign("message", sprintf(_("You are going to paste the copied entry '%s'."), $this->current['source_data']['dn']));
320         return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
321       }
322     }
323   }
326   /* Return the dn of the last edited entry */
327   function last_entry()
328   {
329     return($this->lastdn);
330   }
333   /* Save new values posted by copy & paste dialog */
334   function save_object()
335   {
336     if(isset($_POST['abort_current_cut-copy_operation'])){
337       $this->current = FALSE;
338     }
340     if(isset($_POST['abort_all_cut-copy_operations'])){
341       $this->cleanup_queue();
342       $this->current = FALSE;
343     }
345     /* Assign posted var to all tabs
346      */
347     if($this->current){
348       $this->current['object']->saveCopyDialog();
349     }
350   }
353   /* Create dialog which asks unique attributes/values ... 
354    *  call tabs -> getCopyDialog() 
355    *    which calls tab -> getCopyDialog()  */
356   function generateAttributesToFix()
357   {
358     if($this->current){
359       return($this->current['object']->getCopyDialog());  
360     }
361   }
364   /* Set a single attribute to specified value
365    *  example :   ("base", $newBase );    */
366   function SetVar($name,$value)
367   {
368     $this->setvar_array[$name]=$value; 
369   }
372   /* Update current object attributes, collected via SetVar */
373   function _update_vars()
374   {
375     if($this->current){
377       /* Update all attributes specified with SetVar */
378       foreach($this->setvar_array as $name => $value){
379         if(isset($this->current['object']->$name)){
380           $this->current['object']->$name = $value;
381         }
382       }
384       /* Walk through tabs */
385       foreach($this->current['object']->by_object as $key => $obj){
387         /* Update all attributes specified with SetVar */
388         foreach($this->setvar_array as $name => $value){
389           if(isset($this->current['object']->by_object[$key]->$name)){
390             $this->current['object']->by_object[$key]->$name = $value;
391           }
392         }
393       }
394     }
395   }
398   /* Returns errors from including tabs. */
399   function check()
400   {
401     $ret = array();
402     foreach($this->current['object']->by_object as $obj){
403       if($obj->is_account){
404         $ret = array_merge($ret , $obj->check());
405       }
406     }
407     return($ret);
408   }
411   /* returns the paste icon for headpages */ 
412   function generatePasteIcon()
413   {
414     $Copy_Paste= "&nbsp;<img class='center' src='images/list_seperator.png' align='middle' alt='' height='16' width='1'>&nbsp;";
415     if($this->entries_queued()){
416       $img= "images/copypaste.png";
417       $Copy_Paste.= "<input type='image' name='editPaste' class='center'
418         src='".$img."' alt='"._("Paste")."'>&nbsp;";
419     }else{
420       $Copy_Paste.= "<img class='center' src='images/cant_editpaste.png' alt=\""._("Can't paste")."\">&nbsp;";
421     }
422     return ($Copy_Paste);
423   }
425 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
426 ?>