1d6a1f04ac07b87f3308f9074ec63a0eea69e489
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 }
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']);
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"," ");
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']);
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= " <img class='center' src='images/list_seperator.png' align='middle' alt='' height='16' width='1'> ";
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")."'> ";
419 }else{
420 $Copy_Paste.= "<img class='center' src='images/cant_editpaste.png' alt=\""._("Can't paste")."\"> ";
421 }
422 return ($Copy_Paste);
423 }
424 }
425 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
426 ?>