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 /* Remove entries from hdd that are older than24 hours */
84 $fp = opendir(LDAP_DUMP_PATH);
85 while($file = readdir($fp)){
86 if(is_file(LDAP_DUMP_PATH."/".$file) && !preg_match("/^\./",$file)){
87 $file_time = fileatime(LDAP_DUMP_PATH."/".$file);
88 if($file_time < (time() - (24* 60 *60))){
89 @unlink(LDAP_DUMP_PATH."/".$file);
90 }
91 }
92 }
93 }
96 /* To increase performance we save the ldap dump on hdd
97 * This function automatically creates the dumps and returns
98 * the name of the dumpfile we created
99 */
100 function save_dn_attributes_to_hdd($dn)
101 {
102 $filename = "Should not be returned";
103 $ldap = $this->config->get_ldap_link();
104 $ldap->cd($this->config->current['BASE']);
105 $res = $ldap->cat($dn);
107 /* Check if given dn is valid and ldap search was succesfull */
108 if(!$res){
109 print_red(sprintf(_("Specified object '%s' is not a valid ldap object, please check copy & paste methods.")));
110 new log("copy","all/all",$dn,array(),"Could not create dump of ldap object, given object is not present in the ldap database.");
111 return(FALSE);
112 }
114 /* Create data to save given ldap dump on the hdd */
115 $filename = "gosa_copy-paste_dump_".preg_replace("/[^0-9]/","",microtime());
116 $path = LDAP_DUMP_PATH;
118 /* Create patch if it doesn't exists */
119 if(!is_dir($path)){
120 @mkdir($path);
121 }
123 /* check if we are able to create a new file the given directory */
124 if(!is_writeable($path)){
125 print_red(sprintf(_("We are not allowed to save ldap dump to '%s', please check permissions."),$path));
126 new log("copy","all/all",$dn,array(),
127 sprintf("We are not allowed to save ldap dump to '%s', please check permissions.",$path));
128 return(FALSE);
129 }
131 /* Create file handle */
132 $fp = @fopen($path."/".$filename,"w+");
133 if(!$fp){
134 print_red(sprintf(_("We are not allowed to save ldap dump to '%s/%s', please check permissions."),$path,$filename));
135 new log("copy","all/all",$dn,array(),
136 sprintf("We are not allowed to save ldap dump to '%s/%s', please check permissions.",$path,$filename));
137 return(FALSE);
138 }
140 $data = serialize($ldap->fetch());
141 fwrite($fp,$data,strlen($data));
142 fclose($fp);
144 /* Only the webserver should be able to read those files */
145 @chmod($path."/".$filename,0600);
146 return($path."/".$filename);
147 }
150 /* Check if there are still entries the object queue */
151 function entries_queued()
152 {
153 return( count($this->queue) >=1 || $this->current != FALSE);
154 }
157 /* Paste one entry from queue */
158 function load_entry_from_queue()
159 {
161 /* Save posted variables, handle dialog posts like 'cancel' */
162 $this->save_object();
164 /* If there is currently no object pasted
165 * create new object and prepare object to be pasted
166 */
167 if(!$this->current && $this->entries_queued()){
168 $key = key($this->queue);
169 $entry = $this->queue[$key];
170 $tab_c = $entry['tab_class'];
171 $tab_o = $entry['tab_object'];
172 $tab_a = $entry['tab_acl_category'];
174 if($entry['method'] == "copy"){
175 $entry['object'] = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],"new",$tab_a);
176 }else{
177 $entry['object'] = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],$entry['dn'],$tab_a);
178 }
180 $entry['source_data'] = $this->load_attributes_from_hdd($entry['file_name']);
182 if($entry['method'] == "copy"){
184 /* Prepare each plugin of this tab object to be posted */
185 foreach($entry['object']->by_object as $name => $obj){
187 /* Prepare every single class, to be copied */
188 $entry['object']->by_object[$name]->PrepareForCopyPaste($entry['source_data']);
190 /* handle some special vars */
191 foreach(array("is_account") as $attr){
192 if(isset($entry['source_data'][$attr])){
193 $entry['object']->by_object[$name]->$attr = $entry['source_data'][$attr];
194 }
195 }
196 }
197 }
199 /* Assign created object as current */
200 $this->current = $entry;
201 unset($this->queue[$key]);
202 }
203 }
206 /* Load dumped ldap entry specified by $filename and
207 * return data an unserailized data array
208 */
209 function load_attributes_from_hdd($filename)
210 {
211 $fp = @fopen($filename,"r");
212 if(is_file($filename) && is_readable($filename) && $fp){
213 $data = "";
214 while($str = fgets($fp,512)){
215 $data .= $str;
216 }
217 return(unserialize($data));
218 }else{
219 print_red(sprintf(_("Could not load dumped file '%s', from hard disk drive."),$filename));
220 new log("copy","all/all",$dn,array(),
221 sprintf(sprintf("Could not load dumped file '%s', from hard disk drive.",$filename)));
222 return(FALSE);
223 }
224 }
227 /* Displays a dialog which allows the user to fix all dependencies of this object.
228 Create unique names, ids, or what ever */
229 function execute()
230 {
231 $type = $this->current['method'];
232 if($type == "cut"){
233 if(isset($_POST['PerformCopyPaste'])){
234 while($this->entries_queued()){
235 $this->load_entry_from_queue();
236 $this->_update_vars();
238 $msgs = $this->check();
239 if(count ($msgs) ){
240 foreach( $msgs as $msg){
241 print_red($msg);
242 }
243 }else{
245 /* Load next queue entry */
246 $this->lastdn = $this->current['object']->dn;
247 $this->current['object']->save();
248 }
250 $this->current =FALSE;
251 }
252 }
253 if($this->current){
255 $dns = $this->current['dn']."\n";
256 foreach($this->queue as $entry){
257 $dns .= $entry['dn']."\n";
258 }
260 $smarty = get_smarty();
261 $smarty->assign("type","cut");
262 $smarty->assign("Complete",false);
263 $smarty->assign("AttributesToFix"," ");
264 $smarty->assign("SubDialog",$this->current['object']->SubDialog);
265 $smarty->assign("objectDN" ,$dns);
266 $smarty->assign("message", sprintf(_("You are going to paste the cutted entry '%s'."), "<pre>".$dns."</pre>"));
267 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
268 }
269 }
270 if($type == "copy"){
271 if(isset($_POST['PerformCopyPaste'])){
272 $this->_update_vars();
273 $msgs = $this->check();
274 if(count ($msgs) ){
275 foreach( $msgs as $msg){
276 print_red($msg);
277 }
278 }else{
279 $this->current['object']->save();
280 $this->lastdn = $this->current['object']->dn;
281 $this->current =FALSE;
283 /* Load next queue entry */
284 $this->load_entry_from_queue();
285 }
286 }
287 if($this->current){
288 $smarty = get_smarty();
289 $smarty->assign("type","copy");
290 $smarty->assign("Complete",false);
291 $smarty->assign("AttributesToFix",$this->generateAttributesToFix());
292 $smarty->assign("SubDialog",$this->current['object']->SubDialog);
293 $smarty->assign("objectDN" ,$this->current['source_data']['dn']);
294 $smarty->assign("message", sprintf(_("You are going to paste the copied entry '%s'."), $this->current['source_data']['dn']));
295 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
296 }
297 }
298 }
301 /* Return the dn of the last edited entry */
302 function last_entry()
303 {
304 return($this->lastdn);
305 }
308 /* Save new values posted by copy & paste dialog */
309 function save_object()
310 {
311 if(isset($_POST['abort_current_cut-copy_operation'])){
312 $this->current = FALSE;
313 }
315 if(isset($_POST['abort_all_cut-copy_operations'])){
316 $this->cleanup_queue();
317 $this->current = FALSE;
318 }
320 /* Assign posted var to all tabs
321 */
322 if($this->current){
323 $this->current['object']->saveCopyDialog();
324 }
325 }
328 /* Create dialog which asks unique attributes/values ...
329 * call tabs -> getCopyDialog()
330 * which calls tab -> getCopyDialog() */
331 function generateAttributesToFix()
332 {
333 if($this->current){
334 return($this->current['object']->getCopyDialog());
335 }
336 }
339 /* Set a single attribute to specified value
340 * example : ("base", $newBase ); */
341 function SetVar($name,$value)
342 {
343 $this->setvar_array[$name]=$value;
344 }
347 /* Update current object attributes, collected via SetVar */
348 function _update_vars()
349 {
350 if($this->current){
352 /* Update all attributes specified with SetVar */
353 foreach($this->setvar_array as $name => $value){
354 if(isset($this->current['object']->$name)){
355 $this->current['object']->$name = $value;
356 }
357 }
359 /* Walk through tabs */
360 foreach($this->current['object']->by_object as $key => $obj){
362 /* Update all attributes specified with SetVar */
363 foreach($this->setvar_array as $name => $value){
364 if(isset($this->current['object']->by_object[$key]->$name)){
365 $this->current['object']->by_object[$key]->$name = $value;
366 }
367 }
368 }
369 }
370 }
373 /* Returns errors from including tabs. */
374 function check()
375 {
376 $ret = array();
377 foreach($this->current['object']->by_object as $obj){
378 if($obj->is_account){
379 $ret = array_merge($ret , $obj->check());
380 }
381 }
382 return($ret);
383 }
386 /* returns the paste icon for headpages */
387 function generatePasteIcon()
388 {
389 $Copy_Paste= " <img class='center' src='images/list_seperator.png' align='middle' alt='' height='16' width='1'> ";
390 if($this->entries_queued()){
391 $img= "images/copypaste.png";
392 $Copy_Paste.= "<input type='image' name='editPaste' class='center'
393 src='".$img."' alt='"._("Paste")."'> ";
394 }else{
395 $Copy_Paste.= "<img class='center' src='images/cant_editpaste.png' alt=\""._("Can't paste")."\"> ";
396 }
397 return ($Copy_Paste);
398 }
399 }
400 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
401 ?>