X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=include%2Fclass_CopyPasteHandler.inc;h=1d6a1f04ac07b87f3308f9074ec63a0eea69e489;hb=1374a0a230c81a1974326e319b7576f4f1855afe;hp=78cfb746bd115f9cad1961e131ac60ffe6bc6fdd;hpb=2277cb2e30195dddd0dc2e918ff59dd3c6730a2a;p=gosa.git diff --git a/include/class_CopyPasteHandler.inc b/include/class_CopyPasteHandler.inc index 78cfb746b..1d6a1f04a 100644 --- a/include/class_CopyPasteHandler.inc +++ b/include/class_CopyPasteHandler.inc @@ -1,117 +1,239 @@ config = $config; + function CopyPasteHandler(&$config) + { + $this->config = &$config; $this->current= NULL; + $this->queue = array(); + $this->setvar_array = array(); } - /* Returns wether the current object can be pasted */ - function isCurrentObjectPastAble(){ - - /* Check if we got a valid object */ - if($this->current == NULL){ - return(false); + /* Entry entry to Copy & Paste queue. + * A Queue entry is represented as follows. + * array['file_name'] - Position on hdd + * array['method'] - copy/cut + * array['dn'] - the dn of the object added to the queue + * array['tab_class'] - Tab object that should be used to initialize the new object + * array['tab_object'] - Tab object name used to initialize correct object Type like USERTABS + */ + function add_to_queue($dn,$action,$tab_class,$tab_object,$tab_acl_category) + { + if(!class_exists($tab_class)){ + trigger_error(sprintf("Specified class object '%s' does not exists.",$tab_class)); + return(FALSE); } - return(true); - } + if(!isset($this->config->data['TABS'][$tab_object])){ + trigger_error(sprintf("Specified tab object '%s' does not exists.",$tab_object)); + return(FALSE); + } - /* Clears all copy & paste informations */ - function Clear() - { - $this->copyCurrent = false; - $this->cutCurrent = false; - $this->dialogOpen = false; - $this->current = NULL; + if(!in_array($action,array("cut","copy"))){ + trigger_error(sprintf("Specified action '%s' does not exists for copy & paste.",$action)); + return(FALSE); + } + + if($file_name = $this->save_dn_attributes_to_hdd($dn)){ + $tmp = array(); + $tmp['file_name'] = $file_name; + $tmp['method'] = $action; + $tmp['dn'] = $dn; + $tmp['tab_class'] = $tab_class; + $tmp['tab_object']= $tab_object; + $tmp['tab_acl_category']= $tab_acl_category; + $this->queue[] = $tmp; + } } - /* return current obejct dn */ - function GetCurrentDn() + /* This removes all objects from queue. + * Remove hdd dumps of current entries too. + * Remove entries older than 24 hours. + */ + function cleanup_queue() { - return($this->objectdn); - } + $this->current = FALSE; + $this->setvar_array = array(); + /* Remove all entries from queue */ + foreach($this->queue as $key => $entry){ + @rmdir($entry['file_name']); + unset($this->queue[$key]); + } - /* Add Object which should be copied */ - function Copy($obj,$emptyObj) - { - $this->copyCurrent = true; - $this->objectdn = $obj->dn; - $this->current = $emptyObj; - foreach($obj->by_object as $name => $obj){ + /* Create patch if it doesn't exists */ + if(!is_dir(LDAP_DUMP_PATH)){ + @mkdir(LDAP_DUMP_PATH); + } - /* Prepare every single class, to be copied */ - $this->current->by_object[$name]->PrepareForCopyPaste($obj); - - /* handle some special vars */ - foreach(array("is_account") as $attr){ - if(isset($obj->$attr)){ - $this->current->by_object[$name]->$attr = $obj->$attr; + /* check if we are able to create a new file the given directory */ + if(!is_writeable(LDAP_DUMP_PATH)){ + 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)); + new log("copy","all/all","copy & paste, event queue.",array(), + sprintf("Could not cleanup copy & paste queue. We are not allowed to save ldap dump to '%s', please check permissions.",LDAP_DUMP_PATH)); + return(FALSE); + } + + /* Remove entries from hdd that are older than24 hours */ + $fp = opendir(LDAP_DUMP_PATH); + while($file = readdir($fp)){ + if(is_file(LDAP_DUMP_PATH."/".$file) && !preg_match("/^\./",$file)){ + $file_time = fileatime(LDAP_DUMP_PATH."/".$file); + if($file_time < (time() - (24* 60 *60))){ + @unlink(LDAP_DUMP_PATH."/".$file); } } } - if($this->isCurrentObjectPastAble()){ - return(true); - }else{ - $this->cutCurrent = $this->copyCurrent = false; - $this->obj = NULL; - } - return(false); } - /* Add Object which should be cutted */ - function Cut($obj){ - $this->cutCurrent = true; - $this->current = $obj; - $this->objectdn = $obj->dn; - if($this->isCurrentObjectPastAble()){ - return(true); - }else{ - $this->cutCurrent = $this->copyCurrent = false; - $this->obj = NULL; + /* To increase performance we save the ldap dump on hdd + * This function automatically creates the dumps and returns + * the name of the dumpfile we created + */ + function save_dn_attributes_to_hdd($dn) + { + $filename = "Should not be returned"; + $ldap = $this->config->get_ldap_link(); + $ldap->cd($this->config->current['BASE']); + $res = $ldap->cat($dn); + + /* Check if given dn is valid and ldap search was succesfull */ + if(!$res){ + print_red(sprintf(_("Specified object '%s' is not a valid ldap object, please check copy & paste methods."))); + new log("copy","all/all",$dn,array(),"Could not create dump of ldap object, given object is not present in the ldap database."); + return(FALSE); } - return(false); + + /* Create data to save given ldap dump on the hdd */ + $filename = "gosa_copy-paste_dump_".preg_replace("/[^0-9]/","",microtime()); + $path = LDAP_DUMP_PATH; + + /* Create patch if it doesn't exists */ + if(!is_dir($path)){ + @mkdir($path); + } + + /* check if we are able to create a new file the given directory */ + if(!is_writeable($path)){ + print_red(sprintf(_("We are not allowed to save ldap dump to '%s', please check permissions."),$path)); + new log("copy","all/all",$dn,array(), + sprintf("We are not allowed to save ldap dump to '%s', please check permissions.",$path)); + return(FALSE); + } + + /* Create file handle */ + $fp = @fopen($path."/".$filename,"w+"); + if(!$fp){ + print_red(sprintf(_("We are not allowed to save ldap dump to '%s/%s', please check permissions."),$path,$filename)); + new log("copy","all/all",$dn,array(), + sprintf("We are not allowed to save ldap dump to '%s/%s', please check permissions.",$path,$filename)); + return(FALSE); + } + + $data = serialize($ldap->fetch()); + fwrite($fp,$data,strlen($data)); + fclose($fp); + + /* Only the webserver should be able to read those files */ + @chmod($path."/".$filename,0600); + return($path."/".$filename); } - /* Returns true if current object - * is cutted. And awaits to be pasted anywhere */ - function isCurrentCutted(){ - return($this->cutCurrent); + /* Check if there are still entries the object queue */ + function entries_queued() + { + return( count($this->queue) >=1 || $this->current != FALSE); } - /* Returns true if current object - * was copied, and awaits to be pasted again */ - function isCurrentCopied(){ - return($this->copyCurrent); + /* Paste one entry from queue */ + function load_entry_from_queue() + { + + /* Save posted variables, handle dialog posts like 'cancel' */ + $this->save_object(); + + /* If there is currently no object pasted + * create new object and prepare object to be pasted + */ + if(!$this->current && $this->entries_queued()){ + $key = key($this->queue); + $entry = $this->queue[$key]; + $tab_c = $entry['tab_class']; + $tab_o = $entry['tab_object']; + $tab_a = $entry['tab_acl_category']; + + if($entry['method'] == "copy"){ + $entry['object'] = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],"new",$tab_a); + }else{ + $entry['object'] = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],$entry['dn'],$tab_a); + } + + $entry['source_data'] = $this->load_attributes_from_hdd($entry['file_name']); + + if($entry['method'] == "copy"){ + + /* Prepare each plugin of this tab object to be posted */ + foreach($entry['object']->by_object as $name => $obj){ + + /* Prepare every single class, to be copied */ + $entry['object']->by_object[$name]->PrepareForCopyPaste($entry['source_data']); + + /* handle some special vars */ + foreach(array("is_account") as $attr){ + if(isset($entry['source_data'][$attr])){ + $entry['object']->by_object[$name]->$attr = $entry['source_data'][$attr]; + } + } + } + } + + /* Assign created object as current */ + $this->current = $entry; + unset($this->queue[$key]); + } } - /* Returns true if the copy$paste dialog is still open */ - function stillOpen(){ - if(isset($_POST['AbortCopyPaste'])){ - $this->dialogOpen = false; + /* Load dumped ldap entry specified by $filename and + * return data an unserailized data array + */ + function load_attributes_from_hdd($filename) + { + $fp = @fopen($filename,"r"); + if(is_file($filename) && is_readable($filename) && $fp){ + $data = ""; + while($str = fgets($fp,512)){ + $data .= $str; + } + return(unserialize($data)); + }else{ + print_red(sprintf(_("Could not load dumped file '%s', from hard disk drive."),$filename)); + new log("copy","all/all",$dn,array(), + sprintf(sprintf("Could not load dumped file '%s', from hard disk drive.",$filename))); + return(FALSE); } - return($this->dialogOpen); } @@ -119,50 +241,122 @@ class CopyPasteHandler { Create unique names, ids, or what ever */ function execute() { - $this->dialogOpen = true; + $ui = get_userinfo(); + $type = $this->current['method']; + if($type == "cut"){ + if(isset($_POST['PerformCopyPaste'])){ + while($this->entries_queued()){ + $this->load_entry_from_queue(); + $this->_update_vars(); - /* Cut & paste - */ - if($this->cutCurrent){ - $this->current->save(); - $this->dialogOpen =false; - $this->Clear(); + $msgs = $this->check(); + $acl = $ui->get_category_permissions($this->current['dn'], $this->current['tab_acl_category']); + + /* Check permissions */ + if(!preg_match("/((c|w)|(w|c))/",$acl)){ + print_red(sprintf(_("You are not allowed to cut and paste the following object '%s'."),$this->current['dn'])); + }elseif(count ($msgs) ){ + foreach( $msgs as $msg){ + print_red($msg); + } + }else{ + + /* Load next queue entry */ + $this->lastdn = $this->current['object']->dn; + $this->current['object']->save(); + } - /* Copy & paste - */ - }else{ + $this->current =FALSE; + } + } + if($this->current){ + + $dns = $this->current['dn']."\n"; + foreach($this->queue as $entry){ + $dns .= $entry['dn']."\n"; + } + + $smarty = get_smarty(); + $smarty->assign("type","cut"); + $smarty->assign("Complete",false); + $smarty->assign("AttributesToFix"," "); + $smarty->assign("SubDialog",$this->current['object']->SubDialog); + $smarty->assign("objectDN" ,$dns); + $smarty->assign("message", sprintf(_("You are going to paste the cutted entry '%s'."), "
".$dns."")); + return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE))); + } + } + if($type == "copy"){ if(isset($_POST['PerformCopyPaste'])){ - $msgs = $this->check(); - if(count ($msgs) ){ + $this->_update_vars(); + $msgs = $this->check(); + + $acl = $ui->get_category_permissions($this->current['dn'], $this->current['tab_acl_category']); + + /* Check permissions */ + if(!preg_match("/((c|w)|(w|c))/",$acl)){ + print_red(sprintf(_("You are not allowed to copy and paste the following object '%s'."),$this->current['dn'])); + }elseif(count ($msgs) ){ foreach( $msgs as $msg){ print_red($msg); } }else{ - $this->current->save(); - $this->lastdn = $this->current->dn; - $this->dialogOpen =false; - $this->Clear(); + $this->current['object']->save(); + $this->lastdn = $this->current['object']->dn; + $this->current =FALSE; + + /* Load next queue entry */ + $this->load_entry_from_queue(); } } if($this->current){ - $smarty = get_smarty(); + $smarty = get_smarty(); + $smarty->assign("type","copy"); $smarty->assign("Complete",false); - $smarty->assign("AttributesToFix",$this->generateAttributesToFix()); - $smarty->assign("SubDialog",$this->current->SubDialog); - $smarty->assign("objectDN" ,$this->objectdn); - $smarty->assign("message", sprintf(_("You are going to copy the entry '%s'."), $this->objectdn)); + $smarty->assign("AttributesToFix",$this->generateAttributesToFix()); + $smarty->assign("SubDialog",$this->current['object']->SubDialog); + $smarty->assign("objectDN" ,$this->current['source_data']['dn']); + $smarty->assign("message", sprintf(_("You are going to paste the copied entry '%s'."), $this->current['source_data']['dn'])); return($smarty->fetch(get_template_path("copyPasteDialog.tpl",FALSE))); } } } + + /* Return the dn of the last edited entry */ + function last_entry() + { + return($this->lastdn); + } + + + /* Save new values posted by copy & paste dialog */ + function save_object() + { + if(isset($_POST['abort_current_cut-copy_operation'])){ + $this->current = FALSE; + } + + if(isset($_POST['abort_all_cut-copy_operations'])){ + $this->cleanup_queue(); + $this->current = FALSE; + } + + /* Assign posted var to all tabs + */ + if($this->current){ + $this->current['object']->saveCopyDialog(); + } + } + + /* Create dialog which asks unique attributes/values ... * call tabs -> getCopyDialog() * which calls tab -> getCopyDialog() */ function generateAttributesToFix() { if($this->current){ - return($this->current->getCopyDialog()); + return($this->current['object']->getCopyDialog()); } } @@ -171,21 +365,32 @@ class CopyPasteHandler { * example : ("base", $newBase ); */ function SetVar($name,$value) { - foreach($this-> current->by_object as $key => $obj){ - if(isset($this->current->by_object[$key]->$name)){ - $this->current->by_object[$key]->$name = $value; - } - } + $this->setvar_array[$name]=$value; } - /* Save new values posted by copy & paste dialog */ - function save_object() + /* Update current object attributes, collected via SetVar */ + function _update_vars() { - /* Assign posted var to all tabs - */ if($this->current){ - $this->current->saveCopyDialog(); + + /* Update all attributes specified with SetVar */ + foreach($this->setvar_array as $name => $value){ + if(isset($this->current['object']->$name)){ + $this->current['object']->$name = $value; + } + } + + /* Walk through tabs */ + foreach($this->current['object']->by_object as $key => $obj){ + + /* Update all attributes specified with SetVar */ + foreach($this->setvar_array as $name => $value){ + if(isset($this->current['object']->by_object[$key]->$name)){ + $this->current['object']->by_object[$key]->$name = $value; + } + } + } } } @@ -194,7 +399,7 @@ class CopyPasteHandler { function check() { $ret = array(); - foreach($this-> current->by_object as $obj){ + foreach($this->current['object']->by_object as $obj){ if($obj->is_account){ $ret = array_merge($ret , $obj->check()); } @@ -202,26 +407,20 @@ class CopyPasteHandler { return($ret); } - + /* returns the paste icon for headpages */ function generatePasteIcon() { $Copy_Paste= "