Code

Replaced config->search with get_cfg_value
[gosa.git] / gosa-core / include / class_plugin.inc
index 0f108c4d22789e88a3ebfb43b9a37098443411bc..33f750a351abde4216839399a5784ca2d3519d83 100644 (file)
  */
 
 class plugin
  */
 
 class plugin
-{
+{ 
+  /*! \brief    The title shown in path menu while this plugin is visible.
+   */
+  var $pathTitle = "";
+
   /*!
     \brief Reference to parent object
 
   /*!
     \brief Reference to parent object
 
@@ -145,6 +149,18 @@ class plugin
     $this->config= &$config;   
     $this->dn= $dn;
 
     $this->config= &$config;   
     $this->dn= $dn;
 
+    // Ensure that we've a valid acl_category set.
+    if(empty($this->acl_category)){
+      $tmp = $this->plInfo();
+      if (isset($tmp['plCategory'])) {
+        $c = key($tmp['plCategory']);
+        if(is_numeric($c)){
+          $c = $tmp['plCategory'][0];
+        }
+        $this->acl_category = $c."/";
+      }
+    }
+
     /* Handle new accounts, don't read information from LDAP */
     if ($dn == "new"){
       return;
     /* Handle new accounts, don't read information from LDAP */
     if ($dn == "new"){
       return;
@@ -264,6 +280,8 @@ class plugin
     session::set('LOCK_VARS_USED_GET',array());
     session::set('LOCK_VARS_USED_POST',array());
     session::set('LOCK_VARS_USED_REQUEST',array());
     session::set('LOCK_VARS_USED_GET',array());
     session::set('LOCK_VARS_USED_POST',array());
     session::set('LOCK_VARS_USED_REQUEST',array());
+
+    pathNavigator::registerPlugin($this);
   }
 
   /*! \brief Removes object from parent
   }
 
   /*! \brief Removes object from parent
@@ -315,7 +333,7 @@ class plugin
 
     /* Save values to object */
     foreach ($this->attributes as $val){
 
     /* Save values to object */
     foreach ($this->attributes as $val){
-      if ($this->acl_is_writeable($val) && isset ($_POST["$val"])){
+      if (isset ($_POST["$val"]) && $this->acl_is_writeable($val)){
         /* Check for modifications */
         if (get_magic_quotes_gpc()) {
           $data= stripcslashes($_POST["$val"]);
         /* Check for modifications */
         if (get_magic_quotes_gpc()) {
           $data= stripcslashes($_POST["$val"]);
@@ -448,8 +466,7 @@ class plugin
     }
 
     /* Find hooks entries for this class */
     }
 
     /* Find hooks entries for this class */
-    $command= $this->config->search(get_class($this), "CHECK", array('menu', 'tabs'));
-
+    $command = $config->configRegistry->getPropertyValue(get_class($plugin),"check");
     if ($command != ""){
 
       if (!check_command($command)){
     if ($command != ""){
 
       if (!check_command($command)){
@@ -506,7 +523,7 @@ class plugin
       $current_csn = getEntryCSN($this->dn);
       if($current_csn != $this->entryCSN && !empty($this->entryCSN) && !empty($current_csn)){
         $this->entryCSN = $current_csn;
       $current_csn = getEntryCSN($this->dn);
       if($current_csn != $this->entryCSN && !empty($this->entryCSN) && !empty($current_csn)){
         $this->entryCSN = $current_csn;
-        $message[] = _("The object has changed since opened in GOsa. All changes that may be done by others get lost if you save this entry!");
+        $message[] = _("The current object has been altered while beeing edited. If you save this entry, changes that have been made by others will be discarded!");
       }
     }
     return ($message);
       }
     }
     return ($message);
@@ -576,9 +593,10 @@ class plugin
     } else {
       $state= "";
     }
     } else {
       $state= "";
     }
-    $display= "<table summary=\"\" width=\"100%\"><tr>\n<td colspan=2><p><b>$text</b></p>\n";
-    $display.= "<input type=submit value=\"$button_text\" name=\"modify_state\" ".$state.
-      "><p class=\"seperator\">&nbsp;</p></td></tr></table>";
+    $display = "<div class='plugin-enable-header'>\n";
+    $display.= "<p>$text</p>\n";
+    $display.= "<button type='submit' name=\"modify_state\" ".$state.">$button_text</button>\n";
+    $display.= "</div>\n";
 
     return($display);
   }
 
     return($display);
   }
@@ -592,159 +610,14 @@ class plugin
     } else {
       $state= "";
     }
     } else {
       $state= "";
     }
-    $display= "<table summary=\"\" width=\"100%\"><tr>\n<td colspan=2><p><b>$text</b></p>\n";
-    $display.= "<input type=submit value=\"$button_text\" name=\"modify_state\" ".$state.
-      "><p class=\"seperator\">&nbsp;</p></td></tr></table>";
-
+    $display = "<div class='plugin-disable-header'>\n";
+    $display.= "<p>$text</p>\n";
+    $display.= "<button type='submit' name=\"modify_state\" ".$state.">$button_text</button>\n";
+    $display.= "</div>\n";
     return($display);
   }
 
 
     return($display);
   }
 
 
-  /*! \brief Show header message for tab dialogs */
-  function show_header($button_text, $text, $disabled= FALSE)
-  {
-    echo "FIXME: show_header should be replaced by show_disable_header and show_enable_header<br>";
-    if ($disabled == TRUE){
-      $state= "disabled";
-    } else {
-      $state= "";
-    }
-    $display= "<table summary=\"\" width=\"100%\"><tr>\n<td colspan=2><p><b>$text</b></p>\n";
-    $display.= "<input type=submit value=\"$button_text\" name=\"modify_state\" ".
-      ($this->acl_is_createable()?'':'disabled')." ".$state.
-      "><p class=\"seperator\">&nbsp;</p></td></tr></table>";
-
-    return($display);
-  }
-
-  /*! \brief Executes commands after an object has been created */
-  function postcreate($add_attrs= array())
-  {
-    /* Find postcreate entries for this class */
-    $command= $this->config->search(get_class($this), "POSTCREATE",array('menu', 'tabs'));
-
-    if ($command != ""){
-
-      /* Walk through attribute list */
-      foreach ($this->attributes as $attr){
-        if (!is_array($this->$attr)){
-          $add_attrs[$attr] = $this->$attr;
-        }
-      }
-      $add_attrs['dn']=$this->dn;
-
-      $tmp = array();
-      foreach($add_attrs as $name => $value){
-        $tmp[$name] =  strlen($name);
-      }
-      arsort($tmp);
-      
-      /* Additional attributes */
-      foreach ($tmp as $name => $len){
-        $value = $add_attrs[$name];
-        $command= str_replace("%$name", "$value", $command);
-      }
-
-      if (check_command($command)){
-        @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
-            $command, "Execute");
-        exec($command,$arr);
-        foreach($arr as $str){
-          @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
-            $command, "Result: ".$str);
-        }
-      } else {
-        $message= msgPool::cmdnotfound("POSTCREATE", get_class($this));
-        msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
-      }
-    }
-  }
-
-  /*! \brief Execute commands after an object has been modified */
-  function postmodify($add_attrs= array())
-  {
-    /* Find postcreate entries for this class */
-    $command= $this->config->search(get_class($this), "POSTMODIFY",array('menu','tabs'));
-
-    if ($command != ""){
-
-      /* Walk through attribute list */
-      foreach ($this->attributes as $attr){
-        if (!is_array($this->$attr)){
-          $add_attrs[$attr] = $this->$attr;
-        }
-      }
-      $add_attrs['dn']=$this->dn;
-
-      $tmp = array();
-      foreach($add_attrs as $name => $value){
-        $tmp[$name] =  strlen($name);
-      }
-      arsort($tmp);
-      
-      /* Additional attributes */
-      foreach ($tmp as $name => $len){
-        $value = $add_attrs[$name];
-        $command= str_replace("%$name", "$value", $command);
-      }
-
-      if (check_command($command)){
-        @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,$command, "Execute");
-        exec($command,$arr);
-        foreach($arr as $str){
-          @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
-            $command, "Result: ".$str);
-        }
-      } else {
-        $message= msgPool::cmdnotfound("POSTMODIFY", get_class($this));
-        msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
-      }
-    }
-  }
-
-  /*! \brief Executes a command after an object has been removed */
-  function postremove($add_attrs= array())
-  {
-    /* Find postremove entries for this class */
-    $command= $this->config->search(get_class($this), "POSTREMOVE",array('menu','tabs'));
-    if ($command != ""){
-
-      /* Walk through attribute list */
-      foreach ($this->attributes as $attr){
-        if (!is_array($this->$attr)){
-          $add_attrs[$attr] = $this->$attr;
-        }
-      }
-      $add_attrs['dn']=$this->dn;
-
-      $tmp = array();
-      foreach($add_attrs as $name => $value){
-        $tmp[$name] =  strlen($name);
-      }
-      arsort($tmp);
-      
-      /* Additional attributes */
-      foreach ($tmp as $name => $len){
-        $value = $add_attrs[$name];
-        $command= str_replace("%$name", "$value", $command);
-      }
-
-      if (check_command($command)){
-        @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
-            $command, "Execute");
-
-        exec($command,$arr);
-        foreach($arr as $str){
-          @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,
-            $command, "Result: ".$str);
-        }
-      } else {
-        $message= msgPool::cmdnotfound("POSTREMOVE", get_class($this));
-        msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
-      }
-    }
-  }
-
 
   /* Create unique DN */
   function create_unique_dn2($data, $base)
 
   /* Create unique DN */
   function create_unique_dn2($data, $base)
@@ -968,8 +841,7 @@ class plugin
     $ldap->cd($this->config->current['BASE']);
     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dst_dn));
     if (!$ldap->rename_dn($src_dn,$dst_dn)){
     $ldap->cd($this->config->current['BASE']);
     $ldap->create_missing_trees(preg_replace("/^[^,]+,/","",$dst_dn));
     if (!$ldap->rename_dn($src_dn,$dst_dn)){
-#      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $src_dn, "", get_class()));
-      new log("debug","Ldap Protocol v3 implementation error, ldap_rename failed, falling back to manual copy.","FROM: $src_dn  -- TO: $dst_dn",array(),$ldap->get_error());
+      new log("debug","LDAP protocol v3 implementation error, ldap_rename failed, falling back to manual copy.","FROM: $src_dn  -- TO: $dst_dn",array(),$ldap->get_error());
       @DEBUG(DEBUG_LDAP,__LINE__,__FUNCTION__,__FILE__,"Rename failed FROM: $src_dn  -- TO:  $dst_dn", 
           "Ldap Protocol v3 implementation error, falling back to maunal method.");
       return(FALSE);
       @DEBUG(DEBUG_LDAP,__LINE__,__FUNCTION__,__FILE__,"Rename failed FROM: $src_dn  -- TO:  $dst_dn", 
           "Ldap Protocol v3 implementation error, falling back to maunal method.");
       return(FALSE);
@@ -987,13 +859,14 @@ class plugin
     }
 
     // Migrate objectgroups if needed
     }
 
     // Migrate objectgroups if needed
-    $ogroups = get_sub_list("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter(LDAP::fix($src_dn))."))","ogroups", array(get_ou("ogroupRDN")),$this->config->current['BASE'],array("dn"), GL_SUBSEARCH | GL_NO_ACL_CHECK);
+    $ogroups = get_sub_list("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter(LDAP::fix($src_dn))."))",
+      "ogroups", array(get_ou("ogroupRDN")),$this->config->current['BASE'],array("dn"), GL_SUBSEARCH | GL_NO_ACL_CHECK);
 
     // Walk through all objectGroups
     foreach($ogroups as $ogroup){
       // Migrate old to new dn
       $o_ogroup= new ogroup($this->config,$ogroup['dn']);
 
     // Walk through all objectGroups
     foreach($ogroups as $ogroup){
       // Migrate old to new dn
       $o_ogroup= new ogroup($this->config,$ogroup['dn']);
-      if (isset($o_group->member[$src_dn])) {
+      if (isset($o_ogroup->member[$src_dn])) {
         unset($o_ogroup->member[$src_dn]);
       }
       $o_ogroup->member[$dst_dn]= $dst_dn;
         unset($o_ogroup->member[$src_dn]);
       }
       $o_ogroup->member[$dst_dn]= $dst_dn;
@@ -1025,6 +898,23 @@ class plugin
         $role->save();
       }
     }
         $role->save();
       }
     }
+
+    // Update 'manager' attributes from gosaDepartment and inetOrgPerson 
+    $filter = "(&(objectClass=inetOrgPerson)(manager=".LDAP::prepare4filter(LDAP::fix($src_dn))."))";
+    $ocs = $ldap->get_objectclasses();
+    if(isset($ocs['gosaDepartment']['MAY']) && in_array('manager', $ocs['gosaDepartment']['MAY'])){
+      $filter = "(|".$filter."(&(objectClass=gosaDepartment)(manager=".LDAP::prepare4filter(LDAP::fix($src_dn)).")))";
+    }
+    $leaf_deps=  get_list($filter,array("all"),$this->config->current['BASE'], 
+        array("manager","dn","objectClass"),GL_SUBSEARCH | GL_NO_ACL_CHECK);
+    foreach($leaf_deps as $entry){
+      $update = array('manager' => $dst_dn);
+      $ldap->cd($entry['dn']);
+      $ldap->modify($update);
+      if(!$ldap->success()){
+        trigger_error(sprintf("Failed to update manager for %s: %s", bold($entry['dn']), $ldap->get_error()));
+      }
+    }
  
     /* Check if there are gosa departments moved. 
        If there were deps moved, the force reload of config->deps.
  
     /* Check if there are gosa departments moved. 
        If there were deps moved, the force reload of config->deps.
@@ -1108,24 +998,6 @@ class plugin
   }
 
 
   }
 
 
-  function handle_post_events($mode, $add_attrs= array())
-  {
-    switch ($mode){
-      case "add":
-        $this->postcreate($add_attrs);
-      break;
-
-      case "modify":
-        $this->postmodify($add_attrs);
-      break;
-
-      case "remove":
-        $this->postremove($add_attrs);
-      break;
-    }
-  }
-
-
   function saveCopyDialog(){
   }
 
   function saveCopyDialog(){
   }
 
@@ -1169,13 +1041,13 @@ class plugin
     }
   }
 
     }
   }
 
-  function tag_attrs(&$at, $dn= "", $tag= "", $show= false)
-  {
-    /* Skip tagging? 
-  /*! \brief Get gosaUnitTag for the given DN */
+  /*! \brief Get gosaUnitTag for the given DN
        If this is called from departmentGeneric, we have to skip this
         tagging procedure. 
        If this is called from departmentGeneric, we have to skip this
         tagging procedure. 
-     */
+    */
+  function tag_attrs(&$at, $dn= "", $tag= "", $show= false)
+  {
+    /* Skip tagging? */
     if($this->skipTagging){
       return;
     }
     if($this->skipTagging){
       return;
     }
@@ -1253,114 +1125,6 @@ class plugin
   }
 
 
   }
 
 
-  /*! \brief Create a snapshot of the current object */
-  function create_snapshot($type= "snapshot", $description= array())
-  {
-
-    /* Check if snapshot functionality is enabled */
-    if(!$this->snapshotEnabled()){
-      return;
-    }
-
-    /* Get configuration from gosa.conf */
-    $config = $this->config;
-
-    /* Create lokal ldap connection */
-    $ldap= $this->config->get_ldap_link();
-    $ldap->cd($this->config->current['BASE']);
-
-    /* check if there are special server configurations for snapshots */
-    if($config->get_cfg_value("snapshotURI") == ""){
-
-      /* Source and destination server are both the same, just copy source to dest obj */
-      $ldap_to      = $ldap;
-      $snapldapbase = $this->config->current['BASE'];
-
-    }else{
-      $server         = $config->get_cfg_value("snapshotURI");
-      $user           = $config->get_cfg_value("snapshotAdminDn");
-      $password       = $this->config->get_credentials($config->get_cfg_value("snapshotAdminPassword"));
-      $snapldapbase   = $config->get_cfg_value("snapshotBase");
-
-      $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
-      $ldap_to -> cd($snapldapbase);
-
-      if (!$ldap_to->success()){
-        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
-      }
-
-    }
-
-    /* check if the dn exists */ 
-    if ($ldap->dn_exists($this->dn)){
-
-      /* Extract seconds & mysecs, they are used as entry index */
-      list($usec, $sec)= explode(" ", microtime());
-
-      /* Collect some infos */
-      $base           = $this->config->current['BASE'];
-      $snap_base      = $config->get_cfg_value("snapshotBase");
-      $base_of_object = preg_replace ('/^[^,]+,/i', '', $this->dn);
-      $new_base       = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
-
-      /* Create object */
-#$data             = preg_replace('/^dn:.*\n/', '', $ldap->gen_ldif($this->dn,"(!(objectClass=gosaDepartment))"));
-      $data             = $ldap->gen_ldif($this->dn,"(&(!(objectClass=gosaDepartment))(!(objectClass=FAIclass)))");
-      $newName          = str_replace(".", "", $sec."-".$usec);
-      $target= array();
-      $target['objectClass']            = array("top", "gosaSnapshotObject");
-      $target['gosaSnapshotData']       = gzcompress($data, 6);
-      $target['gosaSnapshotType']       = $type;
-      $target['gosaSnapshotDN']         = $this->dn;
-      $target['description']            = $description;
-      $target['gosaSnapshotTimestamp']  = $newName;
-
-      /* Insert the new snapshot 
-         But we have to check first, if the given gosaSnapshotTimestamp
-         is already used, in this case we should increment this value till there is 
-         an unused value. */ 
-      $new_dn                           = "gosaSnapshotTimestamp=".$newName.",".$new_base;
-      $ldap_to->cat($new_dn);
-      while($ldap_to->count()){
-        $ldap_to->cat($new_dn);
-        $newName = str_replace(".", "", $sec."-".($usec++));
-        $new_dn                           = "gosaSnapshotTimestamp=".$newName.",".$new_base;
-        $target['gosaSnapshotTimestamp']  = $newName;
-      } 
-
-      /* Inset this new snapshot */
-      $ldap_to->cd($snapldapbase);
-      $ldap_to->create_missing_trees($snapldapbase);
-      $ldap_to->create_missing_trees($new_base);
-      $ldap_to->cd($new_dn);
-      $ldap_to->add($target);
-      if (!$ldap_to->success()){
-        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $new_dn, LDAP_ADD, get_class()));
-      }
-
-      if (!$ldap->success()){
-        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $new_base, "", get_class()));
-      }
-
-    }
-  }
-
-  /*! \brief Remove a snapshot */
-  function remove_snapshot($dn)
-  {
-    $ui       = get_userinfo();
-    $old_dn   = $this->dn; 
-    $this->dn = $dn;
-    $ldap = $this->config->get_ldap_link();
-    $ldap->cd($this->config->current['BASE']);
-    $ldap->rmdir_recursive($this->dn);
-    if(!$ldap->success()){
-      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn));
-    }
-    $this->dn = $old_dn;
-  }
-
-
   /*! \brief Test if snapshotting is enabled
    *
    * Test weither snapshotting is enabled or not. There will also be some errors posted,
   /*! \brief Test if snapshotting is enabled
    *
    * Test weither snapshotting is enabled or not. There will also be some errors posted,
@@ -1369,267 +1133,7 @@ class plugin
    */
   function snapshotEnabled()
   {
    */
   function snapshotEnabled()
   {
-    return $this->config->snapshotEnabled();
-  }
-
-
-  /* \brief Return available snapshots for the given base */
-  function Available_SnapsShots($dn,$raw = false)
-  {
-    if(!$this->snapshotEnabled()) return(array());
-
-    /* Create an additional ldap object which
-       points to our ldap snapshot server */
-    $ldap= $this->config->get_ldap_link();
-    $ldap->cd($this->config->current['BASE']);
-    $cfg= &$this->config->current;
-
-    /* check if there are special server configurations for snapshots */
-    if($this->config->get_cfg_value("snapshotURI") == ""){
-      $ldap_to      = $ldap;
-    }else{
-      $server         = $this->config->get_cfg_value("snapshotURI");
-      $user           = $this->config->get_cfg_value("snapshotAdminDn");
-      $password       = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
-      $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
-      $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
-      $ldap_to -> cd($snapldapbase);
-      if (!$ldap_to->success()){
-        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
-      }
-    }
-
-    /* Prepare bases and some other infos */
-    $base           = $this->config->current['BASE'];
-    $snap_base      = $this->config->get_cfg_value("snapshotBase");
-    $base_of_object = preg_replace ('/^[^,]+,/i', '', $dn);
-    $new_base       = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
-    $tmp            = array(); 
-
-    /* Fetch all objects with  gosaSnapshotDN=$dn */
-    $ldap_to->cd($new_base);
-    $ldap_to->ls("(&(objectClass=gosaSnapshotObject)(gosaSnapshotDN=".$dn."))",$new_base,
-        array("gosaSnapshotType","gosaSnapshotTimestamp","gosaSnapshotDN","description")); 
-
-    /* Put results into a list and add description if missing */
-    while($entry = $ldap_to->fetch()){ 
-      if(!isset($entry['description'][0])){
-        $entry['description'][0]  = "";
-      }
-      $tmp[] = $entry; 
-    }
-
-    /* Return the raw array, or format the result */
-    if($raw){
-      return($tmp);
-    }else{  
-      $tmp2 = array();
-      foreach($tmp as $entry){
-        $tmp2[base64_encode($entry['dn'])] = $entry['description'][0]; 
-      }
-    }
-    return($tmp2);
-  }
-
-
-  function getAllDeletedSnapshots($base_of_object,$raw = false)
-  {
-    if(!$this->snapshotEnabled()) return(array());
-
-    /* Create an additional ldap object which
-       points to our ldap snapshot server */
-    $ldap= $this->config->get_ldap_link();
-    $ldap->cd($this->config->current['BASE']);
-    $cfg= &$this->config->current;
-
-    /* check if there are special server configurations for snapshots */
-    if($this->config->get_cfg_value("snapshotURI") == ""){
-      $ldap_to      = $ldap;
-    }else{
-      $server         = $this->config->get_cfg_value("snapshotURI");
-      $user           = $this->config->get_cfg_value("snapshotAdminDn");
-      $password       = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
-      $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
-      $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
-      $ldap_to -> cd($snapldapbase);
-      if (!$ldap_to->success()){
-        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
-      }
-    }
-
-    /* Prepare bases */ 
-    $base           = $this->config->current['BASE'];
-    $snap_base      = $this->config->get_cfg_value("snapshotBase");
-    $new_base       = preg_replace("/".preg_quote($base, '/')."$/","",$base_of_object).$snap_base;
-
-    /* Fetch all objects and check if they do not exist anymore */
-    $ui = get_userinfo();
-    $tmp = array();
-    $ldap_to->cd($new_base);
-    $ldap_to->ls("(objectClass=gosaSnapshotObject)",$new_base,array("gosaSnapshotType","gosaSnapshotTimestamp","gosaSnapshotDN","description"));
-    while($entry = $ldap_to->fetch()){
-
-      $chk =  str_replace($new_base,"",$entry['dn']);
-      if(preg_match("/,ou=/",$chk)) continue;
-
-      if(!isset($entry['description'][0])){
-        $entry['description'][0]  = "";
-      }
-      $tmp[] = $entry; 
-    }
-
-    /* Check if entry still exists */
-    foreach($tmp as $key => $entry){
-      $ldap->cat($entry['gosaSnapshotDN'][0]);
-      if($ldap->count()){
-        unset($tmp[$key]);
-      }
-    }
-
-    /* Format result as requested */
-    if($raw) {
-      return($tmp);
-    }else{
-      $tmp2 = array();
-      foreach($tmp as $key => $entry){
-        $tmp2[base64_encode($entry['dn'])] = $entry['description'][0]; 
-      }
-    }
-    return($tmp2);
-  } 
-
-
-  /* \brief Restore selected snapshot */
-  function restore_snapshot($dn)
-  {
-    if(!$this->snapshotEnabled()) return(array());
-
-    $ldap= $this->config->get_ldap_link();
-    $ldap->cd($this->config->current['BASE']);
-    $cfg= &$this->config->current;
-
-    /* check if there are special server configurations for snapshots */
-    if($this->config->get_cfg_value("snapshotURI") == ""){
-      $ldap_to      = $ldap;
-    }else{
-      $server         = $this->config->get_cfg_value("snapshotURI");
-      $user           = $this->config->get_cfg_value("snapshotAdminDn");
-      $password       = $this->config->get_credentials($this->config->get_cfg_value("snapshotAdminPassword"));
-      $snapldapbase   = $this->config->get_cfg_value("snapshotBase");
-      $ldap_to        = new ldapMultiplexer(new LDAP($user,$password, $server));
-      $ldap_to -> cd($snapldapbase);
-      if (!$ldap_to->success()){
-        msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap_to->get_error(), $snapldapbase, "", get_class()));
-      }
-    }
-
-    /* Get the snapshot */ 
-    $ldap_to->cat($dn);
-    $restoreObject = $ldap_to->fetch();
-
-    /* Prepare import string */
-    $data  = gzuncompress($ldap_to->get_attribute($dn,'gosaSnapshotData'));
-
-    /* Import the given data */
-    $err = "";
-    $ldap->import_complete_ldif($data,$err,false,false);
-    if (!$ldap->success()){
-      msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, "", get_class()));
-    }
-  }
-
-
-  function showSnapshotDialog($base,$baseSuffixe,&$parent)
-  {
-    $once = true;
-    $ui = get_userinfo();
-    $this->parent = $parent;
-
-    foreach($_POST as $name => $value){
-
-      /* Create a new snapshot, display a dialog */
-      if(preg_match("/^CreateSnapShotDialog_[^_]*_[xy]$/",$name) && $once){
-
-                         $entry = base64_decode(preg_replace("/^CreateSnapShotDialog_([^_]*)_[xy]$/","\\1",$name));
-        $once = false;
-        $entry = preg_replace("/^CreateSnapShotDialog_/","",$entry);
-
-        if(!empty($entry) && $ui->allow_snapshot_create($entry,$this->parent->acl_module)){
-          $this->snapDialog = new SnapShotDialog($this->config,$entry,$this);
-        }else{
-          msg_dialog::display(_("Permission"),sprintf(_("You are not allowed to create a snapshot for %s."),$entry),ERROR_DIALOG);
-        }
-      }  
-  
-      /* Restore a snapshot, display a dialog with all snapshots of the current object */
-      if(preg_match("/^RestoreSnapShotDialog_/",$name) && $once){
-        $once = false;
-        $entry = base64_decode(preg_replace("/^RestoreSnapShotDialog_([^_]*)_[xy]$/i","\\1",$name));
-        if(!empty($entry) && $ui->allow_snapshot_restore($this->dn,$this->parent->acl_module)){
-          $this->snapDialog = new SnapShotDialog($this->config,$entry,$this);
-          $this->snapDialog->display_restore_dialog = true;
-        }else{
-          msg_dialog::display(_("Permission"),sprintf(_("You are not allowed to restore a snapshot for %s."),$entry),ERROR_DIALOG);
-        }
-      }
-
-      /* Restore one of the already deleted objects */
-      if(((isset($_POST['menu_action']) && $_POST['menu_action'] == "RestoreDeletedSnapShot") 
-          || preg_match("/^RestoreDeletedSnapShot_/",$name)) && $once){
-        $once = false;
-
-        if($ui->allow_snapshot_restore($this->dn,$this->parent->acl_module)){
-          $this->snapDialog = new SnapShotDialog($this->config,"",$this);
-          $this->snapDialog->set_snapshot_bases($baseSuffixe);
-          $this->snapDialog->display_restore_dialog      = true;
-          $this->snapDialog->display_all_removed_objects  = true;
-        }else{
-          msg_dialog::display(_("Permission"),sprintf(_("You are not allowed to restore a snapshot for %s."),$base),ERROR_DIALOG);
-        }
-      }
-
-      /* Restore selected snapshot */
-      if(preg_match("/^RestoreSnapShot_/",$name) && $once){
-        $once = false;
-        $entry = base64_decode(preg_replace("/^RestoreSnapShot_([^_]*)_[xy]$/i","\\1",$name));
-
-        if(!empty($entry) && $ui->allow_snapshot_restore($this->dn,$this->parent->acl_module)){
-          $this->restore_snapshot($entry);
-          $this->snapDialog = NULL;
-        }else{
-          msg_dialog::display(_("Permission"),sprintf(_("You are not allowed to restore a snapshot for %s."),$entry),ERROR_DIALOG);
-        }
-      }
-    }
-
-    /* Create a new snapshot requested, check
-       the given attributes and create the snapshot*/
-    if(isset($_POST['CreateSnapshot']) && is_object($this->snapDialog)){
-      $this->snapDialog->save_object();
-      $msgs = $this->snapDialog->check();
-      if(count($msgs)){
-        foreach($msgs as $msg){
-          msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
-        }
-      }else{
-        $this->dn =  $this->snapDialog->dn;
-        $this->create_snapshot("snapshot",$this->snapDialog->CurrentDescription);
-        $this->snapDialog = NULL;
-      }
-    }
-
-    /* Restore is requested, restore the object with the posted dn .*/
-    if((isset($_POST['RestoreSnapshot'])) && (isset($_POST['SnapShot']))){
-    }
-
-    if(isset($_POST['CancelSnapshot'])){
-      $this->snapDialog = NULL;
-    }
-
-    if(is_object($this->snapDialog )){
-      $this->snapDialog->save_object();
-      return($this->snapDialog->execute());
-    }
+      return $this->config->snapshotEnabled();
   }
 
 
   }
 
 
@@ -1642,12 +1146,14 @@ class plugin
 
   function set_acl_base($base)
   {
 
   function set_acl_base($base)
   {
+    @DEBUG (DEBUG_ACL, __LINE__, __FUNCTION__, __FILE__,"<b>".$base."</b>","<b>ACL-Base:</b> ");
     $this->acl_base= $base;
   }
 
 
   function set_acl_category($category)
   {
     $this->acl_base= $base;
   }
 
 
   function set_acl_category($category)
   {
+    @DEBUG (DEBUG_ACL, __LINE__, __FUNCTION__, __FILE__,"<b>".$category."</b>(/".get_class($this).")","<b>ACL-Category:</b> ");
     $this->acl_category= "$category/";
   }
 
     $this->acl_category= "$category/";
   }
 
@@ -1811,8 +1317,7 @@ class plugin
         /* Acls for this object must be adjusted */
         if($found){
 
         /* Acls for this object must be adjusted */
         if($found){
 
-          $debug_info=  _("Changing ACL dn")."&nbsp;:&nbsp;<br>&nbsp;-"._("from")."&nbsp;<b>&nbsp;".
-            $old_dn."</b><br>&nbsp;-"._("to")."&nbsp;<b>".$new_dn."</b><br>";
+          $debug_info= sprintf(_("Changing ACL DN from %s to %s"), bold($old_dn), bold($new_dn));
           @DEBUG (DEBUG_ACL, __LINE__, __FUNCTION__, __FILE__,$debug_info,"ACL");
 
           $update[$attrs['dn']] =array();
           @DEBUG (DEBUG_ACL, __LINE__, __FUNCTION__, __FILE__,$debug_info,"ACL");
 
           $update[$attrs['dn']] =array();
@@ -1935,7 +1440,7 @@ class plugin
         $this->multi_boxes[] = $val;
       }
 
         $this->multi_boxes[] = $val;
       }
 
-      if ($this->acl_is_writeable($val) && isset ($_POST["$val"])){
+      if (isset ($_POST["$val"]) && $this->acl_is_writeable($val)){
 
         /* Check for modifications */
         if (get_magic_quotes_gpc()) {
 
         /* Check for modifications */
         if (get_magic_quotes_gpc()) {
@@ -1978,139 +1483,108 @@ class plugin
     return($message);
   }
 
     return($message);
   }
 
-
-  /*! \brief  Returns the snapshot header part for "Actions" menu in management dialogs 
-      \param  $layer_menu  
-   */   
-  function get_snapshot_header($base,$category)
+  function get_used_snapshot_bases()
   {
   {
-    $str = "";
-    $ui = get_userinfo();
-    if($this->snapshotEnabled() && $ui->allow_snapshot_restore($base,$category)){
-
-      $ok = false;
-      foreach($this->get_used_snapshot_bases() as $base){
-        $ok |= count($this->getAllDeletedSnapshots($base)) >= 1 ;
-      }
+     return(array());
+  }
 
 
-      if($ok){
-        $str = "..|<img class='center' src='images/lists/restore.png' ".
-          "alt='"._("Restore")."'>&nbsp;"._("Restore").                       "|RestoreDeletedSnapShot|\n";
-      }else{
-        $str = "..|<img class='center' src='images/lists/restore_grey.png' alt=''>&nbsp;"._("Restore")."||\n";
-      }
-    }
-    return($str);
+  function is_modal_dialog()
+  {
+    return(isset($this->dialog) && $this->dialog);
   }
 
 
   }
 
 
-  function get_snapshot_action($base,$category)
+  /*! \brief    Forward command execution requests
+   *             to the hook execution method. 
+   */
+  function handle_post_events($mode, $addAttrs= array())
   {
   {
-    $str= ""; 
-    $ui = get_userinfo();
-    if($this->snapshotEnabled()){
-      if ($ui->allow_snapshot_restore($base,$category)){
-
-        if(count($this->Available_SnapsShots($base))){
-          $str.= "<input class='center' type='image' src='images/lists/restore.png'
-            alt='"._("Restore snapshot")."' name='RestoreSnapShotDialog_".base64_encode($base)."' title='"._("Restore snapshot")."'>&nbsp;";
-        } else {
-          $str = "<img class='center' src='images/lists/restore_grey.png' alt=''>&nbsp;";
-        }
-      }
-      if($ui->allow_snapshot_create($base,$category)){
-        $str.= "<input class='center' type='image' src='images/snapshot.png'
-          alt='"._("Create snapshot")."' name='CreateSnapShotDialog_".base64_encode($base)."' 
-          title='"._("Create a new snapshot from this object")."'>&nbsp;";
-      }else{
-        $str = "<img class='center' src='images/empty.png' alt=' '>&nbsp;";
-      }
+    if(!in_array($mode, array('add','remove','modify'))){
+      trigger_error(sprintf("Invalid post event type given %s! Valid types are [add,modify,remove].", bold($mode)));
+      return;
     }
     }
+    switch ($mode){
+      case "add":
+        plugin::callHook($this,"POSTCREATE", $addAttrs);
+      break;
+
+      case "modify":
+        plugin::callHook($this,"POSTMODIFY", $addAttrs);
+      break;
 
 
-    return($str);
+      case "remove":
+        plugin::callHook($this,"POSTREMOVE", $addAttrs);
+      break;
+    }
   }
 
 
   }
 
 
-  function get_copypaste_action($base,$category,$class,$copy = TRUE, $cut = TRUE)
+  /*! \brief    Calls external hooks which are defined for this plugin (gosa.conf)
+   *            Replaces placeholder by class values of this plugin instance.
+   *  @param    Allows to a add special replacements.
+   */
+  static function callHook($plugin, $cmd, $addAttrs= array())
   {
   {
-    $ui = get_userinfo();
-    $action = "";
-    if($this->CopyPasteHandler){
-      if($cut){
-        if($ui->is_cutable($base,$category,$class)){
-          $action .= "<input class='center' type='image'
-            src='images/lists/cut.png' alt='"._("cut")."' name='cut_%KEY%' title='"._("Cut this entry")."'>&nbsp;";
-        }else{
-          $action.="<img src='images/empty.png' alt=' ' class='center'>&nbsp;";
-        }
-      }
-      if($copy){
-        if($ui->is_copyable($base,$category,$class)){
-          $action.= "<input class='center' type='image'
-            src='images/lists/copy.png' alt='"._("copy")."' name='copy_%KEY%' title='"._("Copy this entry")."'>&nbsp;";
-        }else{
-          $action.="<img src='images/empty.png' alt=' ' class='center'>&nbsp;";
+    global $config;
+    $command = $config->configRegistry->getPropertyValue(get_class($plugin),$cmd);
+    
+    if ($command != ""){
+
+      // Walk trough attributes list and add the plugins attributes. 
+      foreach ($plugin->attributes as $attr){
+        if (!is_array($plugin->$attr)){
+          $addAttrs[$attr] = $plugin->$attr;
         }
       }
         }
       }
-    }
-
-    return($action); 
-  }
+      $ui = get_userinfo();
+      $addAttrs['callerDN']=$ui->dn;
+      $addAttrs['dn']=$plugin->dn;
 
 
+      // Sort attributes by length, ensures correct replacement
+      $tmp = array();
+      foreach($addAttrs as $name => $value){
+        $tmp[$name] =  strlen($name);
+      }
+      arsort($tmp);
 
 
-  function get_copypaste_header($base,$category,$copy = TRUE, $cut = TRUE)
-  {
-    $s = "";
-    $ui =get_userinfo();
-
-    if(!is_array($category)){
-      $category = array($category);
-    }
+      // Now replace the placeholder 
+      foreach ($tmp as $name => $len){
+        $value = $addAttrs[$name];
+        $command= str_replace("%$name", "$value", $command);
+      }
 
 
-    /* Check permissions for each category, if there is at least one category which 
-        support read or paste permissions for the given base, then display the specific actions.
-     */
-    $readable = $pasteable = false;
-    foreach($category as $cat){
-      $readable= $readable || preg_match('/r/', $ui->get_category_permissions($base, $cat));
-      $pasteable= $pasteable || $ui->is_pasteable($base, $cat) == 1;
-    }
-  
-    if(($cut || $copy) && isset($this->CopyPasteHandler) && is_object($this->CopyPasteHandler)){
-      if($readable){
-        $s.= "..|---|\n";
-        if($copy){
-          $s.= "..|<img src='images/lists/copy.png' alt='' border='0' class='center'>".
-            "&nbsp;"._("Copy")."|"."multiple_copy_systems|\n";
-        }
-        if($cut){
-          $s.= "..|<img src='images/lists/cut.png' alt='' border='0' class='center'>".
-            "&nbsp;"._("Cut")."|"."multiple_cut_systems|\n";
+      // If there are still some %.. in our command, try to fill these with some other class vars 
+      if(preg_match("/%/",$command)){
+        $attrs = get_object_vars($plugin);
+        foreach($attrs as $name => $value){
+          if(is_array($value)){
+            $s = "";
+            foreach($value as $val){
+              if(is_string($val) || is_int($val) || is_float($val) || is_bool($val)){
+                $s .= '"'.$val.'",'; 
+              }
+            }
+            $value = '['.trim($s,',').']';
+          }
+          if(!is_string($value) && !is_int($value) && !is_float($value) && !is_bool($value)){
+            continue;
+          }
+          $command= preg_replace("/%$name/", $value, $command);
         }
       }
 
         }
       }
 
-      if($pasteable){
-        if($this->CopyPasteHandler->entries_queued()){
-          $img = "<img border='0' class='center' src='images/lists/paste.png' alt=''>";
-          $s.="..|".$img."&nbsp;"._("Paste")."|editPaste|\n";
-        }else{
-          $img = "<img border='0' class='center' src='images/lists/paste-grey.png' alt=''>";
-          $s.="..|".$img."&nbsp;"._("Paste")."\n";
+      if (check_command($command)){
+        @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,$command,"Execute");
+        exec($command,$arr);
+        if(is_array($arr)){
+          $str = implode("\n",$arr);
+          @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Result: ".$str);
         }
         }
+      } else {
+        $message= msgPool::cmdnotfound("POSTCREATE", get_class($plugin));
+        msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
       }
     }
       }
     }
-    return($s);
-  }
-
-
-  function get_used_snapshot_bases()
-  {
-     return(array());
-  }
-
-  function is_modal_dialog()
-  {
-    return(isset($this->dialog) && $this->dialog);
   }
 }
 
   }
 }