Code

Moved config mangement plugin
authorhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Mon, 18 Oct 2010 09:08:49 +0000 (09:08 +0000)
committerhickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8>
Mon, 18 Oct 2010 09:08:49 +0000 (09:08 +0000)
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@20076 594d385d-05f5-0310-b6e9-bd551577e9d8

23 files changed:
gosa-plugins/goto/admin/ConfigManagement/AddItemDialog.tpl [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-filter.xml [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-list.tpl [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-list.xml [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/DeviceConfig.tpl [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/TemplateEngine.tpl [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/TemplateWidget_textEditor.tpl [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_AddItemDialog.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_DeviceConfig.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_ItemSelector.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateEngine.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_checkbox.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_combobox.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_file.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_fixedList.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_list.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_string.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_textEditor.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_textarea.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/class_filterDeviceItems.inc [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/failed.tpl [new file with mode: 0644]
gosa-plugins/goto/admin/ConfigManagement/puppet.tpl [new file with mode: 0644]

diff --git a/gosa-plugins/goto/admin/ConfigManagement/AddItemDialog.tpl b/gosa-plugins/goto/admin/ConfigManagement/AddItemDialog.tpl
new file mode 100644 (file)
index 0000000..2d9823c
--- /dev/null
@@ -0,0 +1,21 @@
+
+<h3>{t}Add item{/t}</h3>
+
+{t}Please specify a name for the item to add, this name has to be uniq within the item configuration.{/t}
+<br>
+
+<hr>
+
+<p>
+ <b>{$itemCfg.name}</b>&nbsp;-&nbsp; {$itemCfg.description}
+</p>
+
+{t}Name{/t}:&nbsp;<input type='text' name='itemName' value="{$itemName}">
+
+<hr>
+
+<div class='plugin-actions'>
+    <button name='saveItemAdd'>{msgPool type=okButton}</button>
+    <button name='cancelItemAdd'>{msgPool type=cancelButton}</button>
+</div>
+
diff --git a/gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-filter.xml b/gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-filter.xml
new file mode 100644 (file)
index 0000000..183ddd4
--- /dev/null
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<filterdef>
+  <definition>
+    <initial>true</initial>
+    <category>Device</category>
+    <scope>auto</scope>
+    <default>default</default>
+    <attribute>-</attribute>
+  </definition>
+
+  <search>
+    <tag>default</tag>
+    <label>Default filter</label>
+    <query>
+      <backend>DeviceItems</backend>
+      <filter>$</filter>
+    </query>
+    <autocomplete>
+      <attribute>cn</attribute>
+      <frequency>0.5</frequency>
+      <characters>3</characters>
+    </autocomplete>
+  </search>
+
+</filterdef>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-list.tpl b/gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-list.tpl
new file mode 100644 (file)
index 0000000..813a1f5
--- /dev/null
@@ -0,0 +1,21 @@
+<div id="mainlist">
+
+  <div class="mainlist-header">
+   <p>{$HEADLINE}&nbsp;{$SIZELIMIT}</p>
+   <div class="mainlist-nav">
+    <table summary="{$HEADLINE}">
+     <tr>
+      <td>{$RELOAD}</td>
+      <td class="left-border">{t}Base{/t} {$RELEASE}</td>
+      <td class="left-border">{$ACTIONS}</td>
+      <td class="left-border">{$FILTER}</td>
+     </tr>
+    </table>
+   </div>
+  </div>
+
+  {$LIST}
+</div>
+
+<div class="clear"></div>
+
diff --git a/gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-list.xml b/gosa-plugins/goto/admin/ConfigManagement/DeviceConfig-list.xml
new file mode 100644 (file)
index 0000000..9a6812d
--- /dev/null
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<list>
+  <definition>
+    <departmentBrowser>false</departmentBrowser>
+    <departmentRootVisible>false</departmentRootVisible>
+    <baseMode>false</baseMode>
+    <multiSelect>true</multiSelect>
+    <template>goto/Config/DeviceConfig-list.tpl</template>
+    <label>List of items</label>
+    <defaultSortColumn>1</defaultSortColumn>
+
+    %TYPES%
+
+  </definition>
+
+  <table>
+    <layout>|20px;c|||170px;r|</layout>
+
+    <department>
+      <value>%{filter:objectType(dn,objectClass)}</value>
+    </department>
+
+    <department>
+      <value>%{filter:departmentLink(row,dn,description)}</value>
+      <span>2</span>
+    </department>
+
+    <column>
+      <value>%{filter:objectType(dn,objectClass)}</value>
+    </column>
+
+    <column>
+      <label>Name</label>
+      <sortAttribute>cn</sortAttribute>
+      <sortType>string</sortType>
+      <value>%{filter:link(row,dn,"%s",cn,pid)}</value>
+      <export>true</export>
+    </column>
+
+    <column>
+      <label>Description</label>
+      <sortAttribute>description</sortAttribute>
+      <sortType>string</sortType>
+      <value>%{filter:link(row,dn,"%s",description,pid)}</value>
+      <export>true</export>
+    </column>
+
+    <column>
+      <label>Actions</label>
+      <value>%{filter:actions(dn,row,objectClass)}</value>
+    </column>
+
+  </table>
+
+  <actionmenu>
+
+    %ITEMS%
+
+    <action>
+      <name>remove</name>
+      <type>entry</type>
+      <image>images/lists/trash.png</image>
+      <label>Remove</label>
+    </action>
+
+  </actionmenu>
+
+  <actiontriggers snapshot="false" copypaste="false">
+
+    <action>
+      <name>editEntry</name>
+      <type>entry</type>
+      <image>images/lists/edit.png</image>
+      <label>Edit item</label>
+    </action>
+
+    <action>
+      <name>remove</name>
+      <type>entry</type>
+      <image>images/lists/trash.png</image>
+      <label>Remove item</label>
+    </action>
+
+  </actiontriggers>
+
+</list>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/DeviceConfig.tpl b/gosa-plugins/goto/admin/ConfigManagement/DeviceConfig.tpl
new file mode 100644 (file)
index 0000000..0bb627e
--- /dev/null
@@ -0,0 +1,12 @@
+<h3>{t}Device Config{/t}</h3>
+{$navigationList}
+<button name='addSubModule'>{msgPool type='addButton'}</button>
+
+<hr>
+
+<b>{$containerName}</b>&nbsp;<i>({$containerDescription})</i>
+
+<p>
+{$template}
+</p>
+
diff --git a/gosa-plugins/goto/admin/ConfigManagement/TemplateEngine.tpl b/gosa-plugins/goto/admin/ConfigManagement/TemplateEngine.tpl
new file mode 100644 (file)
index 0000000..e60c5ae
--- /dev/null
@@ -0,0 +1,11 @@
+<h3>Bla</h3>
+
+{$template}
+
+<hr>
+
+<div class='plugin-actions'>
+    <button name='saveItemEdit'>{msgPool type=okButton}</button>
+    <button name='cancelItemEdit'>{msgPool type=cancelButton}</button>
+</div>
+
diff --git a/gosa-plugins/goto/admin/ConfigManagement/TemplateWidget_textEditor.tpl b/gosa-plugins/goto/admin/ConfigManagement/TemplateWidget_textEditor.tpl
new file mode 100644 (file)
index 0000000..4f2ae45
--- /dev/null
@@ -0,0 +1,12 @@
+{if $write_protect}
+  {t}The text is write protected, due to its encoding. Editing may break it!{/t}
+  <br>
+  <button type='submit' name='editAnyway'>{t}Edit anyway{/t}</button>
+{/if}
+<textarea {if $write_protect} disabled {/if} {if !$write_protect} name="{$postName}" {/if}
+    style="width:100%;height:300px;" id="{$postName}"
+    rows="20" cols="120">{$value}</textarea>
+<div>
+  <input type="file" name="ImportFile">&nbsp;
+  <button type='submit' name='ImportUpload'>{t}Import text{/t}</button>
+</div>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_AddItemDialog.inc b/gosa-plugins/goto/admin/ConfigManagement/class_AddItemDialog.inc
new file mode 100644 (file)
index 0000000..461508f
--- /dev/null
@@ -0,0 +1,61 @@
+<?php
+
+class AddItemDialog
+{
+    private $itemCfg = NULL;
+    private $config = NULL;
+
+    private $itemName = "";
+    private $itemType = NULL;
+
+    function __construct(&$config, $itemType, $itemCfg)
+    {
+        $this->config = $config;
+        $this->itemCfg = $itemCfg;
+        $this->itemType = $itemType;
+    }
+
+    function execute()
+    {
+        $smarty = get_smarty();
+        $smarty->assign('itemCfg', set_post($this->itemCfg));
+        $smarty->assign('itemName', set_post($this->itemName));
+        return($smarty->fetch(get_template_path('goto/Config/AddItemDialog.tpl', TRUE)));
+    }
+
+    function getItemCfg()
+    {
+        return($this->itemCfg);
+    }
+
+    function getName()
+    {
+        return($this->itemName);
+    }
+
+    function getItemType()
+    {
+        return($this->itemType);
+    }
+
+    function save_object()
+    {
+        if(isset($_POST['itemName'])){
+            $this->itemName = get_post('itemName');
+        }
+    }
+
+    function check()
+    {
+        $message = array();
+        if(empty($this->itemName)){
+            $message[] = msgPool::required(_("Name"));
+        }else
+        if(!tests::is_uid($this->itemName)){
+            $message[] = msgPool::invalid(_("Name"));
+        }
+        return($message);
+    }
+}
+
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_DeviceConfig.inc b/gosa-plugins/goto/admin/ConfigManagement/class_DeviceConfig.inc
new file mode 100644 (file)
index 0000000..b6b28d0
--- /dev/null
@@ -0,0 +1,630 @@
+<?php
+
+/*! \brief  A GOsa plugin which generates a device configuration dialog  
+ */
+class DeviceConfig extends management
+{
+
+    // Used to render the item-configuration dialog 
+    private $TemplateEngine = NULL;
+
+    // A list of all configured items for this device.
+    private $allConfiguredItems = array();
+
+    // The currently active item
+    // Add add and remove action will be performed on this item
+    private $currentItem = array();
+    
+    // A baseSelector which will be fed with a simulated 
+    //  department list. All entries will get a fake base
+    //  which can then be used to fill the baseSelector widget.
+    private $itemContainerSelector = NULL;
+
+    // The currently selected base within management list.
+    private $base ;
+
+    // This array contains a list of all item-types we can add 
+    //  to the currently selected item (currentItem) 
+    private $addableContainerItems = array();
+
+    // Due to the fakt that we use a fake 'base/dn' for all items
+    //  we've to map this 'base/dn' to the items 'id'.
+    private $mappingBaseToID = array();
+
+    private $rootItemID;
+    private $itemConfig = array();
+    private $lastItemID = 1;
+
+    private $rpcError = FALSE;
+    private $initFailed = FALSE;
+    private $invalidInstallMethod = FALSE;
+    private $errorMessage = "";
+
+    // Some plugin related memebers which are not member of 
+    //  the management class. See class plugin.
+    public $initTime;
+    public $is_account = FALSE;
+    public $ignore_account = FALSE;
+    public $pl_notify;
+    public $read_only;
+
+    public $allItemConfigurations = NULL;
+
+    /*! \brief  Constructs the device configuration plugin 
+     *  @param  Config  The GOsa configuration object.
+     */
+    function __construct(&$config, $dn)
+    {
+        // Load the template engine and tell her what template
+        //  to use for the HTML it produces.
+        $this->TemplateEngine = new TemplateEngine($config);
+        $this->TemplateEngine->setTemplate('puppet.tpl');
+        $this->config = $config;
+
+        // Set storage points - We do not have any - We just create a fake list which lists all items
+        $this->storagePoints = array("");
+        
+        // Try to initialize
+        $this->init();
+        $this->rebuildListing();
+    }
+
+    
+    /*! \brief  Sets the installation method to the given method.
+     *          Updates the template engine and adds the initial root 
+     *           object for the selected method.
+     *  @param  The method to use.
+     *  @return TRUE on success else FALSE. 
+     */
+    function setInstallMethod($str)
+    {
+        $this->is_account = FALSE;
+        if(!isset($this->allItemConfigurations[$str])){
+            $this->itemConfig = array();
+            $this->invalidInstallMethod =TRUE;
+            $this->errorMessage = sprintf(_("Invalid installation method selected '%s'!"), $str);
+            msg_dialog::display(_("Setup"), $this->errorMessage, ERROR_DIALOG);
+            return(FALSE);
+        }else{
+
+            $this->itemConfig = $this->allItemConfigurations[$str]['items'];
+            $this->invalidInstallMethod =FALSE;
+            $this->TemplateEngine->load($this->itemConfig);
+
+            // Detect root item, its name is / 
+            $root = NULL;
+            foreach($this->itemConfig as $key => $item){
+                if($item['name'] == '/') {
+                    $root = $key;
+                    break;
+                }
+            }
+            if(!$root){
+                $this->errorMessage = sprintf(_("Installation method '%s' is invalid, no root object found!"), $str);
+                msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
+                $this->initFailed = TRUE;
+                $this->itemConfig = array();
+                return(FALSE);
+            }
+
+            // Set current item to 'root', this is the minimum to get things running.
+            $idRoot = $this->addItem($root,'root',array());
+            $this->rootItemID = $idRoot;
+            $this->setCurrentItem($idRoot);
+            $this->setSelectedListItemID($idRoot);
+            $this->is_account = TRUE;
+            $this->rebuildListing();
+            return(TRUE);
+        }
+    }
+
+
+    /*! \brief  Intializes this plugin
+     *          All available installation methods will be loaded
+     *           and populated.
+     */
+    function init()
+    {
+        // Reset erros
+        $this->rpcError = $this->initFailed = FALSE;
+
+        // Load configuration via rpc.
+        $rpc = $this->config->getRpcHandle();
+
+        // Populate install methods on success.
+        $res = $rpc->getSupportedInstallMethods();
+        if(!$rpc->success()){
+            $this->rpcError = TRUE;
+            $this->errorMessage = $rpc->get_error();;
+            return;
+        }       
+        $this->allItemConfigurations = $res;
+        if(!count($this->allItemConfigurations)){
+            $this->errorMessage = _("No selectable install methods returned!");
+            msg_dialog::display(_("Setup"), $this->errorMessage , ERROR_DIALOG);
+            $this->initFailed = TRUE;
+            return;
+        }
+    }
+
+
+    /*! \brief      Add a new child-item to the currently selected one. 
+     *               
+     *  @param  String  type    The 'type' of the new object, eg. 'KickstartTemplate'
+     *  @param  String  name    The 'name' of the new object.
+     *  @param  Array   values  The initial values for this object.
+     *  @return 
+     */
+    function addItem($type,$name, $values = array())
+    {
+        if(!isset($this->itemConfig[$type])){
+            echo "Invalid type {$type}, skipping item!<br>";
+            return;
+        }
+
+        // Add missing values with the item-type defaults.
+        $allValuesSet = TRUE;
+        foreach($this->itemConfig[$type]['options'] as $oName => $oValue){
+            if(!isset($values[$oName])){
+                $values[$oName] = (isset($oValue['default']))?$oValue['default']:"";
+            }
+        }
+
+        // Get the currently selected entry, its the parent for the newly 
+        //  added one. 
+        $current = &$this->currentItem; 
+
+        // Create a FAKE base to be able to use the management lists
+        //  which are currently ldap and thus dn based.
+        $base = (isset($current['base']))? ",".$current['base'] : '';
+        $base = "{$type}={$name}{$base}";
+
+
+        if(isset($this->mappingBaseToID[$base])){
+            echo "Cannot add entry, dn already in use! {$base}<br>";
+            return(null);
+        }
+    
+        // Get next free item slot.
+        $id = ($this->lastItemID ++);
+        $new = array(
+                'base' => $base,
+                'children' => array(),
+                'id' => $id, 
+                'type' => $type, 
+                'name' => $name, 
+                'values' => $values);
+
+        // Append the entry to the list of all items.
+        $this->allConfiguredItems[$id] = $new;
+
+        // Create a child referenc, this creates some kind of entry tree.
+        $current['children'][$id] = &$this->allConfiguredItems[$id];
+
+        // Add entries to the list of base and id mappings
+        //  this allows us to easily detect the base for an id and vice versa.
+        $this->mappingBaseToID[$id] = $base;
+        $this->mappingBaseToID[$base] = $id;
+        return($id);
+    }
+
+
+    /*! \brief      Selects an item as active.
+     *              All further add and remove actions will be performed
+     *               on the obejcts children.
+     *  @param  String  The 'id' of the item we want to select.
+     *  @return 
+     */
+    function setCurrentItem($item)
+    {
+        if(!isset($this->allConfiguredItems[$item])){
+            echo "Invalid item name {$name}! Skipping selection!";
+            return;
+        }
+
+        // Set the new item info.
+        $this->currentItem = &$this->allConfiguredItems[$item];
+        $this->currentItemType = $this->currentItem['type'];
+        $this->currentItemDescriptor = $this->itemConfig[$this->currentItem['type']];
+    }
+
+
+    /*! \brief      Removes a given item ID.
+     *  @param  String  The 'id' of the item we want to remove.
+     *  @return 
+     */
+    function removeItem($id, &$data = NULL)
+    {
+        if($data === NULL){
+            $data = &$this->allConfiguredItems;
+        }
+
+        // Remove the item and its children
+        if(isset($data[$id])){
+            foreach($data[$id]['children'] as $cid => $item){
+                $this->removeItem($cid, $data);
+            }
+            unset($data[$id]);
+        }
+    
+        // Remove to current id from sub entries
+        foreach($data as $key => $item){
+            $this->removeItem($id, $data[$key]['children']);
+        }
+    }
+
+
+    /*! \brief      Initiate item edit.
+     *              An action send from the management list.
+     *  @param  See management::editEntry 
+     *  @return 
+     */
+    function editEntry($action="",$target=array(),$all=array(), 
+            $altTabClass ="", $altTabType = "", $altAclCategory="")
+    {
+        $this->setCurrentItem($target[0]);
+        $this->dialogObject = $this->TemplateEngine;
+        $this->skipFooter = TRUE;
+        $this->dialog = TRUE;
+
+        // Update the template engine to use another type of item and 
+        //  some other values.
+        $this->TemplateEngine->setValues($this->currentItemType,$this->currentItem['values']);
+    }
+
+
+    /*! \brief      Save changes for the currently edited item.
+     */
+    function saveItemChanges()
+    {
+        // Save eventually changed values
+        if($this->currentItem){
+
+            // Check if everything is fine.
+            $msgs = $this->TemplateEngine->save_object();
+            $msgs = $this->TemplateEngine->check();
+            if(count($msgs)){
+                msg_dialog::displayChecks($msgs);
+            }else{
+                foreach($this->TemplateEngine->getWidgets() as $widget){
+                    $this->currentItem['values'][$widget->getName()] = $widget->getValue();
+                }
+                $this->closeDialogs();
+            }
+        }
+    }
+
+
+    /*! \brief      React on open requests from the management list 
+     */
+    function openEntry($action="",$target=array(),$all=array(), 
+            $altTabClass ="", $altTabType = "", $altAclCategory="")
+    {
+        $this->setSelectedListItemID($target[0]);
+    }
+
+
+    /*! \brief   Overridden render method of class mangement.
+     *            this allows us to add a release selection box.
+     */
+    function renderList()
+    {
+        // In case of an error abort here.
+        if($this->rpcError || $this->initFailed || $this->invalidInstallMethod){
+            $smarty = get_smarty();
+            $smarty->assign('initFailed', $this->initFailed);
+            $smarty->assign('rpcError', $this->rpcError);
+            $smarty->assign('invalidInstallMethod', $this->invalidInstallMethod);
+            $smarty->assign('error', $this->errorMessage);
+            return($smarty->fetch(get_template_path('goto/Config/failed.tpl', TRUE)));
+        }
+
+        // Do we represent a valid account
+        if (!$this->is_account){
+            $str = "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\">&nbsp;<b>".
+                msgPool::noValidExtension("GOsa")."</b>";
+            return($str);
+        }
+
+        // Collect item container list to be able to render the fake-base selector
+        if(!$this->itemContainerSelector){
+            $this->itemContainerSelector = new ItemSelector(
+                    $this->getContainerList(), 
+                    $this->base, 
+                    $this->allConfiguredItems[$this->rootItemID]['base']);
+        }else{
+            $this->itemContainerSelector->setBases($this->getContainerList());
+        }
+        $this->itemContainerSelector->update(true);
+        $this->itemContainerSelector->setBase($this->base);
+
+        session::set('DEVICE_ITEMS', $this->allConfiguredItems);
+        $this->rebuildListing();
+        $filter = $this->getFilter();
+        $headpage = $this->getHeadpage();
+
+        $headpage->update();
+        $smarty = get_smarty();
+        $smarty->assign("RELEASE", $this->itemContainerSelector->render());
+        $display = $headpage->render();
+        return($this->getHeader().$display);
+    }
+
+
+    /*! \brief   Build up a list of items useable for the itemSelector.
+     */
+    function getContainerList($array = NULL)
+    {
+        $array = ($array == NULL)?$this->allConfiguredItems[$this->rootItemID]: $array;
+        $ret[$array['base']] = $array['type'];
+        if(count($array['children'])){
+            foreach($array['children'] as $subItem){
+                $ret = array_merge($ret, $this->getContainerList($subItem));
+            }
+        }
+        return($ret);    
+    }
+
+
+    /*! \brief   Update the management class and tell her which 
+     *            items are available for the itemSelector (baseSelector).
+     */
+    function rebuildListing()
+    {
+        // 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("goto/Config/DeviceConfig-filter.xml", true));
+            $filter->setObjectStorage($this->storagePoints);
+        }
+        $this->setFilter($filter);
+
+        // Load service xml file and fill in placeholders
+        $contents =file_get_contents(get_template_path("goto/Config/DeviceConfig-list.xml", true));
+
+        // Build up device-list configuration   
+        $types ="";
+        $images = array();
+        $images[] = 'images/lists/edit.png';
+        $images[] = 'images/caps.png';
+        $images[] = 'images/lists/trash.png';
+        $images[] = 'images/filter.png';
+        $images[] = 'images/find.png';
+        $i = 0; 
+        foreach($this->itemConfig as $type => $item){
+            $desc = $item['description'];
+            $img = $images[$i++];
+            $types .= 
+                "   <objectType>".
+                "     <label>{$desc}</label>".
+                "     <objectClass>{$type}</objectClass>".
+                "     <category>Device</category>".
+                "     <class>dummy</class>".
+                "     <image>{$img}</image>".
+                "   </objectType>";
+        }
+        $contents = preg_replace("/%TYPES%/", $types, $contents);
+
+
+        $items = "";
+        $i = 0;
+        foreach($this->addableContainerItems as $item){
+            $desc = $this->itemConfig[$item]['description'];
+            $img = $images[$i++];
+            $items .=
+                "<action>".
+                "    <name>add_{$item}</name>".
+                "    <type>entry</type>".
+                "    <image>{$img}</image>".
+                "    <label>{$desc}</label>".
+                "</action>";
+        }
+
+        if(!empty($items)){
+            $items = 
+
+                "<action>".
+                " <type>sub</type>".
+                " <image>images/lists/element.png[new]</image>".
+                " <label>Create</label>".
+                " {$items}".
+                "</action>";
+        }
+
+        $contents = preg_replace("/%ITEMS%/", $items, $contents);
+
+        $headpage = new listing($contents,TRUE);
+        $headpage->setBase($this->base);
+        $headpage->setFilter($filter);
+
+        parent::__construct($this->config, $this->ui, "services", $headpage);
+
+        // Register default actions
+        $this->registerAction("new",        "newEntry");
+        $this->registerAction("edit",       "openEntry"); // !! We forward 'edit' to 'open' to have a department like navigation.
+        $this->registerAction("editEntry",  "editEntry");
+
+        $this->registerAction("saveItemChanges", "saveItemChanges");
+        $this->registerAction("cancelItemEdit", "closeDialogs");
+        $this->registerAction("cancelItemAdd", "closeDialogs");
+        $this->registerAction("saveItemAdd", "saveItemAdd");
+        foreach($this->itemConfig as $name => $item){
+            $this->registerAction("add_{$name}", "newEntry");
+        }
+    }
+
+
+    /*! \brief  This method intiates the object creation.
+     *
+     *  @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'.
+     */
+    function newEntry($action="",$target=array(),$all=array(), 
+            $altTabClass ="", $altTabType = "", $altAclCategory="")
+    {
+        $toAdd = preg_replace("/^add_/", "",$action);
+        $itemToAdd = $this->itemConfig[$toAdd];
+
+        $this->dialogObject = new AddItemDialog($this->config,$toAdd,$itemToAdd);
+        $this->dialog = true;
+    }
+
+    
+    /*! \brief   Saves newly created items and adds them as child to 
+     *            the currently selected item.
+     */
+    function saveItemAdd()
+    {
+        if(!$this->dialogObject instanceOf AddItemDialog) return;
+
+        $msgs = $this->dialogObject->save_object();
+        $msgs = $this->dialogObject->check();
+        if(count($msgs)){
+            msg_dialog::displayChecks($msgs);
+        }else{
+            $itemName = $this->dialogObject->getName();
+            $itemCfg = $this->dialogObject->getItemCfg();
+            $itemType = $this->dialogObject->getItemType();
+
+            $this->setCurrentItem($this->mappingBaseToID[$this->base]);
+    
+            $this->addItem($itemType, $itemName);
+            $this->closeDialogs();
+
+#           $this->setCurrentItem($itemName);
+#           $this->dialogObject = $this->TemplateEngine;
+#           $this->skipFooter = TRUE;
+#           $this->dialog = TRUE;
+
+        }
+    }
+
+
+    /*! \brief  Keep track of posted values, some may be interesting for us. 
+     *          Tell the template engine to take care of posted values too.
+     *  @param  String
+     *  @return 
+     */
+    function save_object()
+    {
+        if(isset($_POST['retryInit'])){
+            $this->init();
+            return;
+        }
+            
+        // Do nothing else in case of an error
+        if($this->rpcError || $this->initFailed) return;
+
+        // Add sub-module requested.
+        if(isset($_POST['addSubModule']) && isset($_POST['subModule'])){
+            $sub = get_post('subModule');
+            if(in_array($sub, $this->currentItemDescriptor['container'])){
+
+                // Check if this is a valid item
+                if(!isset($this->itemConfig[$sub])) {
+                    echo "Invalid item type '{$sub}'!";
+                    $values = array();
+                }else{
+                    $values = $this->itemConfig[$sub]['options'];
+                }
+                $name = 'test'.rand(0,99999);
+                $this->addItem($sub,$name,$values);
+            }
+        }
+
+        // Get the selected item-id from the item list and populate it.
+        if($this->itemContainerSelector){
+            $this->itemContainerSelector->update();
+            $id  = $this->mappingBaseToID[$this->itemContainerSelector->getBase()]; 
+            $this->setSelectedListItemID($id);
+        }
+    }
+
+
+    /* \brief   Updates the currenlty seleted item in the management list
+     */   
+    function setSelectedListItemID($id)
+    {
+        $this->base = $this->mappingBaseToID[$id];
+        $type = $this->allConfiguredItems[$id]['type'];
+        $this->addableContainerItems = $this->itemConfig[$type]['container'];
+    }
+
+
+    /*! \brief    Forward plugin acls
+     */
+    function set_acl_base($base)
+    {
+        $this->acl_base = $base;
+    }
+
+
+    /*! \brief    Forward plugin acls
+     */
+    function set_acl_category($category)
+    {
+        $this->acl_category = $category;
+    }
+
+    function save()
+    {
+        foreach($this->allConfiguredItems as $name => $item){
+            foreach($item['values'] as $oName => $oValue){
+                if(!is_array($oValue)) $oValue = array($oValue);
+                foreach($oValue as $val){
+                    echo "<br>{$name} -- <i>{$item['type']}</i>: <b>{$oName}</b>: {$val}";
+                }
+            }
+        }
+    }
+
+
+    /*! \brief  Initiates the removal for the given entries
+     *           and displays a confirmation dialog.
+     *
+     *  @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'.
+     */
+    protected function removeEntryRequested($action="",$target=array(),$all=array())
+    {
+        foreach($target as $id){
+            $this->removeItem($id);
+        }
+    }
+
+    
+    // Inject user actions
+    function detectPostActions()
+    {
+        if($this->rpcError || $this->initFailed) return(array('action' => ''));
+
+        $action = management::detectPostActions();
+        if(isset($_POST['saveItemEdit'])) $action['action'] = "saveItemChanges";
+        if(isset($_POST['saveItemAdd'])) $action['action'] = "saveItemAdd";
+        if(isset($_POST['cancelItemEdit'])) $action['action'] = "cancelItemEdit";
+        if(isset($_POST['cancelItemAdd'])) $action['action'] = "cancelItemAdd";
+        return($action);
+    }
+
+    
+    function closeDialogs()
+    {
+        parent::closeDialogs();
+        $this->dialog = false;
+    }
+   
+    function check()
+    {
+        return(array());
+    }
+
+    function getRootItemId()
+    {
+        return($this->rootItemID);
+    }
+}
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_ItemSelector.inc b/gosa-plugins/goto/admin/ConfigManagement/class_ItemSelector.inc
new file mode 100644 (file)
index 0000000..f4186de
--- /dev/null
@@ -0,0 +1,25 @@
+<?php
+/*
+ * This code is part of GOsa (http://www.gosa-project.org)
+ * Copyright (C) 2003-2010 GONICUS GmbH
+ *
+ * ID: $$Id: class_listing.inc 15296 2010-01-26 08:27:39Z cajus $$
+ *
+ * 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
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+class ItemSelector extends releaseSelector {
+}
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateEngine.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateEngine.inc
new file mode 100644 (file)
index 0000000..577079f
--- /dev/null
@@ -0,0 +1,154 @@
+<?php
+
+/*! \brief  A template engine used to render dynamic template
+ *           for the GOsa-devices.
+ */
+class TemplateEngine
+{
+    private $config;
+    private $data = array();    
+    private $template = "";
+    private $itemType = '';
+    private $widgets = array();
+
+
+    /*! \brief  Constructs the template engine. 
+     *  @param  Config  The GOsa configuration object.
+     */
+    function __construct($config)
+    {
+        $this->config = &$config;
+    }
+
+
+    /*! \brief  Load/Sets the instruction-set to use for the current
+     *           device configuration.
+     *          A device configruation tells us what options 
+     *           an item can have and what children.
+     *  @param  Array   The instruction set to use.
+     */
+    function load($array)
+    {
+        $this->data = $array;
+    }
+
+
+    /*! \brief  Set the template which will be used to generate 
+     *           the HTML content for this configuration session.
+     *  @param  String  A template filename.
+     */
+    function setTemplate($tmpl)
+    {
+        $this->template = $tmpl;
+    }
+
+
+    /*! \brief  Returns the list of widgets which are currently used 
+     *           by the template engine to render the plugin.
+     *  @return Array  A list of widgets.
+     */
+    function getWidgets()
+    {
+        return($this->widgets);
+    }     
+
+
+    /*! \brief  Sets the current item type we want to render
+     *          E.g.  'KickstartTemplate' and the corresponding values.
+     *
+     *  @param  String  The name of the item we want to render now.
+     *  @param  Array   The initial value.
+     */
+    function setValues($name, $values)
+    {
+        // Set the current item type and reset the widget list.
+        $this->itemType = $name;
+        $this->widgets = array();
+
+        // Do nothing if something seems to be wrong. 
+        if(!isset($this->data[$this->itemType])){
+            echo "Undefined item type '{$name}'!<br>";
+            return;
+        }
+
+        // Get the options provided by the item and create widget for them.
+        $data = $this->data[$this->itemType];
+        if(isset($data['options']) && count($data['options'])){
+            foreach($data['options'] as $name => $item){
+                $widgetClassName = "TemplateWidget_{$item['type']}";
+
+                // Check if the widget is available, if it is not, use a default (string).
+                if(!class_available($widgetClassName)){
+                    echo "Unknown widget class {$widgetClassName}! Falling back to default widget.<br>";
+                    $widgetClassName = "TemplateWidget_string";
+                }
+
+                // Prepare the value for the widget 
+                $value = $values[$name];
+                $syntax = (isset($item['syntax']))? $item['syntax']: "";
+                $providedValues = (isset($item['values']))? $item['values']: array();
+   
+                // Create the new widget.
+                $this->widgets[$name] = new $widgetClassName($this->config, $name, 
+                        $value,
+                        $item['description'],
+                        $syntax,
+                        $item['required'],
+                        $item['type'],
+                        $item['display'],
+                        $providedValues);
+            }
+        }
+    }
+
+    
+    function execute(){
+        return($this->render());
+    }
+    
+
+    /*! \brief  Creates the HTML content for the given list of widgets
+     *  @return String  The HTML content.
+     */
+    function render()
+    {
+        $smarty = get_smarty();
+        $smarty->assign("type", $this->itemType);
+
+        // Tell smarty the HTML-content for each widget and the name that should be
+        //  displayed.
+        foreach($this->widgets as $widget){
+            $smarty->assign($widget->getName(), $widget->render());
+            $smarty->assign($widget->getName()."Name", $widget->getDisplayName());
+        }
+        $template = $smarty->fetch(get_template_path("goto/Config/{$this->template}", TRUE));
+
+        $smarty->assign('template', $template);
+        return($smarty->fetch(get_template_path("goto/Config/TemplateEngine.tpl", TRUE)));
+    }
+
+
+    /*! \brief  Keep track of posted values.
+     */
+    function save_object()
+    {
+        foreach($this->widgets as $widget){
+            $widget->save_object();
+        }
+    }
+
+
+    /*! \brief  Check widget values and return a list of errors.
+     */
+    function check()
+    {
+        $msgs = array();
+        foreach($this->widgets as $widget){
+            $msgs = array_merge($msgs, $widget->check());
+        }
+        return($msgs);
+    }
+}
+
+
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget.inc
new file mode 100644 (file)
index 0000000..45f4fae
--- /dev/null
@@ -0,0 +1,122 @@
+<?php
+
+/*! \brief  The base class for all template-widgets used by the 
+ *           device-configuration class.
+ */
+class TemplateWidget
+{
+    protected $name = "unnamed";
+    protected $value = "";
+
+    protected $description = "";
+    protected $required = "";
+    protected $type = "";
+    protected $display = "";
+    protected $syntax = "";
+    protected $values = "";
+
+    /*! \brief  Constructs the template widget and sets the default values.
+     *  @param  Config  The GOsa configuration object.
+     *  @param  String  A name for the widget.
+     *  @param  String  The initial value.
+     *  @param  String  A description.
+     *  @param  String  True/False  Must-Value/Optional-Value.
+     *  @param  String  The widget type. 
+     *  @param  String  A display name for the widget.
+     */
+    function __construct(&$config, $name, $value, $description,$syntax,$required,$type,$display, $values=array())
+    {
+        $this->config = &$config;
+        $this->name = $name;
+        $this->value = $value;
+        $this->description = $description;
+        $this->required = $required;
+        $this->type = $type;
+        $this->syntax = $syntax;
+        $this->values = $values;
+        $this->display = $display;
+        $class = get_class();
+        $this->postName = "{$class}_{$this->name}";
+    }
+
+
+    /*! \brief  Returns the display-name for the current widget.
+     *  @return  String     The display-name for the widget, this 
+     *                       name will usually be rendered infront of input fields.
+     */
+    function getDisplayName()
+    {
+        $must = ($this->required)?"<span class='required'>*</span>":"";
+        return($this->display.$must);
+    }
+
+
+    /*! \brief  Returns the description for the widget.
+     */
+    function getDescription()
+    {
+        return($this->description);
+    }
+
+
+    /*! \brief  Generates the HTML code for the widget.
+     *  @return  The HTML content for the widget.
+     */
+    function render()
+    {
+        return("");
+    }
+
+
+    /*! \brief  Keep track of posted values.
+     */
+    function save_object()
+    {
+        if(isset($_POST[$this->postName])){
+            $this->value = get_post($this->postName);
+        }
+    }
+
+
+    /*! \brief  Returns the current value.
+     *  @return  Mixed  The widgets value.
+     */
+    function getValue()
+    {
+        return($this->value);
+    }
+
+
+    /*! \brief  Returns the name of the widget.
+     *  @param  String  The widgets name.
+     */
+    function getName()
+    {
+        return($this->name);
+    }
+
+
+    /*! \brief  Sets a new value for the widget.
+     *  @param  String  The new value.
+     */
+    function setValue($value)
+    {
+        $this->value = $value;
+    }
+
+
+    /*! \brief  Check the value entry using the provieded syntax.
+     * @return  Array   Returns a list of errors
+     */
+    function check()
+    {
+        if($this->required && empty($this->value)){
+            return(array(msgPool::required($this->display)));
+        }
+        if(!empty($this->value) && !empty($this->syntax) && !preg_match("/".$this->syntax."/", $this->value)){
+            return(array(msgPool::invalid($this->display, $this->value, "/".$this->syntax."/")));
+        }
+        return(array());
+    }
+}
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_checkbox.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_checkbox.inc
new file mode 100644 (file)
index 0000000..cd6cb1b
--- /dev/null
@@ -0,0 +1,19 @@
+<?php
+
+class TemplateWidget_checkbox extends TemplateWidget
+{
+    function render()
+    {
+        $str = "";
+        $str .= "<input type='checkbox' value='1' name='{$this->postName}' ";
+            if($this->value) $str .= " checked ";
+        $str .= ">";
+        return($str);
+    }
+
+    function save_object()
+    {
+        $this->value = isset($_POST[$this->postName]);
+    }
+}
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_combobox.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_combobox.inc
new file mode 100644 (file)
index 0000000..d0a3069
--- /dev/null
@@ -0,0 +1,22 @@
+<?php
+
+class TemplateWidget_combobox extends TemplateWidget
+{
+    function render()
+    {
+        $str = "";
+
+        // Build up list data
+        $str .= "<select size='1' name='{$this->postName}'>";
+        foreach($this->values as $name => $value){
+            if($name == $this->value){
+                $str .= "<option selected value=\"{$name}\">{$value}</option>\n";
+            }else{
+                $str .= "<option value=\"{$name}\">{$value}</option>\n";
+            }
+        }
+        $str .= "</select>";
+        return($str);
+    }
+}
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_file.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_file.inc
new file mode 100644 (file)
index 0000000..4c26fe3
--- /dev/null
@@ -0,0 +1,34 @@
+<?php
+
+class TemplateWidget_file extends TemplateWidget
+{
+    function render()
+    {
+        $title = set_post($this->description);
+        if(mb_strlen($this->value) == 0){   
+            $ret = "<i>"._("No file uploaded yet")."</i>";
+            $ret.= "<br> <input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"2000000\">
+                <input id=\"{$this->postName}\" 
+                name=\"{$this->postName}\" 
+                type=\"file\" 
+                size=\"20\" 
+                maxlength=\"255\" 
+                accept=\"*.*\">&nbsp;";
+            $ret.= "<button name='{$this->postName}_Upload'>"._("Upload")."</button>";
+        }else{
+            $ret = "<i>"._("File uploaded").": ".mb_strlen($this->value)." "._("Bytes");
+            $ret.= "&nbsp;<button name='{$this->postName}_Remove'>".msgPool::delButton()."</button>";
+        }
+        return($ret);
+    }
+
+    function save_object()
+    {
+        if(isset($_POST["{$this->postName}_Upload"]) && isset($_FILES[$this->postName]['tmp_name'])){
+            $this->value = file_get_contents($_FILES[$this->postName]['tmp_name']);
+        }
+        if(isset($_POST["{$this->postName}_Remove"])) $this->value ="";
+    }
+}
+
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_fixedList.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_fixedList.inc
new file mode 100644 (file)
index 0000000..0f98097
--- /dev/null
@@ -0,0 +1,86 @@
+<?php
+
+class TemplateWidget_fixedList extends TemplateWidget
+{
+    protected $value = array();
+    
+    function __construct(&$config, $name, $value, $description,$syntax,$required,$type,$display,$values)
+    {
+        parent:: __construct($config, $name, $value, $description,$syntax,$required,$type,$display,$values);
+
+        $this->listWidget= new sortableListing($this->value);
+        $this->listWidget->setEditable(false);
+        $this->listWidget->setDeleteable(true);
+        $this->listWidget->setColspecs(array('*'));
+        $this->listWidget->setWidth("100%");
+        $this->listWidget->setHeight("70px");
+        $this->listWidget->setAcl("rwcdm");
+    }
+
+    function getAvailableOptions()
+    {
+        $tmp = array();
+        foreach($this->values as $key => $name){
+            if(!in_array($key, $this->value)){
+                $tmp[$key]=$name;
+            }
+        }
+        return($tmp);
+    }
+
+    function render()
+    {
+        $str = "";
+
+        // Build up list data
+        $data = $this->value;
+        foreach($this->value as $key => $name){
+            $lData[$key] = array('data' => array($this->values[$name]));
+        }
+        $this->listWidget->setListData($data, $lData);
+        $this->listWidget->update();
+        $str .= $this->listWidget->render();
+        $str .= "<select size='1' name='{$this->postName}_Input'>";
+        foreach($this->getAvailableOptions() as $name => $value){
+            $str .= "<option value=\"{$name}\">{$value}</option>\n";
+        }
+        $str .= "</select>";
+        $str .= "<button name='{$this->postName}_Add'>".msgPool::addButton()."</button>";
+        return($str);
+    }
+
+    function save_object()
+    {
+        $this->listWidget->save_object();
+        $action = $this->listWidget->getAction();
+        if($action['action'] == 'delete'){
+            $id = $this->listWidget->getKey($action['targets'][0]);
+            unset($this->value[$id]);
+            $this->value = array_values($this->value);
+        }
+
+        if(isset($_POST["{$this->postName}_Add"]) && isset($_POST["{$this->postName}_Input"])){
+            $input = get_post("{$this->postName}_Input");
+
+            if(!empty($input) && !empty($this->syntax) && !preg_match("/".$this->syntax."/", $input)){
+                msg_dialog::displayChecks(array(msgPool::invalid($this->display, $input, "/".$this->syntax."/")));
+            }elseif(!empty($input)){
+                $this->value[] = $input;
+            }
+        }
+    }
+
+    /*! \brief  Check the value entry using the provieded syntax.
+     * @return  Array   Returns a list of errors
+     */
+    function check()
+    {
+        if($this->required && empty($this->value)){
+            return(array(msgPool::required($this->display)));
+        }
+        return(array());
+    }
+}
+
+
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_list.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_list.inc
new file mode 100644 (file)
index 0000000..d95da2c
--- /dev/null
@@ -0,0 +1,64 @@
+<?php
+
+class TemplateWidget_list extends TemplateWidget
+{
+    function __construct(&$config, $name, $value, $description,$syntax,$required,$type,$display,$values)
+    {
+        parent:: __construct($config, $name, $value, $description,$syntax,$required,$type,$display,$values);
+
+        $this->listWidget= new sortableListing($this->value);
+        $this->listWidget->setEditable(false);
+        $this->listWidget->setDeleteable(true);
+        $this->listWidget->setColspecs(array('*'));
+        $this->listWidget->setWidth("100%");
+        $this->listWidget->setHeight("70px");
+        $this->listWidget->setAcl("rwcdm");
+    }
+
+
+    function render()
+    {
+        $str = "";
+        $this->listWidget->setListData($this->value);
+        $this->listWidget->update();
+        $str .= $this->listWidget->render();
+        $str .= "<input type='text' name='{$this->postName}_Input'>";
+        $str .= "<button name='{$this->postName}_Add'>".msgPool::addButton()."</button>";
+        return($str);
+    }
+
+    function save_object()
+    {
+        $this->listWidget->save_object();
+        $action = $this->listWidget->getAction();
+        if($action['action'] == 'delete'){
+            $id = $this->listWidget->getKey($action['targets'][0]);
+            unset($this->value[$id]);
+            $this->value = array_values($this->value);
+        }
+
+        if(isset($_POST["{$this->postName}_Add"]) && isset($_POST["{$this->postName}_Input"])){
+            $input = get_post("{$this->postName}_Input");
+
+            if(!empty($input) && !empty($this->syntax) && !preg_match("/".$this->syntax."/", $input)){
+                msg_dialog::displayChecks(array(msgPool::invalid($this->display, $input, "/".$this->syntax."/")));
+            }elseif(!empty($input)){
+                $this->value[] = $input;
+            }
+        }
+    }
+
+    /*! \brief  Check the value entry using the provieded syntax.
+     * @return  Array   Returns a list of errors
+     */
+    function check()
+    {
+        if($this->required && empty($this->value)){
+            return(array(msgPool::required($this->display)));
+        }
+        return(array());
+    }
+}
+
+
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_string.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_string.inc
new file mode 100644 (file)
index 0000000..2bf3ccc
--- /dev/null
@@ -0,0 +1,18 @@
+<?php
+
+class TemplateWidget_string extends TemplateWidget
+{
+    function render()
+    {
+        $desc = set_post($this->description);
+        $value = set_post($this->value);
+
+        $name = " name=\"{$this->postName}\" ";
+        $value = " value=\"{$value}\" ";
+        $title = (empty($this->description))?"": " title=\"{$desc}\"";
+
+        return("<input type='text' {$title} {$name} {$value }>");
+    }
+}
+
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_textEditor.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_textEditor.inc
new file mode 100644 (file)
index 0000000..93b7951
--- /dev/null
@@ -0,0 +1,75 @@
+<?php
+
+class TemplateWidget_textEditor extends TemplateWidget
+{
+    protected $value = array();
+    protected $write_protect = FALSE;
+    
+    function __construct(&$config, $name, $value, $description,$syntax,$required,$type,$display,$values)
+    {
+        parent:: __construct($config, $name, $value, $description,$syntax,$required,$type,$display,$values);
+
+        // Keep an eye on dangerous encodings, we may break scripts while editing.
+        $this->mb_extension = function_exists("mb_detect_encoding");
+        if($this->mb_extension){
+            $this->enc_before_edit = mb_detect_encoding($this->value);
+            if($this->enc_before_edit != "ASCII"){
+                $this->write_protect = TRUE;
+            }
+        }
+    }
+
+
+    function render()
+    {
+        $smarty = get_smarty();
+        $smarty->assign("postName", set_post($this->postName));
+        $smarty->assign("write_protect", set_post($this->write_protect));
+        $smarty->assign("value", set_post($this->value));
+        return($smarty->fetch(get_template_path("TemplateWidget_textEditor.tpl", TRUE, dirname(__FILE__))));
+    }
+
+
+    function save_object()
+    {
+        TemplateWidget::save_object();
+        if(isset($_POST['editAnyway'])) $this->write_protect = FALSE;
+
+        if(isset($_POST['ImportUpload'])){
+            if(($_FILES['ImportFile']['error']!=0)){
+                msg_dialog::display(_("Error"), msgPool::incorrectUpload(), ERROR_DIALOG);
+            }elseif(($_FILES['ImportFile']['size']==0)){
+                msg_dialog::display(_("Error"), msgPool::incorrectUpload(_("file is empty")), ERROR_DIALOG);
+            }else{
+                $str = file_get_contents($_FILES['ImportFile']['tmp_name']);
+                $this->value = $str;
+
+                // Check encoding again
+                if($this->mb_extension){
+                    $this->enc_before_edit = mb_detect_encoding($this->value);
+                    if($this->enc_before_edit != "ASCII"){
+                        $this->write_protect = TRUE;
+                    }
+                }
+            }
+        }
+        $this->enc_after_edit = mb_detect_encoding($this->value);
+    }
+
+
+    /*! \brief  Check the value entry using the provieded syntax.
+     * @return  Array   Returns a list of errors
+     */
+    function check()
+    {
+        $msgs = TemplateWidget::check();
+        if($this->mb_extension && !$this->write_protect && $this->enc_after_edit !== $this->enc_before_edit ){
+            $msg = sprintf(_("The text encodig has changed from '%s' to '%s'. Do you really want to save?"),
+                    "<i>".$this->enc_before_edit."</i>","<i>".$this->enc_after_edit."</i>");
+            $msgs[] = $msg;
+            $this->enc_before_edit = $this->enc_after_edit;
+        }
+        return($msgs);
+    }
+}
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_textarea.inc b/gosa-plugins/goto/admin/ConfigManagement/class_TemplateWidget_textarea.inc
new file mode 100644 (file)
index 0000000..030dd11
--- /dev/null
@@ -0,0 +1,16 @@
+<?php
+
+class TemplateWidget_textarea extends TemplateWidget
+{
+    function render()
+    {
+        $title = set_post($this->description);
+        return("<textarea   title=\"{$title}\"
+                            style='width:100%' 
+                            rows=4 type='text' 
+                            name=\"{$this->postName}\">".set_post($this->value)."</textarea>");
+    }
+
+}
+
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/class_filterDeviceItems.inc b/gosa-plugins/goto/admin/ConfigManagement/class_filterDeviceItems.inc
new file mode 100644 (file)
index 0000000..d6dd7c9
--- /dev/null
@@ -0,0 +1,57 @@
+<?php
+
+class filterDeviceItems {
+
+    static function query($base, $scope, $filter, $attributes, $category, $objectStorage= "")
+    {
+        // Walk through the data array till we reach the correct level, then 
+        //  create the list of entries.
+        $data = session::get('DEVICE_ITEMS');
+        foreach($data as $id => $item){
+            if($item['base'] == $base){
+                $data = $item['children'];
+                break;;
+            }
+        }
+
+        // Prepare filter, strip out regex regex related chars, except for *
+        $filter = preg_replace('/\*/','____STAR____', $filter);
+        $filter = preg_quote($filter,'/');
+        $filter = preg_replace('/____STAR____/','.*', $filter);
+
+        // Add entries 
+        $ret = array();
+        foreach($data as $item){
+            filterDeviceItems::addEntry($ret, $item, $scope == 'sub', $filter);
+        }
+        return($ret);
+    }
+
+    static function addEntry(&$ret, $item, $recursive = FALSE, $filter)
+    {
+        if(preg_match("/".$filter."/",$item['name'])){
+            $entry = array();
+            $entry['dn'] = $item['id'];
+            $entry[] = 'dn';
+            $entry['cn'] = array($item['name'], 'count' => 1);
+            $entry[] = 'cn';
+            $entry['id'] = array($item['id'], 'count' => 1);
+            $entry[] = 'id';
+            $entry['description'] = array($item['type'], 'count' => 1);
+            $entry[] = 'description';
+            $entry['objectClass'] = array($item['type'],'count' => 1);
+            $entry[] = 'objectClass';
+            $entry['count'] = 5;
+            $ret[] = $entry;
+        }
+
+        if($recursive && isset($item['children']) && count($item['children'])){
+            foreach($item['children'] as $item){
+                filterDeviceItems::addEntry($ret, $item, $recursive,$filter);
+            }
+        }
+
+    }
+}
+
+?>
diff --git a/gosa-plugins/goto/admin/ConfigManagement/failed.tpl b/gosa-plugins/goto/admin/ConfigManagement/failed.tpl
new file mode 100644 (file)
index 0000000..6a65bc3
--- /dev/null
@@ -0,0 +1,12 @@
+{if $rpcError}
+    <h3>{t}Error{/t}</h3>
+    {msgPool type=rpcError p1=$error}
+    <button name='retryInit'>{t}Retry{/t}</button>
+{elseif $initFailed}
+    <h3>{t}Communication failed{/t}</h3>
+    {msgPool type=rpcError p1=$error}
+    <button name='retryInit'>{t}Retry{/t}</button>
+{elseif $invalidInstallMethod}
+    <h3>{t}Configuration error {/t}</h3>
+    {msgPool type=rpcError p1=$error}
+{/if}
diff --git a/gosa-plugins/goto/admin/ConfigManagement/puppet.tpl b/gosa-plugins/goto/admin/ConfigManagement/puppet.tpl
new file mode 100644 (file)
index 0000000..8b8d95b
--- /dev/null
@@ -0,0 +1,39 @@
+{if $type == 'PuppetModule'}
+    <table width="100%">
+        <tr>
+            <td style="width:50%; vertical-align: top;">
+                <table>
+                    <tr>
+                        <td>{$nameName}</td>
+                        <td>{$name}</td>
+                    </tr>
+                    <tr>
+                        <td>{$descriptionName}</td>
+                        <td>{$description}</td>
+                    </tr>
+                    <tr>
+                        <td>{$versionName}</td>
+                        <td>{$version}</td>
+                    </tr>
+                </table>
+            </td>
+            <td style="width:50%; vertical-align: top;">
+                {$dependencyName}:<br>
+                {$dependency}
+            </td>
+        </tr>
+    </table>
+{/if}
+{if $type == 'PuppetTemplate'}
+    <table>
+        <tr>
+            <td>{$nameName}</td>
+            <td>{$name}</td>
+        </tr>
+        <tr>
+            <td>{$dataName}</td>
+            <td>{$data}</td>
+        </tr>
+    </table>
+    <input type='submit'>    
+{/if}