1 <?php
3 define("LDAP_DUMP_PATH","/tmp/gosa");
5 class CopyPasteHandler {
7 var $config;
8 var $current;
10 var $copyCurrent = false;
11 var $cutCurrent = false;
12 var $dialogOpen = false;
13 var $objectdn = false;
15 var $was_successfull = false;
17 /* this array contains all dns of the currently copyied objects */
18 var $queue = array();
19 var $setvar_array= array();
20 var $lastdn = "";
22 /* Create CP handler */
23 function CopyPasteHandler($config)
24 {
25 $this->config = $config;
26 $this->current= NULL;
27 $this->queue = array();
28 $this->setvar_array = array();
29 }
32 /* Entry entry to Copy & Paste queue.
33 * A Queue entry is represented as follows.
34 * array['file_name'] - Position on hdd
35 * array['method'] - copy/cut
36 * array['dn'] - the dn of the object added to the queue
37 * array['tab_class'] - Tab object that should be used to initialize the new object
38 * array['tab_object'] - Tab object name used to initialize correct object Type like USERTABS
39 */
40 function add_to_queue($dn,$action,$tab_class,$tab_object)
41 {
42 if(!class_exists($tab_class)){
43 trigger_error(sprintf("Specified class object '%s' does not exists.",$tab_class));
44 return(FALSE);
45 }
47 if(!isset($this->config->data['TABS'][$tab_object])){
48 trigger_error(sprintf("Specified tab object '%s' does not exists.",$tab_object));
49 return(FALSE);
50 }
52 if(!in_array($action,array("cut","copy"))){
53 trigger_error(sprintf("Specified action '%s' does not exists for copy & paste.",$action));
54 return(FALSE);
55 }
57 if($file_name = $this->save_dn_attributes_to_hdd($dn)){
58 $tmp = array();
59 $tmp['file_name'] = $file_name;
60 $tmp['method'] = $action;
61 $tmp['dn'] = $dn;
62 $tmp['tab_class'] = $tab_class;
63 $tmp['tab_object']= $tab_object;
64 $this->queue[] = $tmp;
65 }
66 }
69 /* This removes all objects from queue.
70 * Remove hdd dumps of current entries too.
71 * Remove entries older than 24 hours.
72 */
73 function cleanup_queue()
74 {
75 $this->current = FALSE;
76 $this->setvar_array = array();
78 /* Remove all entries from queue */
79 foreach($this->queue as $key => $entry){
80 @rmdir($entry['file_name']);
81 unset($this->queue[$key]);
82 }
84 /* Remove entries from hdd that are older than24 hours */
85 $fp = opendir(LDAP_DUMP_PATH);
86 while($file = readdir($fp)){
87 if(is_file(LDAP_DUMP_PATH."/".$file) && !preg_match("/^\./",$file)){
88 $file_time = fileatime(LDAP_DUMP_PATH."/".$file);
89 if($file_time < (time() - (24* 60 *60))){
90 @unlink(LDAP_DUMP_PATH."/".$file);
91 }
92 }
93 }
94 }
97 /* To increase performance we save the ldap dump on hdd
98 * This function automatically creates the dumps and returns
99 * the name of the dumpfile we created
100 */
101 function save_dn_attributes_to_hdd($dn)
102 {
103 $filename = "Should not be returned";
104 $ldap = $this->config->get_ldap_link();
105 $ldap->cd($this->config->current['BASE']);
106 $res = $ldap->cat($dn);
108 /* Check if given dn is valid and ldap search was succesfull */
109 if(!$res){
110 print_red(sprintf(_("Specified object '%s' is not a valid ldap object, please check copy & paste methods.")));
111 new log("copy","all/all",$dn,array(),"Could not create dump of ldap object, given object is not present in the ldap database.");
112 return(FALSE);
113 }
115 /* Create data to save given ldap dump on the hdd */
116 $filename = "gosa_copy-paste_dump_".preg_replace("/[^0-9]/","",microtime());
117 $path = LDAP_DUMP_PATH;
119 /* Create patch if it doesn't exists */
120 if(!is_dir($path)){
121 @mkdir($path);
122 }
124 /* check if we are able to create a new file the given directory */
125 if(!is_writeable($path)){
126 print_red(sprintf(_("We are not allowed to save ldap dump to '%s', please check permissions."),$path));
127 new log("copy","all/all",$dn,array(),
128 sprintf("We are not allowed to save ldap dump to '%s', please check permissions.",$path));
129 return(FALSE);
130 }
132 /* Create file handle */
133 $fp = @fopen($path."/".$filename,"w+");
134 if(!$fp){
135 print_red(sprintf(_("We are not allowed to save ldap dump to '%s/%s', please check permissions."),$path,$filename));
136 new log("copy","all/all",$dn,array(),
137 sprintf("We are not allowed to save ldap dump to '%s/%s', please check permissions.",$path,$filename));
138 return(FALSE);
139 }
141 $data = serialize($ldap->fetch());
142 fwrite($fp,$data,strlen($data));
143 fclose($fp);
145 /* Only the webserver should be able to read those files */
146 @chmod($path."/".$filename,0600);
147 return($path."/".$filename);
148 }
151 /* Check if there are still entries the object queue */
152 function entries_queued()
153 {
154 return( count($this->queue) >=1 || $this->current != FALSE);
155 }
158 /* Paste one entry from queue */
159 function load_entry_from_queue()
160 {
162 /* Save posted variables, handle dialog posts like 'cancel' */
163 $this->save_object();
165 /* If there is currently no object pasted
166 * create new object and prepare object to be pasted
167 */
168 if(!$this->current && $this->entries_queued()){
169 $key = key($this->queue);
170 $entry = $this->queue[$key];
171 $tab_c = $entry['tab_class'];
172 $tab_o = $entry['tab_object'];
174 if($entry['method'] == "copy"){
175 $entry['object'] = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],"new");
176 }else{
177 $entry['object'] = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],$entry['dn'],"users");
178 }
182 $entry['source_data'] = $this->load_attributes_from_hdd($entry['file_name']);
184 if($entry['method'] == "copy"){
186 /* Prepare each plugin of this tab object to be posted */
187 foreach($entry['object']->by_object as $name => $obj){
189 /* Prepare every single class, to be copied */
190 $entry['object']->by_object[$name]->PrepareForCopyPaste($entry['source_data']);
192 /* handle some special vars */
193 foreach(array("is_account") as $attr){
194 if(isset($entry['source_data'][$attr])){
195 $entry['object']->by_object[$name]->$attr = $entry['source_data'][$attr];
196 }
197 }
198 }
199 }
201 /* Assign created object as current */
202 $this->current = $entry;
203 unset($this->queue[$key]);
204 }
205 }
208 /* Load dumped ldap entry specified by $filename and
209 * return data an unserailized data array
210 */
211 function load_attributes_from_hdd($filename)
212 {
213 $fp = @fopen($filename,"r");
214 if(is_file($filename) && is_readable($filename) && $fp){
215 $data = "";
216 while($str = fgets($fp,512)){
217 $data .= $str;
218 }
219 return(unserialize($data));
220 }else{
221 print_red(sprintf(_("Could not load dumped file '%s', from hard disk drive."),$filename));
222 new log("copy","all/all",$dn,array(),
223 sprintf(sprintf("Could not load dumped file '%s', from hard disk drive.",$filename)));
224 return(FALSE);
225 }
226 }
229 /* Displays a dialog which allows the user to fix all dependencies of this object.
230 Create unique names, ids, or what ever */
231 function execute()
232 {
233 $type = $this->current['method'];
234 if($type == "cut"){
235 if(isset($_POST['PerformCopyPaste'])){
236 while($this->entries_queued()){
237 $this->load_entry_from_queue();
238 $this->_update_vars();
240 $msgs = $this->check();
241 if(count ($msgs) ){
242 foreach( $msgs as $msg){
243 print_red($msg);
244 }
245 }else{
247 /* Load next queue entry */
248 $this->lastdn = $this->current['object']->dn;
249 $this->current['object']->save();
250 }
252 $this->current =FALSE;
253 }
254 }
255 if($this->current){
257 $dns = $this->current['dn']."\n";
258 foreach($this->queue as $entry){
259 $dns .= $entry['dn']."\n";
260 }
262 $smarty = get_smarty();
263 $smarty->assign("type","cut");
264 $smarty->assign("Complete",false);
265 $smarty->assign("AttributesToFix"," ");
266 $smarty->assign("SubDialog",$this->current['object']->SubDialog);
267 $smarty->assign("objectDN" ,$dns);
268 $smarty->assign("message", sprintf(_("You are going to paste the cutted entry '%s'."), "<pre>".$dns."</pre>"));
269 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
270 }
271 }
272 if($type == "copy"){
273 if(isset($_POST['PerformCopyPaste'])){
274 $this->_update_vars();
275 $msgs = $this->check();
276 if(count ($msgs) ){
277 foreach( $msgs as $msg){
278 print_red($msg);
279 }
280 }else{
281 $this->current['object']->save();
282 $this->lastdn = $this->current['object']->dn;
283 $this->current =FALSE;
285 /* Load next queue entry */
286 $this->load_entry_from_queue();
287 }
288 }
289 if($this->current){
290 $smarty = get_smarty();
291 $smarty->assign("type","copy");
292 $smarty->assign("Complete",false);
293 $smarty->assign("AttributesToFix",$this->generateAttributesToFix());
294 $smarty->assign("SubDialog",$this->current['object']->SubDialog);
295 $smarty->assign("objectDN" ,$this->current['source_data']['dn']);
296 $smarty->assign("message", sprintf(_("You are going to paste the copied entry '%s'."), $this->current['source_data']['dn']));
297 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
298 }
299 }
300 }
303 function last_entry()
304 {
305 return($this->lastdn);
306 }
309 /* Save new values posted by copy & paste dialog */
310 function save_object()
311 {
312 if(isset($_POST['abort_current_cut-copy_operation'])){
313 $this->current = FALSE;
314 }
316 if(isset($_POST['abort_all_cut-copy_operations'])){
317 $this->cleanup_queue();
318 $this->current = FALSE;
319 }
321 /* Assign posted var to all tabs
322 */
323 if($this->current){
324 $this->current['object']->saveCopyDialog();
325 }
326 }
329 /* Create dialog which asks unique attributes/values ...
330 * call tabs -> getCopyDialog()
331 * which calls tab -> getCopyDialog() */
332 function generateAttributesToFix()
333 {
334 if($this->current){
335 return($this->current['object']->getCopyDialog());
336 }
337 }
340 /* Set a single attribute to specified value
341 * example : ("base", $newBase ); */
342 function SetVar($name,$value)
343 {
344 $this->setvar_array[$name]=$value;
345 }
348 /* Update current object attributes, collected via SetVar */
349 function _update_vars()
350 {
351 if($this->current){
353 /* Update all attributes specified with SetVar */
354 foreach($this->setvar_array as $name => $value){
355 if(isset($this->current['object']->$name)){
356 $this->current['object']->$name = $value;
357 }
358 }
360 /* Walk through tabs */
361 foreach($this->current['object']->by_object as $key => $obj){
363 /* Update all attributes specified with SetVar */
364 foreach($this->setvar_array as $name => $value){
365 if(isset($this->current['object']->by_object[$key]->$name)){
366 $this->current['object']->by_object[$key]->$name = $value;
367 }
368 }
369 }
370 }
371 }
374 /* Returns errors from including tabs. */
375 function check()
376 {
377 $ret = array();
378 foreach($this->current['object']->by_object as $obj){
379 if($obj->is_account){
380 $ret = array_merge($ret , $obj->check());
381 }
382 }
383 return($ret);
384 }
387 /* returns the paste icon for headpages */
388 function generatePasteIcon()
389 {
390 $Copy_Paste= " <img class='center' src='images/list_seperator.png' align='middle' alt='' height='16' width='1'> ";
391 if($this->entries_queued()){
392 $img= "images/copypaste.png";
393 $Copy_Paste.= "<input type='image' name='editPaste' class='center'
394 src='".$img."' alt='"._("Paste")."'> ";
395 }else{
396 $Copy_Paste.= "<img class='center' src='images/cant_editpaste.png' alt=\""._("Can't paste")."\"> ";
397 }
399 return ($Copy_Paste);
400 }
419 /******** Functions below are unused and will be rewritten **********/
425 /* Add Object which should be cutted */
426 function Cut_old($obj)
427 {
428 $this->cutCurrent = true;
429 $this->current = $obj;
430 $this->objectdn = $obj->dn;
431 if($this->isCurrentObjectPastAble()){
432 return(true);
433 }else{
434 $this->cutCurrent = $this->copyCurrent = false;
435 $this->obj = NULL;
436 }
437 return(false);
438 }
441 /* Displays a dialog which allows the user to fix all dependencies of this object.
442 Create unique names, ids, or what ever */
443 function execute_old()
444 {
445 return;
446 /* Cut & paste
447 */
448 if($this->cutCurrent){
450 if(isset($_POST['PerformCopyPaste'])){
451 $msgs = $this->check();
452 if(count ($msgs) ){
453 foreach( $msgs as $msg){
454 print_red($msg);
455 }
456 }else{
457 $this->current->save();
458 $this->dialogOpen =false;
459 $this->Clear();
460 }
461 }
462 if($this->current){
463 $smarty = get_smarty();
464 $smarty->assign("type","cut");
465 $smarty->assign("Complete",false);
466 $smarty->assign("AttributesToFix"," ");
467 $smarty->assign("SubDialog",$this->current->SubDialog);
468 $smarty->assign("objectDN" ,$this->objectdn);
469 $smarty->assign("message", sprintf(_("You are going to paste the cutted entry '%s'."), $this->objectdn));
470 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
471 }
473 /* Copy & paste
474 */
475 }else{
476 if(isset($_POST['PerformCopyPaste'])){
477 $msgs = $this->check();
478 if(count ($msgs) ){
479 foreach( $msgs as $msg){
480 print_red($msg);
481 }
482 }else{
483 $this->current->save();
484 $this->lastdn = $this->current->dn;
485 $this->dialogOpen =false;
486 $this->Clear();
487 }
488 }
489 if($this->current){
490 $smarty = get_smarty();
491 $smarty->assign("type","copy");
492 $smarty->assign("Complete",false);
493 $smarty->assign("AttributesToFix",$this->generateAttributesToFix());
494 $smarty->assign("SubDialog",$this->current->SubDialog);
495 $smarty->assign("objectDN" ,$this->objectdn);
496 $smarty->assign("message", sprintf(_("You are going to paste the copied entry '%s'."), $this->objectdn));
497 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
498 }
499 }
500 }
502 /* Save new values posted by copy & paste dialog */
503 function save_object_2()
504 {
505 /* Assign posted var to all tabs
506 */
507 if($this->current){
508 $this->current->saveCopyDialog();
509 }
510 }
513 }
514 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
515 ?>