Code

Updated listing table summary
[gosa.git] / gosa-plugins / fai / admin / fai / class_faiManagement.inc
index 7a23abecd58a5092c7c17c939b68b41c732adfeb..72031cfd93868a7ad1b093cc8cfdd541170052f9 100644 (file)
@@ -3,7 +3,7 @@
  * This code is part of GOsa (http://www.gosa-project.org)
  * Copyright (C) 2003-2008 GONICUS GmbH
  *
- * ID: $$Id: class_roleManagement.inc 14742 2009-11-04 13:18:33Z hickert $$
+ * ID: $$Id: class_faiManagement.inc 14742 2009-11-04 13:18:33Z hickert $$
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -27,14 +27,14 @@ class faiManagement extends management
   var $plIcon  = "plugins/fai/images/plugin.png";
 
   // Tab definition 
-  protected $tabClass = "roletabs";
-  protected $tabType = "ROLETABS";
-  protected $aclCategory = "roles";
-  protected $aclPlugin   = "role";
-  protected $objectName   = "role";
+  protected $tabClass = "";
+  protected $tabType = "";
+  protected $aclCategory = "";
+  protected $aclPlugin   = "";
+  protected $objectName   = "FAI object";
 
   //  Attributes Managed by this plugin can be used in post events
-  protected $attributes   = array("lock_type","lock_name","lock_dn");  
+  public $attributes   = array("lock_type","lock_name","lock_dn");  
 
   var $dispNewBranch=false;
   var $dispNewFreeze=false;
@@ -47,12 +47,32 @@ class faiManagement extends management
   var $lock_dn = "";
   var $lock_name = "";
 
+  var $opsi = NULL;
+
 
   function __construct($config,$ui)
   {
     $this->config = $config;
+
+    /* Check if the opsi plugin is installed.
+     */
+    if(class_available("opsi")){
+      $this->opsi = new opsi($this->config);;
+    }
+
     $this->fai_base = get_ou("faiBaseRDN").$this->config->current['BASE'];
-    $this->fai_release = $this->fai_base;
+    $cfg_rel = $this->config->search("faiManagement","DEFAULTFAIRELEASE",array("menu"));
+    if(!empty($cfg_rel)){
+      $this->fai_release = $cfg_rel;
+    }else{
+      $this->fai_release = $this->fai_base;
+    }
+
+    $releases = $this->getReleaseList();
+    if(!isset($releases[$this->fai_release])){
+      $this->fai_release = $this->fai_base;
+    }
+
     $this->acl_base = $this->config->current['BASE'];
     $this->ui = $ui;
     $this->storagePoints = array(
@@ -61,15 +81,17 @@ class faiManagement extends management
         get_ou('faiScriptRDN'),
         get_ou('faiVariableRDN'),
         get_ou('faiHookRDN'),
-        get_ou('faiProfileRDN'),get_ou('faiTemplateRDN'));
+        get_ou('faiProfileRDN'),
+        get_ou('faiTemplateRDN'));
 
-#    // Build filter
-#    if (session::global_is_set(get_class($this)."_filter")){
-#      $filter= session::global_get(get_class($this)."_filter");
-#    } else {
+    // Build filter
+    if (session::global_is_set(get_class($this)."_filter")){
+      $filter= session::global_get(get_class($this)."_filter");
+    } else {
       $filter = new filter(get_template_path("fai-filter.xml", true));
       $filter->setObjectStorage($this->storagePoints);
-#    }
+    }
+    $filter->elementValues['RELEASE'] = $this->fai_release;
     $this->setFilter($filter);
 
     // Build headpage
@@ -82,9 +104,17 @@ class faiManagement extends management
     if ($this->config->boolValueIsTrue("main", "copyPaste")){
       $this->cpHandler = new CopyPasteHandler($this->config);
     }
-    if($this->config->get_cfg_value("enableSnapshots") == "true"){
-      $this->snapHandler = new SnapshotHandler($this->config);
-    }
+
+    $this->registerAction("remove_multiple","removeEntryRequested");
+    $this->registerAction("new_profile","newEntry");
+    $this->registerAction("new_template","newEntry");
+    $this->registerAction("new_script","newEntry");
+    $this->registerAction("new_hook","newEntry");
+    $this->registerAction("new_variable","newEntry");
+    $this->registerAction("new_package","newEntry");
+    $this->registerAction("new_partition","newEntry");
+    $this->registerAction("newClassNameSelected","newClassNameSelected");
+    $this->registerAction("saveOpsiProperties","saveOpsiProperties");
     $this->registerAction("editByGroup","editByGroup");
     $this->registerAction("createBranch","createBranch");
     $this->registerAction("createFreeze","createFreeze");
@@ -92,71 +122,364 @@ class faiManagement extends management
     $this->registerAction("removeBranchConfirmed","removeBranchConfirmed");
     $this->registerAction("saveBranch","saveBranch");
     $this->registerAction("PerformBranch","PerformBranch");
-    parent::__construct($config, $ui, "roles", $headpage);
+
+    parent::__construct($config, $ui, "FAI object", $headpage);
   }
 
 
-  function editEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
+  /*! \brief  Act on copy & paste actions here.
+   */
+  function copyPasteHandler($action="",$target=array(),$all=array(),$altTabClass ="",$altTabType="",$altAclCategory="",$altAclPlugin="")
   {
+    // Collect real dns, the listed objects are grouped by their cn
     $headpage = $this->getHeadpage();
-    if(count($target) == 1){
-      $entry = $headpage->getEntry($target[0]);
-      if($entry){
+    if($action == "copy"){
+
+      if(count($target) == 1){
+
+        // We just want to copy a single FAI object, let the user choose entries from the FAI-Group
+        $entry = $headpage->getEntry($target[0]);
         if(count($entry['GROUPS']) == 1){
           $data = array_pop($entry['GROUPS']);
           $type = $this->get_type($data);
-          management::editEntry('editEntry',array($data['dn']),array(),$type[0],$type[2],$type[1]);
-          $this->tabObject->by_object[$type[1]]->FAIstate = $data['FAIstate'];
-          $this->tabObject->read_only = preg_match("/freeze/i", $data['FAIstate']);
-
+          $this->cpHandler->add_to_queue($g['dn'],"copy",$type[0],$type[2],'fai',$this);
+          @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$g['dn'],"Entry copied!");
         }else{
-          $this->dialogObject = new faiGroupHandle($entry['GROUPS'],"edit");
+          $this->dialogObject = new faiGroupHandle($entry['GROUPS'],"copy");
+        }
+        
+      }else{
+
+        // More than one group was selected, expect that the user wants to copy the complete groups.
+        foreach($target as $t){
+          $entry = $headpage->getEntry($t);
+
+          // Check for valid FAI objects
+          if(in_array('FAKE_OC_FAI', $entry['objectClass'])){
+            foreach($entry['GROUPS'] as $g){
+              $type = $this->get_type($g);
+              $this->cpHandler->add_to_queue($g['dn'],"copy",$type[0],$type[2],'fai',$this);
+              @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$g['dn'],"Entry copied!");
+            }
+          }
         }
       }
     }
+
+    // Initiate pasting
+    if($action == "paste"){
+      $this->cpPastingStarted = TRUE;
+    }
+
+    // Display any c&p dialogs, eg. object modifications required before pasting.
+    if($this->cpPastingStarted && $this->cpHandler->entries_queued()){
+      $this->cpHandler->SetVar("base",$headpage->getBase());
+      $data = $this->cpHandler->execute();
+      FAI::save_release_changes_now();
+      if(!empty($data)){
+        return($data);
+      }
+    }
+
+    // Automatically disable pasting process since there is no entry left to paste.
+    if(isset($this->cpHandler) && !$this->cpHandler->entries_queued()){
+      $this->cpPastingStarted = FALSE;
+    }
+    return("");
   }
 
 
-  function removeEntryRequested($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
+  /*! \brief  A new FAI object was requested, let the user specify a name theis object now. 
+   */
+  function newEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
+  {
+    $types = array( 
+        "new_partition"     =>  "FAIpartitionTable",
+        "new_script"        =>  "FAIscript",
+        "new_hook"          =>  "FAIhook",
+        "new_variable"      =>  "FAIvariable",
+        "new_template"      =>  "FAItemplate",
+        "new_package"       =>  "FAIpackageList");
+    $types_i18n = array( 
+        "new_partition"     =>  _("partition table"),
+        "new_script"        =>  _("script"),
+        "new_hook"          =>  _("hook"),
+        "new_variable"      =>  _("variable"),
+        "new_template"      =>  _("template"),
+        "new_package"       =>  _("package list"));
+
+    if(isset($types[$action])){
+      $type_acl_mapping = array(
+          "FAIpartitionTable"  => "faiPartitionTable",
+          "FAIpackageList"     => "faiPackage",
+          "FAIscript"          => "faiScript",
+          "FAIvariable"        => "faiVariable",
+          "FAIhook"            => "faiHook",
+          "FAIprofile"         => "faiProfile",
+          "FAItemplate"        => "faiTemplate");
+
+      $acl = $this->ui->get_permissions($this->acl_base,"fai/".$type_acl_mapping[$types[$action]]);
+      if(preg_match("/c/",$acl)){
+        $this->dialogObject = new askClassName($this->config,$this->dn,$this->ui,$types[$action]);
+        $this->dialogObject->parent = &$this;
+      }else{
+        msg_dialog::display(_("Permission error"), 
+            sprintf(_("You have no permission to create a new %s!"), $types_i18n[$action]),      ERROR_DIALOG);
+      }
+    }
+    if($action == "new_profile"){
+      $this->dn = "new" ;
+
+      $acl = $this->ui->get_permissions($this->acl_base,"fai/faiProfile");
+      if(preg_match("/c/",$acl)){
+        $type= $this->get_type(array("objectClass"=>array("FAIprofile")));
+        $str= management::newEntry('newEntry',array(),array(),$type[0],$type[2],$type[1]);
+        if($str) return($str);
+        $this->tabObject->set_acl_base($this->acl_base);
+        $this->tabObject->by_object[$type[1]]->cn = $name;
+      }else{
+        msg_dialog::display(_("Permission error"), sprintf(_("You have no permission to create a new %s!"), _("profile")), ERROR_DIALOG);
+      }
+    }
+  }
+
+
+  /*! \brief   A new FAI class was requested and the user had a specify a name for it.
+   *           Here we check if this name is useable and then open the edit dialogs.
+   */
+  function newClassNameSelected()
+  {
+    $this->dialogObject->save_object();
+    if(count($this->dialogObject->check())!=0){
+      foreach($this->dialogObject->check() as $msg){
+        msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
+      }
+    }elseif(isset($this->dialogObject->objectClass)){
+      $this->dn = "new" ;
+      $type= $this->get_type(array("objectClass"=>array($this->dialogObject->objectClass)));
+      $name = $this->dialogObject->save();
+
+      if(class_exists($type[0])){
+        $this->closeDialogs();
+        $str = management::newEntry('newEntry',array(),array(),$type[0],$type[2],$type[1]);
+        if($str) return($str);
+        $this->tabObject->set_acl_base($this->acl_base);
+        $this->tabObject->by_object[$type[1]]->cn = $name;
+      }
+    }
+  }
+
+
+  /*! \brief   Edit the selected entry.
+   *           If there was a FAI group clicked, display a dialog with all members of the group.
+   */
+  function editEntry($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
   {
     $headpage = $this->getHeadpage();
     if(count($target) == 1){
       $entry = $headpage->getEntry($target[0]);
       if($entry){
-        $this->dialogObject = new faiGroupHandle($entry['GROUPS'],"remove");
+
+        // Edit Opsi objects here 
+        if(in_array("opsi_local", $entry['TYPES']) || in_array("opsi_netboot", $entry['TYPES'])){ 
+          $name = $entry['cn'];
+          $cfg = $this->opsi->get_product_properties($name);
+
+          $str = management::editEntry('editEntry',array($name),array(),'tabs_opsiProdConfig','OPSIPRODCONFIG','opsi');
+          if($str) return($str);
+          if(isset($this->tabObject->by_object['opsiProperties'])){
+            $this->tabObject->by_object['opsiProperties']->set_cfg($cfg);
+            $this->tabObject->by_object['opsiProperties']->set_product($name);
+            $this->skipFooter = TRUE;
+          }else{
+            trigger_error("Unknown tab, please check config.");
+          }
+
+        }else{
+
+          // Edit FAI objects here 
+          if(count($entry['GROUPS']) == 1){
+            $data = array_pop($entry['GROUPS']);
+            $type = $this->get_type($data);
+            $str = management::editEntry('editEntry',array($data['dn']),array(),$type[0],$type[2],$type[1]);
+            if($str) return($str);
+            $this->tabObject->by_object[$type[1]]->FAIstate = $data['FAIstate'];
+            $this->tabObject->read_only = preg_match("/freeze/i", $data['FAIstate']);
+
+          }else{
+            $this->dialogObject = new faiGroupHandle($entry['GROUPS'],"edit");
+          }
+        }
+      }
+    }
+  }
+
+
+  /*! \brief   Save changes made in opsi dialogs.
+   */
+  function saveOpsiProperties()
+  {
+    if($this->tabObject instanceof tabs_opsiProdConfig && isset($_POST['save_properties'])){
+      $this->tabObject->save_object();
+      $op    = $this->tabObject->by_object['opsiProperties'];
+      $name  = $op->get_product();
+      $cfg   = $op->get_cfg();
+      $this->opsi->set_product_properties($name,$cfg);
+      if($this->opsi->is_error()){
+        msg_dialog::display(_("Error"),msgPool::siError($this->opsi->get_error()),ERROR_DIALOG);
+      }else{
+        $this->remove_lock();
+        $this->closeDialogs();
+      }
+    }
+  }
+
+
+  /*! \brief   Someone wants to remove some object(s)
+   *            ask for a confirmation now.
+   */
+  function removeEntryRequested($action="",$target=array(),$all=array(), $altTabClass ="", $altTabType = "", $altAclCategory="")
+  {
+    $this->closeDialogs();
+    if($action == "remove_multiple"){
+
+      // Collect objects to delete
+      $headpage = $this->getHeadpage();
+      $to_delete = array();
+      foreach($target as $id){
+        $object = $headpage->getEntry($id);
+        if(in_array("FAKE_OC_FAI", $object['objectClass'])){
+          foreach($object['GROUPS']  as $entry){
+            array_push($to_delete, $entry);
+          }
+        }
+      }
+      return($this->removeFAIObjects($to_delete));
+    }else{
+
+      // Try to remove a single object, only FAI objects can be removed!
+      $headpage = $this->getHeadpage();
+      if(count($target) == 1){
+        $entry = $headpage->getEntry($target[0]);
+        if($entry && in_array("FAKE_OC_FAI",$entry['objectClass'])){
+          $this->dialogObject = new faiGroupHandle($entry['GROUPS'],"remove");
+        }
       }
     }
   }
 
-  /*! \brief  Object removal was confirmed, now remove the requested entries.
-   *
-   *  @param  String  'action'  The name of the action which was the used as trigger.
-   *  @param  Array   'target'  A list of object dns, which should be affected by this method.
-   *  @param  Array   'all'     A combination of both 'action' and 'target'.
+
+  /*! \brief   Someone wants to remove some object(s)
+   *            ask for a confirmation now.
+   */
+  function removeFAIObjects($to_delete)
+  {
+    // Close dialogs and remove locks for currently handled dns
+    $this->cancelEdit();
+
+    // Do not allow to remove objects with state freeezed
+    $errors = $disallowed = array();
+  
+    foreach($to_delete as $obj){
+      $type = $this->get_type($obj);
+      $acl  = $this->ui->get_permissions($obj['dn'],"fai/".$type[1]);
+      if(!preg_match("/d/",$acl)){
+        $disallowed[] = $obj['dn'];
+      }elseif(isset($obj['FAIstate']) && preg_match('/^freeze/', $obj['FAIstate'])){
+        $errors[] = $obj['dn'];
+      }else{
+        $this->dns[] = $obj['dn'];
+      }
+    }
+    if(count($errors)){
+      msg_dialog::display(_("Branch locked"),
+          sprintf(_("The following entries are locked, you can't remove them %s."),msgPool::buildList($errors)),INFO_DIALOG);
+    }
+    if(count($disallowed)){ 
+      msg_dialog::display(_("Permission error"), msgPool::permDelete($disallowed), ERROR_DIALOG);
+    }
+
+    // Check entry locking
+    $smarty = get_smarty();
+    if(count($this->dns)){
+      if ($user= get_multiple_locks($this->dns)){
+        return(gen_locked_message($user,$this->dns));
+      }
+      if(count($this->dns)){
+
+        // Add locks
+        $dns_names = array();
+        $types = array();
+        $h = $this->getHeadpage();
+
+        // Build list of object -labels
+        foreach($h->objectTypes as $type){
+          $map[$type['objectClass']]= $type['label'];
+        }
+
+        foreach($this->dns as $dn){
+          $tmp = $h->getType($dn);
+          if(isset($map[$tmp])){
+            $dns_names[] = '('._($map[$tmp]).') - '.LDAP::fix($dn);
+          }else{
+            $dns_names[] =LDAP::fix($dn);
+          }
+        }
+        add_lock ($this->dns, $this->ui->dn);
+
+        $smarty->assign("info",msgPool::deleteInfo($dns_names));
+        return($smarty->fetch(get_template_path('removeEntries.tpl', TRUE)));
+      }
+    }
+  }
+
+
+  /*! \brief   Entry removal is confirmed, now remove objects
    */
   function removeEntryConfirmed($action="",$target=array(),$all=array(),
       $altTabClass="",$altTabType="",$altAclCategory="")
   {
     $ldap = $this->config->get_ldap_link();
-    $ldap->cd($this->config->current['BASE']);  
+    $ldap->cd($this->config->current['BASE']); 
+
+    $disallowed = array();
     foreach($this->dns as $key => $dn){
       $ldap->cat($dn);
       if($ldap->count()){
         $attrs = $ldap->fetch();
         $type= $this->get_type($attrs);
-        management::removeEntryConfirmed($action,array($dn),$all,$type[0],$type[2],$type[1]);
 
-        // Now save changes
-        FAI::save_release_changes_now();
-        $to_del = FAI::clean_up_releases($dn);
-        foreach($to_del as $dn){
-          $ldap->rmdir_recursive($dn);
+        $acl  = $this->ui->get_permissions($dn,"fai/".$type[1]);
+        if(preg_match("/d/",$acl)){
+
+          // Now save changes
+          $str = management::removeEntryConfirmed($action,array($dn),$all,$type[0],$type[2],$type[1]);
+          if(!empty($str)) return($str);
+          FAI::save_release_changes_now();
+          $to_del = FAI::clean_up_releases($dn);
+          foreach($to_del as $dn){
+            $ldap->rmdir_recursive($dn);
+          }
+
+        } else {
+          $disallowed[] = $dn;
+          new log("security","fai/".get_class($this),$dn,array(),"Tried to trick deletion.");
         }
       }
     }
+
+    /* Normally this shouldn't be reached, send some extra
+       logs to notify the administrator */
+    if(count($disallowed)){ 
+      msg_dialog::display(_("Permission error"), msgPool::permDelete($disallowed), ERROR_DIALOG);
+    }
   }
 
 
+  /*! \brief   Someone clicked on edit/remove for a grouped FAI object.
+   *           We are now going to display a dialog to let the user select the entry 
+   *            he wants to perform the action on.
+   */
   function editByGroup()
   {
     if($this->dialogObject instanceOf faiGroupHandle && $this->dialogObject->get_mode() == "edit"){
@@ -165,91 +488,53 @@ class faiManagement extends management
       $this->closeDialogs();
       $data = array_pop($entry);
       $type = $this->get_type($data);
-      management::editEntry('editEntry',array($data['dn']),array(),$type[0],$type[2],$type[1]);
+      $str = management::editEntry('editEntry',array($data['dn']),array(),$type[0],$type[2],$type[1]);
+      if($str) return($str);
       $this->tabObject->by_object[$type[1]]->FAIstate = $data['FAIstate'];
       $this->tabObject->read_only = preg_match("/freeze/i", $data['FAIstate']);
-
     }elseif($this->dialogObject instanceOf faiGroupHandle && $this->dialogObject->get_mode() == "remove"){
       $this->dialogObject->save_object();
       $to_delete = $entry = $this->dialogObject->get_selected();
-      $dns = array();
-
-
-      // Check FAIstate to ensure that we do not remove frozen objects
-      //  additionally check ACLs
-      $locked = array();
-      $disallowed = array();
-      foreach($to_delete as $obj){
-        if(isset($obj['FAIstate']) && preg_match('/^freeze/', $obj['FAIstate'])){
-          $locked[] = $obj['dn'];
-        }else{
-          $type = $this->get_type($obj);
-          $acl = $this->ui->get_permissions($obj['dn'], 'acl/'.$type[1]);
-          if(!preg_match("/d/",$acl)){
-            $disallowed[] = $obj['dn']; 
-          }else{
-            $dns[] = $obj['dn'];
-          }
-        }
-      }
-
-      // Display info dialog about locked and not removeable entries
-      if(count($locked)){
-        msg_dialog::display(_("Branch locked"),sprintf(_("The following entries are locked, you can't remove them %s."),
-            msgPool::buildList($locked)));
-      }
-
-      // Display info dialog about not removeable entries due to permissions
-      if(count($disallowed)){
-        msg_dialog::display(_("Permission"),msgPool::permDelete($disallowed),INFO_DIALOG);
-      }
-
-      // There are entries left to be removed
-      if(count($dns)){  
-        $this->closeDialogs();
-        $this->dns = $dns;
-
-        @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$target,"Entry removel requested!");
-
-        // check locks
-        if ($user= get_multiple_locks($this->dns)){
-          return(gen_locked_message($user,$this->dns));
-        }
-
-        // Add locks
-        $dns_names = array();
-        foreach($this->dns as $dn){
-          $dns_names[] =LDAP::fix($dn);
+      if(count($to_delete)) $this->closeDialogs();
+      return($this->removeFAIObjects($to_delete));
+    }elseif($this->dialogObject instanceOf faiGroupHandle && $this->dialogObject->get_mode() == "copy"){
+      $this->dialogObject->save_object();
+      $entries = $entry = $this->dialogObject->get_selected();
+      if(count($entries)){
+        foreach($entries as $entry){
+          $type = $this->get_type($entry);
+          $this->cpHandler->add_to_queue($entry['dn'],"copy",$type[0],$type[2],'fai',$this);
+          @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__,$entry['dn'],"Entry copied!");
         }
-        add_lock ($this->dns, $this->ui->dn);
-
-        // Display confirmation dialog.
-        $smarty = get_smarty();
-        $smarty->assign("info", msgPool::deleteInfo($dns_names,_($this->objectName)));
-        $smarty->assign("multiple", true);
-        return($smarty->fetch(get_template_path('remove.tpl', TRUE)));
-      }else{
         $this->closeDialogs();
       }
     }
   }
 
-  
+
+  /*! \brief   Save dialog/object modifications
+   */
   protected function saveChanges()
   {
-    management::saveChanges();
+    $str = management::saveChanges();
+    if($str) return($str);
 
     // Now save changes
     FAI::save_release_changes_now();
     $to_del = FAI::clean_up_releases($this->last_dn);
+    $ldap= $this->config->get_ldap_link();
     foreach($to_del as $dn){
       $ldap->rmdir_recursive($dn);
     }
   }
 
+
+  /*! \brief   Save dialog/object modifications but keep the dialogs opened
+   */
   protected function applyChanges()
   {
-    management::applyChanges();
+    $str = management::applyChanges();
+    if($str) return($str);
 
     // Now save changes
     FAI::save_release_changes_now();
@@ -259,122 +544,9 @@ class faiManagement extends management
     }
   }
 
-  function detectPostActions()
-  {
-    $action = management::detectPostActions();
-    if(isset($_POST['faiGroupHandle_cancel'])) $action['action'] = "cancel";
-    if(isset($_POST['CancelBranchName'])) $action['action'] = "cancel";
-    if(isset($_POST['delete_branch_confirm'])) $action['action'] = "removeBranchConfirmed";
-    if(isset($_GET['PerformBranch'])) $action['action'] = "PerformBranch";
-    if(isset($_POST['UseBranchName'])) $action['action'] = "saveBranch";
-    if(isset($_POST['faiGroupHandle_apply']))  $action['action'] = "editByGroup";
-    if(isset($_GET['act']) && $_GET['act'] == "branch_branch")  $action['action'] = "createBranch";
-    if(isset($_GET['act']) && $_GET['act'] == "freeze_branch")  $action['action'] = "createFreeze";
-    if(isset($_GET['act']) && $_GET['act'] == "remove_branch")  $action['action'] = "removeBranch";
-
-    foreach($_POST as $name => $value){
-      if(preg_match("/^edit_([0-9]*)_([a-z]*)_(x|y)/i", $name)){
-        $id = preg_replace("/^edit_([0-9]*)_([a-z]*)_(x|y)/i","\\1", $name);
-        $tab = preg_replace("/^edit_([0-9]*)_([a-z]*)_(x|y)/i","\\2", $name);
-        $headpage = $this->getHeadpage();
-        if(isset($headpage->entries[$id]['GROUPS'][$tab])){
-          $data =$headpage->entries[$id]['GROUPS'][$tab];
-          $type = $this->get_type($data);
-          management::editEntry('editEntry',array($data['dn']),array(),$type[0],$type[2],$type[1]); 
-        } 
-        break;
-      }
-    }
-    return($action);
-  }
-
-
-  function renderList()
-  {
-    $filter = $this->getFilter();
-    $headpage = $this->getHeadpage();
-    $filter->setComboBoxOptions("RELEASE",$this->getReleaseList());
-
-    if(isset($_POST['RELEASE'])){
-      $this->fai_release = get_post('RELEASE');
-    }
-    $headpage->setBase($this->fai_release);
-    $headpage->update();
-    $smarty = get_smarty();
-    $smarty->assign("fai_release", $this->fai_release);
-    $smarty->assign("fai_base", $this->fai_base);
-    $r = $this->config->search("faiManagement", "POSTREMOVE",array('menu','tabs'));
-    $c = $this->config->search("faiManagement", "POSTCREATE",array('menu','tabs'));
-    $smarty->assign("allow_create", $c);
-    $smarty->assign("allow_remove", $r);
-    $display = $headpage->render();
-    return($this->getHeader().$display);
-  }
-
-  function getReleaseList($base = "", $prefix ="")
-  {
-    $list = array();
-    if(empty($base)){
-      $base = $this->fai_base;
-      $list[$base] = "/";
-    }
-
-    $ldap = $this->config->get_ldap_link();
-    $ldap->ls("(objectClass=FAIbranch)",$base,array("ou","FAIstate"));
-    $cfg_rel = $this->config->search("faiManagement","DEFAULTFAIRELEASE",array("menu"));
-
-    while($release = $ldap->fetch()){
-      $list[$release['dn']] = $prefix.$release['ou'][0];
-
-      // Preset to prefered releaes if necessary  
-      if(empty($this->fai_release) && $cfg_rel == $release['dn']){
-        $this->fai_release = $release['dn'];
-      }
-
-      $list = array_merge($list,$this->getReleaseList($release['dn'],$prefix."  "));
-    }
-    return($list);
-  }
-
-
-  static function filterProperties($row, $classes)
-  {
-    $objects = array(
-        "FAIpartitionTable"  => array("IMG"=> "plugins/fai/images/fai_partitionTable.png",
-          "NAME"=>_("Partition table"),"KZL"=> "PT", "VAR"=>"ShowPartitions"),
-        "FAIpackageList"     => array("IMG"=> "plugins/fai/images/fai_packages.png",
-          "NAME"=>_("Package list") ,  "KZL"=> "PL", "VAR"=>"ShowPackages"),
-        "FAIscript"          => array("IMG"=> "plugins/fai/images/fai_script.png",
-          "NAME"=>_("Scripts") ,       "KZL"=> "S",  "VAR"=>"ShowScripts"),
-        "FAIvariable"        => array("IMG"=> "plugins/fai/images/fai_variable.png",
-          "NAME"=>_("Variables") ,     "KZL"=> "V",  "VAR"=>"ShowVariables"),
-        "FAIhook"            => array("IMG"=> "plugins/fai/images/fai_hook.png",
-          "NAME"=>_("Hooks"),          "KZL"=> "H",  "VAR"=>"ShowHooks"),
-        "FAIprofile"         => array("IMG"=> "plugins/fai/images/fai_profile.png",
-          "NAME"=>_("Profile") ,       "KZL"=> "P",  "VAR"=>"ShowProfiles"),
-        "FAItemplate"        => array("IMG"=> "plugins/fai/images/fai_template.png",
-          "NAME"=>_("Templates") ,     "KZL"=> "T",  "VAR"=>"ShowTemplates"),
-        "opsi_netboot"       => array("IMG"=> "plugins/opsi/images/netboot_package.png",
-          "NAME"=>_("OPSI netboot product") ,     "KZL"=> "ON",  "VAR"=>"ShowOpsiNetboot"),
-        "opsi_local"         => array("IMG"=> "plugins/opsi/images/local_package.png",
-          "NAME"=>_("OPSI localboot product")   ,     "KZL"=> "OL",  "VAR"=>"ShowOpsiLocal"));
-
-    $icon_list = "";
-    foreach($objects as $type => $type_data){
-      if(in_array($type, $classes)){
-        $icon_list .= "<input type='image' src='".$type_data['IMG']."' title='".$type_data['NAME']."'
-          alt='".$type_data['KZL']."' class='center' name='edit_".$row."_".$type."'>\n";
-      }else{
-        $icon_list .= "<img src='images/empty.png' alt=' ' class='center'>\n";
-      }
-    }
-
-    return $icon_list;
-  }
-
-
-
 
+  /*! \brief   Initiates release removal
+   */
   function removeBranch()
   {
     /* Check if we have a post remove method configured
@@ -395,6 +567,8 @@ class faiManagement extends management
   }
 
 
+  /*! \brief   Remove a release after removal was confirmed
+   */
   function removeBranchConfirmed()
   {
     /* Check if we have a post remove method configured
@@ -462,7 +636,7 @@ class faiManagement extends management
           $this->fai_release = $this->fai_base;
           $this->lock_name   = $name;
           $this->lock_dn     = $bb;
-          $this->postremove();
+          $this->handle_post_events('remove');
 
           $fai_filter = session::get("fai_filter");
           $fai_filter['fai_release'] = $this->fai_release;
@@ -475,36 +649,54 @@ class faiManagement extends management
   }
 
 
+  /*! \brief   Initiates release creation 
+   */
   function createBranch()
   { 
-    $smarty = get_smarty();
-    $this->dispNewBranch=true;
-    $this->dispNewFreeze=false;
-    $smarty->assign("iframe",false);
-    if(isset($_POST['BranchName'])){
-      $smarty->assign("BranchName", $_POST['BranchName']);
+    if($this->config->search("faiManagement", "POSTCREATE",array('menu','tabs')) == ""){ 
+      msg_dialog::display(_("Configuration"), msgPool::cmdnotfound("POSTCREATE", get_class()), ERROR_DIALOG);
+    }elseif(!preg_match("/c/",$this->ui->get_permissions($this->acl_base,"fai/faiManagement"))){
+      msg_dialog::display(_("Permission error"), msgPool::permCreate(_("Branch")), ERROR_DIALOG);
     }else{
-      $smarty->assign("BranchName","");
+      $smarty = get_smarty();
+      $this->dispNewBranch=true;
+      $this->dispNewFreeze=false;
+      $smarty->assign("iframe",false);
+      if(isset($_POST['BranchName'])){
+        $smarty->assign("BranchName", $_POST['BranchName']);
+      }else{
+        $smarty->assign("BranchName","");
+      }
+      return($smarty->fetch(get_template_path('faiNewBranch.tpl', TRUE, dirname(__FILE__))));
     }
-    return($smarty->fetch(get_template_path('faiNewBranch.tpl', TRUE, dirname(__FILE__))));
   }
 
+
+  /*! \brief   Initiates release creation 
+   */
   function createFreeze()
-  { 
-    $smarty = get_smarty();
-    $this->dispNewFreeze=true;
-    $this->dispNewBranch=false;
-    $smarty->assign("iframe",false);
-    if(isset($_POST['BranchName'])){
-      $smarty->assign("BranchName", $_POST['BranchName']);
+  {
+    if($this->config->search("faiManagement", "POSTCREATE",array('menu','tabs')) == ""){ 
+      msg_dialog::display(_("Configuration"), msgPool::cmdnotfound("POSTCREATE", get_class()), ERROR_DIALOG);
+    }elseif(!preg_match("/c/",$this->ui->get_permissions($this->acl_base,"fai/faiManagement"))){
+      msg_dialog::display(_("Permission error"), msgPool::permCreate(_("Branch")), ERROR_DIALOG);
     }else{
-      $smarty->assign("BranchName","");
+      $smarty = get_smarty();
+      $this->dispNewFreeze=true;
+      $this->dispNewBranch=false;
+      $smarty->assign("iframe",false);
+      if(isset($_POST['BranchName'])){
+        $smarty->assign("BranchName", $_POST['BranchName']);
+      }else{
+        $smarty->assign("BranchName","");
+      }
+      return($smarty->fetch(get_template_path('faiNewBranch.tpl', TRUE, dirname(__FILE__))));
     }
-    return($smarty->fetch(get_template_path('faiNewBranch.tpl', TRUE, dirname(__FILE__))));
   }
 
 
-
+  /*! \brief   Creates a new branch
+   */
   function PerformBranch()
   {
     if(!preg_match("/c/",$this->ui->get_permissions($this->acl_base,"fai/faiManagement"))){
@@ -625,13 +817,11 @@ class faiManagement extends management
 
       $this->dispNewFreeze = false;
 
-      /* Postcreate */
-
       /* Assign possible attributes */
       $this->lock_type  = $type;
       $this->lock_name  = $name;
       $this->lock_dn    = $baseToUse;
-      $this->postcreate();
+      $this->handle_post_events('add');
 
       /* Send daemon event to reload the fai release database
        */
@@ -658,8 +848,8 @@ class faiManagement extends management
   }
 
 
-
-
+  /*! \brief   Creates a new branch, after a useable name was specified.
+   */
   function saveBranch()
   {
     if($this->dispNewBranch){
@@ -709,25 +899,40 @@ class faiManagement extends management
     $smarty->assign("plugID", $_GET['plug']);
     $display  = $smarty->fetch(get_template_path('faiNewBranch.tpl', TRUE, dirname(__FILE__)));
     return($display);
+
   }
 
 
-  function CheckNewBranchName($name,$base)
+
+  /*! \brief   Returns a list of all releases for useable for drop down boxes.
+   *                      ou=fai... /
+   *              ou=siga,ou=fai... &nbsp; siga
+   *         ou=1,ou=siga,ou=fai... &nbsp;&nbsp; 1
+   */
+  function getReleaseList($base = "", $prefix ="")
   {
-    $f = $this->fai_release;
-    if($name == ""){
-      return(false);
-    }elseif(in_array($name,$this->getBranches($f))) {
-      return(false);
-    }elseif(tests::is_department_name_reserved($name,$base)){
-      return(false);
+    $list = array();
+    if(empty($base)){
+      $base = $this->fai_base;
+      $list[$base] = "/";
     }
-    return(true);
+
+    $ldap = $this->config->get_ldap_link();
+    $ldap->ls("(objectClass=FAIbranch)",$base,array("ou","FAIstate"));
+
+    while($release = $ldap->fetch()){
+      $list[$release['dn']] = $prefix.$release['ou'][0];
+      $list = array_merge($list,$this->getReleaseList($release['dn'],$prefix."&nbsp; "));
+    }
+    return($list);
   }
 
 
-  /* Get available branches for current base */
+  /*! \brief   Returns a list of all releases with full release names
+   *                      ou=fai... /
+   *              ou=siga,ou=fai... siga
+   *         ou=1,ou=siga,ou=fai... siga/1
+   */
   function getBranches($base = false,$prefix = "")
   {
     $ret = array("/"=>$this->fai_base);
@@ -746,6 +951,11 @@ class faiManagement extends management
   }
 
 
+  /*! \brief   Detects object info like corresponding  tab,class,acl 
+   *    e.g.    [0]   =  tabsPartition
+   *            [1]   =  faiPartitionTable
+   *            [2]   =  FAIPARTITIONTABS
+   */
   function get_type($array)
   {
     if(!isset($array['objectClass'])) return(array());
@@ -772,6 +982,184 @@ class faiManagement extends management
     }
     return(array());
   }
+
+
+  /*! \brief   Checks if the given string can be used as class name
+   */
+  static function check_class_name($oc,$name,$dn)
+  {
+    $base = FAI::get_release_dn($dn);
+
+    if($oc == "FAIprofile"){
+      $f = "";
+      $ocs = array("FAIprofile","FAItemplate","FAIhook","FAIpartitionTable","FAIpackageList","FAIscript","FAIvariable");
+      foreach($ocs as $oc){
+        $f .= "(objectClass=".$oc.")";
+      }
+      $res  = FAI::get_all_objects_for_given_base($base,"(|".$f.")",TRUE);
+    }else{
+      $res  = FAI::get_all_objects_for_given_base($base,"(objectClass=".$oc.")",TRUE);
+    }
+    $delete = array();
+    $used   = array();
+    foreach($res as $object){
+      $used[$object['cn'][0]]= $object['cn'][0];
+    }
+    return($used);
+  }
+
+
+  /*! \brief   Checks if the given string can be used for a new release
+   */
+  function CheckNewBranchName($name,$base)
+  {
+    $f = $this->fai_release;
+    if($name == ""){
+      return(false);
+    }elseif(in_array($name,$this->getBranches($f))) {
+      return(false);
+    }elseif(tests::is_department_name_reserved($name,$base)){
+      return(false);
+    }
+    return(true);
+  }
+
+
+  /*! \brief   This filter is used to display small icons for each listed object 
+   *            instead of their typ names
+   */
+  static function filterProperties($row, $classes)
+  {
+    $objects = array(
+        "FAIpartitionTable"  => array("IMG"=> "plugins/fai/images/fai_partitionTable.png",
+          "NAME"=>_("Partition table"),"KZL"=> "PT", "VAR"=>"ShowPartitions"),
+        "FAIpackageList"     => array("IMG"=> "plugins/fai/images/fai_packages.png",
+          "NAME"=>_("Package list") ,  "KZL"=> "PL", "VAR"=>"ShowPackages"),
+        "FAIscript"          => array("IMG"=> "plugins/fai/images/fai_script.png",
+          "NAME"=>_("Scripts") ,       "KZL"=> "S",  "VAR"=>"ShowScripts"),
+        "FAIvariable"        => array("IMG"=> "plugins/fai/images/fai_variable.png",
+          "NAME"=>_("Variables") ,     "KZL"=> "V",  "VAR"=>"ShowVariables"),
+        "FAIhook"            => array("IMG"=> "plugins/fai/images/fai_hook.png",
+          "NAME"=>_("Hooks"),          "KZL"=> "H",  "VAR"=>"ShowHooks"),
+        "FAIprofile"         => array("IMG"=> "plugins/fai/images/fai_profile.png",
+          "NAME"=>_("Profile") ,       "KZL"=> "P",  "VAR"=>"ShowProfiles"),
+        "FAItemplate"        => array("IMG"=> "plugins/fai/images/fai_template.png",
+          "NAME"=>_("Templates") ,     "KZL"=> "T",  "VAR"=>"ShowTemplates"),
+        "opsi_netboot"       => array("IMG"=> "plugins/opsi/images/netboot_package.png",
+          "NAME"=>_("OPSI netboot product") ,     "KZL"=> "ON",  "VAR"=>"ShowOpsiNetboot"),
+        "opsi_local"         => array("IMG"=> "plugins/opsi/images/local_package.png",
+          "NAME"=>_("OPSI localboot product")   ,     "KZL"=> "OL",  "VAR"=>"ShowOpsiLocal"));
+
+    $icon_list = "";
+    foreach($objects as $type => $type_data){
+      if(in_array($type, $classes)){
+        $icon_list .= "<input type='image' src='".$type_data['IMG']."' title='".$type_data['NAME']."'
+          alt='".$type_data['KZL']."' class='center' name='edit_".$row."_".$type."'>\n";
+      }else{
+        $icon_list .= "<img src='images/empty.png' alt=' ' class='center'>\n";
+      }
+    }
+
+    return $icon_list;
+  }
+
+
+  /*! \brief   Overridden render method of class mangement. 
+   *            this allows us to add a release selection box.
+   */
+  function renderList()
+  {
+    $filter = $this->getFilter();
+    $headpage = $this->getHeadpage();
+    $filter->setComboBoxOptions("RELEASE",$this->getReleaseList());
+
+    if(isset($_POST['RELEASE'])){
+      $this->fai_release = get_post('RELEASE');
+    }
+    $headpage->setBase($this->fai_release);
+    $headpage->update();
+    $smarty = get_smarty();
+    $smarty->assign("fai_release", $this->fai_release);
+    $smarty->assign("opsi_available", (is_object($this->opsi) && $this->opsi->enabled()));
+    $smarty->assign("fai_base", $this->fai_base);
+    $r = $this->config->search("faiManagement", "POSTREMOVE",array('menu','tabs'));
+    $c = $this->config->search("faiManagement", "POSTCREATE",array('menu','tabs'));
+    $smarty->assign("allow_create", $c);
+    $smarty->assign("allow_remove", $r);
+    $display = $headpage->render();
+    return($this->getHeader().$display);
+  }
+
+
+  /*! \brief   Convert POST and GET variables into actions.
+   */
+  function detectPostActions()
+  {
+    $action = management::detectPostActions();
+    if(isset($_POST['remove_multiple'])) $action['action'] = "remove";
+    if(isset($_POST['new_profile'])) $action['action'] = "new_profile";
+    if(isset($_POST['new_template'])) $action['action'] = "new_template";
+    if(isset($_POST['new_script'])) $action['action'] = "new_script";
+    if(isset($_POST['new_hook'])) $action['action'] = "new_hook";
+    if(isset($_POST['new_variable'])) $action['action'] = "new_variable";
+    if(isset($_POST['new_package'])) $action['action'] = "new_package";
+    if(isset($_POST['new_partition'])) $action['action'] = "new_partition";
+
+    if(isset($_POST['save_properties'])) $action['action'] = "saveOpsiProperties";
+    if(isset($_POST['cancel_properties'])) $action['action'] = "cancel";
+
+    if(isset($_POST['edit_continue'])) $action['action'] = "newClassNameSelected";
+    if(isset($_POST['edit_cancel'])) $action['action'] = "cancel";
+
+    if(isset($_POST['faiGroupHandle_cancel'])) $action['action'] = "cancel";
+    if(isset($_POST['CancelBranchName'])) $action['action'] = "cancel";
+    if(isset($_POST['delete_branch_confirm'])) $action['action'] = "removeBranchConfirmed";
+    if(isset($_GET['PerformBranch'])) $action['action'] = "PerformBranch";
+    if(isset($_POST['UseBranchName'])) $action['action'] = "saveBranch";
+    if(isset($_POST['faiGroupHandle_apply']))  $action['action'] = "editByGroup";
+    if(isset($_GET['act']) && $_GET['act'] == "branch_branch")  $action['action'] = "createBranch";
+    if(isset($_GET['act']) && $_GET['act'] == "freeze_branch")  $action['action'] = "createFreeze";
+    if(isset($_GET['act']) && $_GET['act'] == "remove_branch")  $action['action'] = "removeBranch";
+
+    foreach($_POST as $name => $value){
+      if(preg_match("/^edit_([0-9]*)_([a-z_]*)_(x|y)/i", $name)){
+        $id = preg_replace("/^edit_([0-9]*)_([a-z_]*)_(x|y)/i","\\1", $name);
+        $tab = preg_replace("/^edit_([0-9]*)_([a-z_]*)_(x|y)/i","\\2", $name);
+
+        $headpage = $this->getHeadpage();
+        $entry = $headpage->entries[$id];
+
+        if(in_array('FAKE_OC_FAI', $entry['objectClass'])){
+          if(isset($headpage->entries[$id]['GROUPS'][$tab])){
+            $data =$headpage->entries[$id]['GROUPS'][$tab];
+            $type = $this->get_type($data);
+            $str = management::editEntry('editEntry',array($data['dn']),array(),$type[0],$type[2],$type[1]); 
+            if($str) return($str);
+          } 
+        }else{
+          $str = $this->editEntry('editEntry',array($entry['dn'])); 
+          if($str) return($str);
+        }
+        break;
+      }
+    }
+    return($action);
+  }
+
+
+  static function plInfo()
+  {
+    return (array(
+          "plShortName"   => _("FAI releases"),
+          "plDescription" => _("FAI release management"),
+          "plSelfModify"  => FALSE,
+          "plDepends"     => array(),
+          "plPriority"    => 0,
+          "plSection"     => array("administration"),
+          "plCategory"    => array("fai"=> array("description" => _("FAI"),
+              "objectClass" => "FAIclass")),
+          "plProvidedAcls"=> array()));
+  }
 } 
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
 ?>