Code

Added new Copy & Paste handling.
authorhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Wed, 6 Jun 2007 13:50:20 +0000 (13:50 +0000)
committerhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Wed, 6 Jun 2007 13:50:20 +0000 (13:50 +0000)
NOT WORKING AT ALL, use on your own RISK :-) Remember this is the devel tree.

git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@6559 594d385d-05f5-0310-b6e9-bd551577e9d8

include/class_CopyPasteHandler.inc
include/class_plugin.inc
plugins/admin/users/class_divListUsers.inc
plugins/admin/users/class_userManagement.inc

index afb2a117ec147840cf00c55b04a2e4a639b476e8..3fda66e3397645bf20c37e63868c42398ad39215 100644 (file)
@@ -1,5 +1,7 @@
 <?php
 
+define("LDAP_DUMP_PATH","/tmp/gosa");
+
 class CopyPasteHandler {
 
   var $config;
@@ -11,80 +13,324 @@ class CopyPasteHandler {
   var $objectdn    = false;
 
   var $lastdn      = "";
-
   var $was_successfull = false;
 
+  /* this array contains all dns of the currently copyied objects */
+  var $queue       = array(); 
+
   /* Create CP handler  */
-  function CopyPasteHandler($config){
+  function CopyPasteHandler($config)
+  {
     $this->config = $config;   
     $this->current= NULL;
+    $this->queue  = array();
   }
 
 
-  /* Returns wether the current object can be pasted */        
-  function isCurrentObjectPastAble(){
+  /* 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)
+  {
+    echo "validate given data here !!!!!!!";
+
+    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;
+      $this->queue[]    = $tmp; 
+    }
+  }
 
-    /* Check if we got a valid object */
-    if($this->current == NULL){
-      return(false);
+  
+  /* This removes all objects from queue.
+   * Remove hdd dumps of current entries too.
+   * Remove entries older than 24 hours.
+   */
+  function cleanup_queue()
+  {
+    $this->current = FALSE;
+
+    /* Remove all entries from queue */  
+    foreach($this->queue as $key => $entry){
+      @rmdir($entry['file_name']);  
+      unset($this->queue[$key]);
+    }
+
+    /* 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);
+        }
+      }
     }
-    return(true);
-  }    
+  }
 
 
-  /* Clears all copy & paste informations */
-  function Clear()
+  /* 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)
   {
-    $this->copyCurrent         = false;
-    $this->cutCurrent          = false;
-    $this->dialogOpen   = false;
-    $this->current             = NULL;
+    $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);
+    }
+
+    /* 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);
   }
 
 
-  /* return current obejct dn */
-  function GetCurrentDn()
+  /* Check if there are still entries the object queue */
+  function entries_queued()
   {
-    return($this->objectdn);
+    return( count($this->queue) >=1);
   }
 
 
-  /* Add Object which should be copied  */
-  function Copy($obj,$emptyObj)
+  /* Paste one entry from queue */
+  function paste_entries()
   {
-    $this->copyCurrent = true;
-    $this->objectdn    = $obj->dn;
-    $this->current = $emptyObj;
 
-    if(!isset($obj->by_object)){
-      trigger_error("No valid tab object specified for copy & paste.");
-      return;
+    /* 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'];
+      $entry['object']      = new $tab_c($this->config,$this->config->data['TABS'][$tab_o],"new");
+      $entry['source_data'] = $this->load_attributes_from_hdd($entry['file_name']);
+
+      /* 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]);
     }
     
-    foreach($obj->by_object as $name => $obj){
-    
-      /* 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;
+    return($this->execute());
+  }
+
+  
+  /* 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);
+    }
+  }
+
+
+  /* Displays a dialog which allows the user to fix all dependencies of this object.
+     Create unique names, ids, or what ever */
+  function execute()
+  {
+    $type = $this->current['method'];
+    if($type == "copy"){
+      if(isset($_POST['PerformCopyPaste'])){
+        $msgs = $this->check();
+        if(count ($msgs) ){
+          foreach( $msgs as $msg){
+            print_red($msg);
+          }
+        }else{
+          $this->current['object']->save();
+          $this->lastdn = $this->current['object']->dn;
+          $this->current =FALSE;
         }
       }
+      if($this->current){
+        $smarty = get_smarty();
+        $smarty->assign("type","copy");
+        $smarty->assign("Complete",false);
+        $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)));
+      }
     }
-    if($this->isCurrentObjectPastAble()){
-      return(true);
+  }
+
+
+  /* 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['object']->getCopyDialog());  
+    }
+  }
+
+
+  /* Set a single attribute to specified value
+   *  example :   ("base", $newBase );    */
+  function SetVar($name,$value)
+  {
+    echo $name.$value."<br>";
+    foreach($this->    current->by_object as $key => $obj){
+      if(isset($this->current->by_object[$key]->$name)){
+        $this->current->by_object[$key]->$name = $value;
+      }
+    }
+  }
+
+
+  /* Returns errors from including tabs. */
+  function check()
+  {
+    $ret = array();
+    foreach($this->current['object']->by_object as $obj){
+      if($obj->is_account){
+        $ret = array_merge($ret , $obj->check());
+      }
+    }
+    return($ret);
+  }
+
+  
+  /* returns the paste icon for headpages */ 
+  function generatePasteIcon()
+  {
+    $Copy_Paste= "&nbsp;<img class='center' src='images/list_seperator.png' align='middle' alt='' height='16' width='1'>&nbsp;";
+    if($this->entries_queued()){
+      $img= "images/copypaste.png";
+      $Copy_Paste.= "<input type='image' name='editPaste' class='center'
+        src='".$img."' alt='"._("Paste")."'>&nbsp;";
     }else{
-      $this->cutCurrent = $this->copyCurrent = false;
-      $this->obj = NULL;
+      $Copy_Paste.= "<img class='center' src='images/cant_editpaste.png' alt=\""._("Can't paste")."\">&nbsp;";
     }
-    return(false);
+
+    return ($Copy_Paste);
   }
 
 
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  /******** Functions below are unused and will be rewritten **********/
+
+
+
+
+
   /* Add Object which should be cutted  */
-  function Cut($obj){
+  function Cut_old($obj)
+  {
     $this->cutCurrent = true;
     $this->current       = $obj;
     $this->objectdn    = $obj->dn;
@@ -98,35 +344,13 @@ class CopyPasteHandler {
   }
 
 
-  /* Returns true if current object 
-   *  is cutted. And awaits to be pasted anywhere  */
-  function isCurrentCutted(){
-    return($this->cutCurrent);
-  }
-
-
-  /* Returns true if current object  
-   *  was copied, and awaits to be pasted again  */
-  function isCurrentCopied(){
-    return($this->copyCurrent);
-  }
-
-
-  /* Returns true if the copy$paste dialog is still open  */
-  function stillOpen(){        
-    if(isset($_POST['AbortCopyPaste'])){
-      $this->dialogOpen = false;
-    }
-    return($this->dialogOpen);
-  }
-
-
   /* Displays a dialog which allows the user to fix all dependencies of this object.
      Create unique names, ids, or what ever */
-  function execute()
+  function execute_old()
   {
-    $this->dialogOpen = true;
+    print_a($this->current);
 
+    return;
     /* Cut & paste
      */
     if($this->cutCurrent){
@@ -183,31 +407,8 @@ class CopyPasteHandler {
     }
   }
 
-  /* Create dialog which asks unique attributes/values ... 
-   *  call tabs -> getCopyDialog() 
-   *    which calls tab -> getCopyDialog()  */
-  function generateAttributesToFix()
-  {
-    if($this->current){
-      return($this->current->getCopyDialog());  
-    }
-  }
-
-
-  /* Set a single attribute to specified value
-   *  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;
-      }
-    }
-  }
-
-
   /* Save new values posted by copy & paste dialog */
-  function save_object()
+  function save_object_2()
   {
     /* Assign posted var to all tabs
      */
@@ -217,38 +418,6 @@ class CopyPasteHandler {
   }
 
 
-  /* Returns errors from including tabs. */
-  function check()
-  {
-    $ret = array();
-    foreach($this->    current->by_object as $obj){
-      if($obj->is_account){
-        $ret = array_merge($ret , $obj->check());
-      }
-    }
-    return($ret);
-  }
-
-  
-  /* returns the paste icon for headpages */ 
-  function generatePasteIcon()
-  {
-    $Copy_Paste= "&nbsp;<img class='center' src='images/list_seperator.png' align='middle' alt='' height='16' width='1'>&nbsp;";
-    if($this->isCurrentObjectPastAble()){
-      if($this->isCurrentCutted()){
-        $img= "images/cutpaste.png";
-      }else{
-        $img= "images/copypaste.png";
-      }
-      $Copy_Paste.= "<input type='image' name='editPaste' class='center'
-        src='".$img."' alt='"._("Paste")."' title='".$this->GetCurrentDn()."'>&nbsp;";
-    }else{
-      $Copy_Paste.= "<img class='center' src='images/cant_editpaste.png' alt=\""._("Can't paste")."\">&nbsp;";
-    }
-
-    return ($Copy_Paste);
-  }
-
 }
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
 ?>
index e71962fafa91d831532e42be925b685ce56422cc..b467f354a29ecaf89207cd6a0e152b3ac15b3f61 100644 (file)
@@ -907,15 +907,29 @@ class plugin
   }
 
 
-  function PrepareForCopyPaste($source){
+  function PrepareForCopyPaste($source)
+  {
     $todo = $this->attributes;
     if(isset($this->CopyPasteVars)){
       $todo = array_merge($todo,$this->CopyPasteVars);
     }
     $todo[] = "is_account";
     foreach($todo as $var){
-      if (isset($source->$var)){
-        $this->$var= $source->$var;
+      if (isset($source[$var])){
+        if(isset($source[$var]['count'])){
+          if($source[$var]['count'] > 1){
+            $this->$var = array();
+            $tmp = array();
+            for($i = 0 ; $i < $source[$var]['count']; $i++){
+              $tmp = $source[$var][$i];
+            }
+            $this->$var = $tmp;
+          }else{
+            $this->$var = $source[$var][0];
+          }
+        }else{
+          $this->$var= $source[$var];
+        }
       }
     }
   }
index c73fe97aa866e3f246a236a392a156cc1227761b..f22979edf3b35b560a59bf1473eff2804813b394 100644 (file)
@@ -167,7 +167,11 @@ class divListUsers extends MultiSelectWindow
     /* Multiple options */ 
     $listhead .= "&nbsp;<input class='center' type='image' align='middle' src='images/edittrash.png'
         title='"._("Remove selected user")."' alt='"._("Remove user")."' name='remove_multiple_users'>&nbsp;";
-    
+    $listhead .= "&nbsp;<input class='center' type='image' align='middle' src='images/editcopy.png'
+        title='"._("Copy selected user")."' alt='"._("Copy users")."' name='multiple_copy_users'>&nbsp;";
+    $listhead .= "&nbsp;<input class='center' type='image' align='middle' src='images/editcut.png'
+        title='"._("cut selected user")."' alt='"._("Cut users")."' name='multiple_cut_users'>&nbsp;";
+
     $listhead .="</div>";;
     $this->SetListHeader($listhead);
   }
index 63ba95115fe7216dae8183f3e698030db46cf603..cdd8ad2c5313e49c36a820b0472643717861deea 100644 (file)
@@ -37,6 +37,8 @@ class userManagement extends plugin
   var $CPPasswordChange     = ""; // Contains the entry id which should get a new password
   var $DivListUsers;
 
+  var $start_pasting_copied_objects = FALSE;
+
   function userManagement($config, $ui)
   {
     /* Save configuration for internal use */
@@ -82,8 +84,11 @@ class userManagement extends plugin
                     "del_multiple" => "^remove_multiple_users",
                     "create_user_from_tpl"          => "userfrom_tpl",
                     "change_pw" => "user_chgpw", 
-                    "editPaste" => "editPaste",   "copy"      => "copy",
-                    "cut"       => "cut") as $act => $name){
+                    "editPaste" => "editPaste",  
+                    "copy_multiple" => "multiple_copy_users",
+                    "cut_multiple" => "multiple_cut_users",
+                    "copy"      => "^copy",
+                    "cut"       => "^cut") as $act => $name){
 
         if (preg_match("/".$name.".*/", $key)){
           $s_action= $act;
@@ -109,6 +114,13 @@ class userManagement extends plugin
       $s_tab = "user";
     }
 
+
+    $ret = $this->copyPasteHandling_from_queue($s_action);
+    if($ret){
+      return($ret);
+    }
+
+
     /* Display the copy & paste dialog, if it is currently open */
     $ret = $this->copyPasteHandling($s_action,$s_entry);
     if($ret){
@@ -867,85 +879,49 @@ class userManagement extends plugin
     }
   }
 
-  /* Perform copy & paste requests
-      If copy&paste is in progress this returns a dialog to fix required attributes 
-   */ 
-  function copyPasteHandling($s_action,$s_entry)
-  {
-    /* Only perform copy/paste if it is enabled */
-    if($this->CopyPasteHandler){
 
-      /* Prepare current object to be pasted */
-      if( $s_action == "editPaste" || $this->CopyPasteHandler->stillOpen()){
+  function copyPasteHandling_from_queue($s_action)
+  {
+    if($s_action == "copy_multiple" || $s_action == "cut_multiple"){
 
-        $this->CopyPasteHandler->save_object();
-        $this->CopyPasteHandler->SetVar("base", $this->DivListUsers->selectedBase);
+      /* Cleanup object queue */
+      $this->CopyPasteHandler->cleanup_queue();
 
-        /* Execute copy & paste dialog and display returned data, normaly a dialog which allows 
-            us to solve all attribute mismatches for this object.
-            If nothing is returned, copy & paste was succesfully or aborted */
-        if(($ret= $this->CopyPasteHandler->execute())){
-          return ($ret);
-        }
-
-        /* Use the last dn to search for it's ID in the newly generated list. */
-        $dn= $this->CopyPasteHandler->lastdn;
+      /* Add new entries to CP queue */
+      foreach($_POST as $name => $value){
+        if(preg_match("/^item_selected_[0-9]*$/",$name)){
+          $id = preg_replace("/^item_selected_/","",$name);
+          $dn = $this->list[$id]['dn'];
 
-        /* Get new user list */
-        $this->reload();
-        foreach($this->list as $id => $entry){
-          if($entry['dn'] == $dn){
-            $s_entry= $id;
-            break;
+          if($s_action == "copy_multiple"){
+            $this->CopyPasteHandler->add_to_queue($dn,"copy","usertabs","USERTABS");
+          }
+          if($s_action == "cut_multiple"){
+            $this->CopyPasteHandler->add_to_queue($dn,"cut","usertabs","USERTABS");
           }
-        }
-       
-        /* Set CPPasswordChange to s_entry which indicates that this entry requires a new password. */
-        if(isset($_POST['passwordTodo']) && ($_POST['passwordTodo'] == "new")){
-          $this->CPPasswordChange = $s_entry;
-        }
-      }
-
-      /* Copy selected object 
-         Create a new empty object and the current selected object. 
-         Send both to copy&paste class*/
-      if($s_action == "copy"){
-        $this->CopyPasteHandler->Clear();
-        $dn= $this->list[trim($s_entry)]['dn'];
-
-        /* Check acl */
-        $ui = get_userinfo();
-        $acl_all  = $ui->has_complete_category_acls($this->DivListUsers->selectedBase,"users") ;
-        if(preg_match("/(c.*w|w.*c)/",$acl_all)){
-          $obj    = new usertabs($this->config, $this->config->data['TABS']['USERTABS'], $dn);
-          $obj->set_acl_base($dn);
-          $objNew = new usertabs($this->config, $this->config->data['TABS']['USERTABS'], "new");
-          $objNew->set_acl_base($dn);
-
-          $this->CopyPasteHandler->Copy($obj,$objNew);
-        }else{
-          print_red("You are not allowed to copy this entry.");
         }
       }
+    }
+    
+    if($s_action == "editPaste"){
+      $this->start_pasting_copied_objects = TRUE;
+    }
 
-      /* Cut selected object. 
-         Open user object and send it to the copy & paste handler */
-      if($s_action == "cut"){
-        $this->CopyPasteHandler->Clear();
-        $dn= $this->list[trim($s_entry)]['dn'];
-
-        /* Check acl */
-        $acl_all  = $ui->has_complete_category_acls($this->DivListUsers->selectedBase,"users") ;
-        if(preg_match("/(c.*w|w.*c)/",$acl_all)){
-          $obj= new usertabs($this->config, $this->config->data['TABS']['USERTABS'], $dn);
-          $obj->set_acl_base($dn);
-          $this->CopyPasteHandler->Cut($obj);
-        }else{
-          print_red("You are not allowed to cut this entry.");
-        }
-      }
+    if($this->start_pasting_copied_objects && $this->CopyPasteHandler->entries_queued()){
+      return($this->CopyPasteHandler->paste_entries());
     }
+    
+    $this->start_pasting_copied_objects = FALSE;
+  }
+
+  /* Perform copy & paste requests
+      If copy&paste is in progress this returns a dialog to fix required attributes 
+   */ 
+  function copyPasteHandling($s_action,$s_entry)
+  { 
+    echo "replaced";
+    return;
   }
 
   function save_object()