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 $lastdn = "";
16 var $was_successfull = false;
18 /* this array contains all dns of the currently copyied objects */
19 var $queue = array();
21 /* Create CP handler */
22 function CopyPasteHandler($config)
23 {
24 $this->config = $config;
25 $this->current= NULL;
26 $this->queue = 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)
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 $this->queue[] = $tmp;
63 }
64 }
67 /* This removes all objects from queue.
68 * Remove hdd dumps of current entries too.
69 * Remove entries older than 24 hours.
70 */
71 function cleanup_queue()
72 {
73 $this->current = FALSE;
75 /* Remove all entries from queue */
76 foreach($this->queue as $key => $entry){
77 @rmdir($entry['file_name']);
78 unset($this->queue[$key]);
79 }
81 /* Remove entries from hdd that are older than24 hours */
82 $fp = opendir(LDAP_DUMP_PATH);
83 while($file = readdir($fp)){
84 if(is_file(LDAP_DUMP_PATH."/".$file) && !preg_match("/^\./",$file)){
85 $file_time = fileatime(LDAP_DUMP_PATH."/".$file);
86 if($file_time < (time() - (24* 60 *60))){
87 @unlink(LDAP_DUMP_PATH."/".$file);
88 }
89 }
90 }
91 }
94 /* To increase performance we save the ldap dump on hdd
95 * This function automatically creates the dumps and returns
96 * the name of the dumpfile we created
97 */
98 function save_dn_attributes_to_hdd($dn)
99 {
100 $filename = "Should not be returned";
101 $ldap = $this->config->get_ldap_link();
102 $ldap->cd($this->config->current['BASE']);
103 $res = $ldap->cat($dn);
105 /* Check if given dn is valid and ldap search was succesfull */
106 if(!$res){
107 print_red(sprintf(_("Specified object '%s' is not a valid ldap object, please check copy & paste methods.")));
108 new log("copy","all/all",$dn,array(),"Could not create dump of ldap object, given object is not present in the ldap database.");
109 return(FALSE);
110 }
112 /* Create data to save given ldap dump on the hdd */
113 $filename = "gosa_copy-paste_dump_".preg_replace("/[^0-9]/","",microtime());
114 $path = LDAP_DUMP_PATH;
116 /* Create patch if it doesn't exists */
117 if(!is_dir($path)){
118 @mkdir($path);
119 }
121 /* check if we are able to create a new file the given directory */
122 if(!is_writeable($path)){
123 print_red(sprintf(_("We are not allowed to save ldap dump to '%s', please check permissions."),$path));
124 new log("copy","all/all",$dn,array(),
125 sprintf("We are not allowed to save ldap dump to '%s', please check permissions.",$path));
126 return(FALSE);
127 }
129 /* Create file handle */
130 $fp = @fopen($path."/".$filename,"w+");
131 if(!$fp){
132 print_red(sprintf(_("We are not allowed to save ldap dump to '%s/%s', please check permissions."),$path,$filename));
133 new log("copy","all/all",$dn,array(),
134 sprintf("We are not allowed to save ldap dump to '%s/%s', please check permissions.",$path,$filename));
135 return(FALSE);
136 }
138 $data = serialize($ldap->fetch());
139 fwrite($fp,$data,strlen($data));
140 fclose($fp);
142 /* Only the webserver should be able to read those files */
143 @chmod($path."/".$filename,0600);
144 return($path."/".$filename);
145 }
148 /* Check if there are still entries the object queue */
149 function entries_queued()
150 {
151 return( count($this->queue) >=1);
152 }
155 /* Paste one entry from queue */
156 function paste_entries()
157 {
159 /* Save posted variables, handle dialog posts like 'cancel' */
160 $this->save_object();
162 /* If there is currently no object pasted
163 * create new object and prepare object to be pasted
164 */
165 if(!$this->current && $this->entries_queued()){
166 $key = key($this->queue);
167 $entry = $this->queue[$key];
168 $tab_c = $entry['tab_class'];
169 $tab_o = $entry['tab_object'];
170 $entry['object'] = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],"new");
171 $entry['source_data'] = $this->load_attributes_from_hdd($entry['file_name']);
173 /* Prepare each plugin of this tab object to be posted */
174 foreach($entry['object']->by_object as $name => $obj){
176 /* Prepare every single class, to be copied */
177 $entry['object']->by_object[$name]->PrepareForCopyPaste($entry['source_data']);
179 /* handle some special vars */
180 foreach(array("is_account") as $attr){
181 if(isset($entry['source_data'][$attr])){
182 $entry['object']->by_object[$name]->$attr = $entry['source_data'][$attr];
183 }
184 }
185 }
187 /* Assign created object as current */
188 $this->current = $entry;
189 unset($this->queue[$key]);
190 }
192 return($this->execute());
193 }
196 /* Load dumped ldap entry specified by $filename and
197 * return data an unserailized data array
198 */
199 function load_attributes_from_hdd($filename)
200 {
201 $fp = @fopen($filename,"r");
202 if(is_file($filename) && is_readable($filename) && $fp){
203 $data = "";
204 while($str = fgets($fp,512)){
205 $data .= $str;
206 }
207 return(unserialize($data));
208 }else{
209 print_red(sprintf(_("Could not load dumped file '%s', from hard disk drive."),$filename));
210 new log("copy","all/all",$dn,array(),
211 sprintf(sprintf("Could not load dumped file '%s', from hard disk drive.",$filename)));
212 return(FALSE);
213 }
214 }
217 /* Displays a dialog which allows the user to fix all dependencies of this object.
218 Create unique names, ids, or what ever */
219 function execute()
220 {
221 $type = $this->current['method'];
222 if($type == "copy"){
223 if(isset($_POST['PerformCopyPaste'])){
224 $msgs = $this->check();
225 if(count ($msgs) ){
226 foreach( $msgs as $msg){
227 print_red($msg);
228 }
229 }else{
230 $this->current['object']->save();
231 $this->lastdn = $this->current['object']->dn;
232 $this->current =FALSE;
233 }
234 }
235 if($this->current){
236 $smarty = get_smarty();
237 $smarty->assign("type","copy");
238 $smarty->assign("Complete",false);
239 $smarty->assign("AttributesToFix",$this->generateAttributesToFix());
240 $smarty->assign("SubDialog",$this->current['object']->SubDialog);
241 $smarty->assign("objectDN" ,$this->current['source_data']['dn']);
242 $smarty->assign("message", sprintf(_("You are going to paste the copied entry '%s'."), $this->current['source_data']['dn']));
243 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
244 }
245 }
246 }
249 function last_entry()
250 {
251 return($this->lastdn);
252 }
255 /* Save new values posted by copy & paste dialog */
256 function save_object()
257 {
258 if(isset($_POST['abort_current_cut-copy_operation'])){
259 $this->current = FALSE;
260 }
262 if(isset($_POST['abort_all_cut-copy_operations'])){
263 $this->cleanup_queue();
264 $this->current = FALSE;
265 }
267 /* Assign posted var to all tabs
268 */
269 if($this->current){
270 $this->current['object']->saveCopyDialog();
271 }
272 }
275 /* Create dialog which asks unique attributes/values ...
276 * call tabs -> getCopyDialog()
277 * which calls tab -> getCopyDialog() */
278 function generateAttributesToFix()
279 {
280 if($this->current){
281 return($this->current['object']->getCopyDialog());
282 }
283 }
286 /* Set a single attribute to specified value
287 * example : ("base", $newBase ); */
288 function SetVar($name,$value)
289 {
290 if($this->current){
291 foreach($this->current['object']->by_object as $key => $obj){
292 if(isset($this->current['object']->by_object[$key]->$name)){
293 $this->current['object']->by_object[$key]->$name = $value;
294 }
295 }
296 }
297 }
300 /* Returns errors from including tabs. */
301 function check()
302 {
303 $ret = array();
304 foreach($this->current['object']->by_object as $obj){
305 if($obj->is_account){
306 $ret = array_merge($ret , $obj->check());
307 }
308 }
309 return($ret);
310 }
313 /* returns the paste icon for headpages */
314 function generatePasteIcon()
315 {
316 $Copy_Paste= " <img class='center' src='images/list_seperator.png' align='middle' alt='' height='16' width='1'> ";
317 if($this->entries_queued()){
318 $img= "images/copypaste.png";
319 $Copy_Paste.= "<input type='image' name='editPaste' class='center'
320 src='".$img."' alt='"._("Paste")."'> ";
321 }else{
322 $Copy_Paste.= "<img class='center' src='images/cant_editpaste.png' alt=\""._("Can't paste")."\"> ";
323 }
325 return ($Copy_Paste);
326 }
345 /******** Functions below are unused and will be rewritten **********/
351 /* Add Object which should be cutted */
352 function Cut_old($obj)
353 {
354 $this->cutCurrent = true;
355 $this->current = $obj;
356 $this->objectdn = $obj->dn;
357 if($this->isCurrentObjectPastAble()){
358 return(true);
359 }else{
360 $this->cutCurrent = $this->copyCurrent = false;
361 $this->obj = NULL;
362 }
363 return(false);
364 }
367 /* Displays a dialog which allows the user to fix all dependencies of this object.
368 Create unique names, ids, or what ever */
369 function execute_old()
370 {
371 print_a($this->current);
373 return;
374 /* Cut & paste
375 */
376 if($this->cutCurrent){
378 if(isset($_POST['PerformCopyPaste'])){
379 $msgs = $this->check();
380 if(count ($msgs) ){
381 foreach( $msgs as $msg){
382 print_red($msg);
383 }
384 }else{
385 $this->current->save();
386 $this->dialogOpen =false;
387 $this->Clear();
388 }
389 }
390 if($this->current){
391 $smarty = get_smarty();
392 $smarty->assign("type","cut");
393 $smarty->assign("Complete",false);
394 $smarty->assign("AttributesToFix"," ");
395 $smarty->assign("SubDialog",$this->current->SubDialog);
396 $smarty->assign("objectDN" ,$this->objectdn);
397 $smarty->assign("message", sprintf(_("You are going to paste the cutted entry '%s'."), $this->objectdn));
398 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
399 }
401 /* Copy & paste
402 */
403 }else{
404 if(isset($_POST['PerformCopyPaste'])){
405 $msgs = $this->check();
406 if(count ($msgs) ){
407 foreach( $msgs as $msg){
408 print_red($msg);
409 }
410 }else{
411 $this->current->save();
412 $this->lastdn = $this->current->dn;
413 $this->dialogOpen =false;
414 $this->Clear();
415 }
416 }
417 if($this->current){
418 $smarty = get_smarty();
419 $smarty->assign("type","copy");
420 $smarty->assign("Complete",false);
421 $smarty->assign("AttributesToFix",$this->generateAttributesToFix());
422 $smarty->assign("SubDialog",$this->current->SubDialog);
423 $smarty->assign("objectDN" ,$this->objectdn);
424 $smarty->assign("message", sprintf(_("You are going to paste the copied entry '%s'."), $this->objectdn));
425 return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE)));
426 }
427 }
428 }
430 /* Save new values posted by copy & paste dialog */
431 function save_object_2()
432 {
433 /* Assign posted var to all tabs
434 */
435 if($this->current){
436 $this->current->saveCopyDialog();
437 }
438 }
441 }
442 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
443 ?>