summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 0512a6d)
raw | patch | inline | side by side (parent: 0512a6d)
author | hickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Tue, 18 May 2010 09:47:45 +0000 (09:47 +0000) | ||
committer | hickert <hickert@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Tue, 18 May 2010 09:47:45 +0000 (09:47 +0000) |
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@18529 594d385d-05f5-0310-b6e9-bd551577e9d8
20 files changed:
diff --git a/gosa-core/plugins/addons/configViewer/class_commandVerifier.inc b/gosa-core/plugins/addons/configViewer/class_commandVerifier.inc
+++ /dev/null
@@ -1,77 +0,0 @@
-<?php
-class commandVerifier
-{
- private $property = NULL;
- private $config = NULL;
- private $command = "";
-
- function __construct($config, $property)
- {
- $this->config = &$config;
- $this->property = &$property;
- $this->command = $this->property->getValue(TRUE);
- }
-
- function execute()
- {
- $smarty = get_smarty();
- $output= "";
-
- if(isset($_POST['execute'])){
-
-
- $descriptorSpec = array(0 => array("pipe", "r"),
- 1 => array('pipe', 'w'),
- 2 => array('pipe', 'w'));
- $process = proc_open($this->command, $descriptorSpec, $pipes);
- $txOff = 0; $txLen = strlen($stdin);
-
- $stdout = ''; $stdoutDone = FALSE;
- $stderr = ''; $stderrDone = FALSE;
- stream_set_blocking($pipes[0], 0); // Make stdin/stdout/stderr non-blocking
- stream_set_blocking($pipes[1], 0);
- stream_set_blocking($pipes[2], 0);
- if ($txLen == 0) fclose($pipes[0]);
- while (TRUE) {
- $rx = array(); // The program's stdout/stderr
- if (!$stdoutDone) $rx[] = $pipes[1];
- if (!$stderrDone) $rx[] = $pipes[2];
- foreach ($rx as $r) {
- if ($r == $pipes[1]) {
- $stdout .= fread($pipes[1], 8192);
- if (feof($pipes[1])) { fclose($pipes[1]); $stdoutDone = TRUE; }
- } else if ($r == $pipes[2]) {
- $stderr .= fread($pipes[2], 8192);
- if (feof($pipes[2])) { fclose($pipes[2]); $stderrDone = TRUE; }
- }
- }
- if (!is_resource($process)) break;
- if ($txOff >= $txLen && $stdoutDone && $stderrDone) break;
- }
- $code = proc_close($process);
-
- if(!empty($stdout)) $stdout = "<pre>".htmlentities($stdout,ENT_COMPAT,'UTF-8')."</pre>";
- if(!empty($stderr)) $stderr = "<pre>".htmlentities($stderr,ENT_COMPAT,'UTF-8')."</pre>";
- $output = "
- <table summary='"._("Results")."'>
- <tr><td><b>Result:</b></td><td>$stdout</td></tr>
- <tr><td><b>Error:</b></td><td>$stderr</td></tr>
- <tr><td><b>Return code:</b></td><td>$code</td></tr>
- </table>";
- }
- $smarty->assign('value', htmlentities($this->command,ENT_COMPAT,'UTF-8'));
- $smarty->assign('output', $output);
- return($smarty->fetch(get_template_path('commandVerifier.tpl', 'TRUE')));
- }
-
- function save_object()
- {
- if(isset($_POST['command'])) $this->command = get_post('command');
- }
-
- function save()
- {
- $this->property->setValue($this->command);
- }
-}
-?>
diff --git a/gosa-core/plugins/addons/configViewer/class_configViewer.inc b/gosa-core/plugins/addons/configViewer/class_configViewer.inc
+++ /dev/null
@@ -1,272 +0,0 @@
-<?php
-
-
-class propertyEditor extends management
-{
- var $plHeadline= "Preferences";
- var $plDescription= "Configure global and special GOsa settings like hooks and plugin parameters";
- var $plIcon = "plugins/propertyEditor/images/plugin.png";
-
- var $toBeMigrated = array();
-
- function __construct($config,$ui)
- {
- $this->config = $config;
- $this->ui = $ui;
-
- // 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("property-filter.xml", true));
- $filter->setObjectStorage($this->storagePoints);
- }
- $this->setFilter($filter);
-
- // Build headpage
- $headpage = new listing(get_template_path("property-list.xml", true));
- $headpage->registerElementFilter("propertyName", "propertyEditor::propertyName");
- $headpage->registerElementFilter("propertyGroup", "propertyEditor::propertyGroup");
- $headpage->registerElementFilter("propertyClass", "propertyEditor::propertyClass");
- $headpage->registerElementFilter("propertyValue", "propertyEditor::propertyValue");
- $headpage->setFilter($filter);
- parent::__construct($config, $ui, "property", $headpage);
-
- $this->registerAction("saveProperties","saveProperties");
- $this->registerAction("cancelProperties","cancelProperties");
- }
-
-
- function execute()
- {
- // Walk trough all properties and check if there posts for us.
- $all = $this->config->configRegistry->getAllProperties();
- foreach($all as $prop){
- $post = "{$prop->getClass()}:{$prop->getName()}";
- if(isset($_POST[$post]) && $prop->getStatus() != 'removed'){
- $prop->setValue(get_post($post));
- }
-
- // Open the command verify dialog
- if(isset($_POST["testCommand_{$post}"])){
- $this->dialogObject = new commandVerifier($this->config,$prop);
- }
- }
- if(isset($_POST['commandVerifier_save'])){
- $this->dialogObject->save();
- $this->closeDialogs();
- }
- if(isset($_POST['commandVerifier_cancel'])){
- $this->closeDialogs();
- }
-
-
- // Execute registered management event listeners.
- $this->handleActions($this->detectPostActions());
-
- // Handle properties that have to be migrated
- if(isset($_POST['propertyMigrate_cancel']) && count($this->toBeMigrated)){
- unset($this->toBeMigrated[0]);
- $this->toBeMigrated = array_values($this->toBeMigrated);
- }
- if(isset($_POST['propertyMigrate_save']) && count($this->toBeMigrated)){
- $first = $this->toBeMigrated[0]->getMigrationClass();
- $first->save_object();
- $msgs = $first->check();
- if(!count($msgs)){
- $this->toBeMigrated[0]->save();
- unset($this->toBeMigrated[0]);
- $this->toBeMigrated = array_values($this->toBeMigrated);
-
- // Nothing to migrate and everything is fine, reload the list now.
- if(!count($this->toBeMigrated)){
- $this->config->configRegistry->reload($force=TRUE);
- }
- }
- }
- if(count($this->toBeMigrated)){
- $first = $this->toBeMigrated[0]->getMigrationClass();
- $first->save_object();
-
- // We've no problems with this property anymore.
- while($first instanceOf propertyMigration && !$first->checkForIssues()){
- $this->toBeMigrated[0]->save();
- unset($this->toBeMigrated[0]);
- $this->toBeMigrated = array_values($this->toBeMigrated);
- if(count($this->toBeMigrated)){
- $first = $this->toBeMigrated[0]->getMigrationClass();
- }else{
- $first = NULL;
-
- // Nothing to migrate and everything is fine, reload the list now.
- if(!count($this->toBeMigrated)){
- $this->config->configRegistry->reload($force=TRUE);
- }
- }
- }
-
- if($first){
- $content = $first->execute();
- $smarty = get_smarty();
- $smarty->assign('content', $content);
- $smarty->assign('leftSteps', count($this->toBeMigrated));
- return($smarty->fetch(get_template_path('migrate.tpl',TRUE)));
- }
- }
-
- return(management::execute());
- }
-
- function renderList()
- {
- // Walk trough all properties and check if we have modified something
- $all = $this->config->configRegistry->getAllProperties();
- foreach($all as $prop){
- $modified = in_array($prop->getStatus(),array('modified','removed'));
- if($modified) break;
- }
-
- $smarty = get_smarty();
- $smarty->assign('is_modified', $modified);
- return(management::renderList());
- }
-
-
- function cancelProperties()
- {
- $this->config->configRegistry->reload($force=TRUE);
- }
-
- function saveProperties()
- {
- // Check if we've misconfigured properties and skip saving in this case.
- $all = $this->config->configRegistry->getAllProperties();
- $valid = TRUE;
- foreach($all as $prop){
- $valid &= $prop->check();
- }
-
- // Now save the properties.
- if($valid){
- $this->toBeMigrated = $this->config->configRegistry->saveChanges();
-
- // Nothing to migrate and everything is fine, reload the list now.
- if(!count($this->toBeMigrated)){
- $this->config->configRegistry->reload($force=TRUE);
- }
- }
- }
-
- function detectPostActions()
- {
- $action = management::detectPostActions();
- if(isset($_POST['saveProperties'])) $action['action'] = 'saveProperties';
- if(isset($_POST['cancelProperties'])) $action['action'] = 'cancelProperties';
- return($action);
- }
-
- protected function removeEntryRequested($action="",$target=array(),$all=array())
- {
- foreach($target as $dn){
- list($class,$name) = preg_split("/:/", $dn);
- if($this->config->configRegistry->propertyExists($class,$name)){
- $prop = $this->config->configRegistry->getProperty($class,$name);
- $prop->restoreDefault();
- }
- }
- }
-
- static function propertyGroup($group, $description = array())
- {
- return($group[0]);
- }
- static function propertyClass($class, $description = array())
- {
- global $config;
- if(isset($config->configRegistry->classToName[$class[0]])){
- $class = $config->configRegistry->classToName[$class[0]];
- }else{
- $class = $class[0];
- }
- return($class);
- }
- static function propertyName($class,$cn, $description,$mandatory)
- {
- $id = "{$class[0]}_{$cn[0]}";
-
- $title = _("No description");
- if(isset($description[0])) $title = htmlentities($description[0],ENT_COMPAT, 'UTF-8');
- $title = preg_replace("/\n/", "<br>", $title);
- $tooltip = "<div id='tooltip_{$id}' class='tooltip' style='display:none'>".$title."</div>";
-
- $must = ($mandatory[0]) ? "<span class='required'>*</span>" : "";
-
- return($tooltip."<span title='tooltip_{$id}'>{$cn[0]}{$must}</span>");
- }
- static function propertyValue($class,$cn,$value,$type,$default,$defaults,$check,$mandatory)
- {
- $ssize = "208px";
- $isize = "200px";
- $name = "{$class[0]}:{$cn[0]}";
- $value = htmlentities($value[0],ENT_QUOTES ,'UTF-8');
-
- // Add slashes to keep escaped values escaped after passing them to smarty.
- $value = addslashes($value);
-
- switch($type[0]){
- case 'bool':
- $res = "<select size=1 name=\"{$name}\" style='width:{$ssize}'>";
- $false = (preg_match('/true/i', $value)) ? '' : "selected";
- $true = (preg_match('/true/i', $value)) ? "selected" : '';
- $res.= "<option {$false} value='false'>"._("FALSE")."</option>";
- $res.= "<option {$true} value='true'>"._("TRUE")."</option>";
- $res.= "</select>";
- case 'switch':
- if(!empty($defaults[0])){
- $data = call_user_func(preg_split("/::/", $defaults[0]), $class[0],$cn[0],$value, $type[0]);
- if(is_array($data)){
- $res = "<select size=1 name=\"{$name}\" style='width:{$ssize}'>";
- foreach($data as $oValue => $oDesc){
- if($oValue == $value){
- $res.="<option selected value=\"{$oValue}\">{$oDesc}</option>\n";
- }else{
- $res.="<option value=\"{$oValue}\">{$oDesc}</option>\n";
- }
- }
- $res.= "</select>";
- }
- }
- break;
- case 'command':
- $res = "<input style='width:{$isize}' type='text' value=\"{$value}\" name=\"{$name}\">";
- $res.= image('images/lists/edit.png', "testCommand_{$name}", _("Test the given command."));
- break;
- case 'dn':
- case 'rdn':
- case 'uri':
- case 'path':
- case 'file':
- case 'string':
- case 'integer':
- $res = "<input style='width:{$isize}' type='text' value=\"{$value}\" name=\"{$name}\">";
- break;
- default: echo $type[0].$name." ";$res = "";
- }
-
- // Check if it is a required value.
- if($mandatory[0] && empty($value)){
- $res.= "<rowClass:entry-error/>";
- }
-
- // Color row in red if the check methods returns false.
- if(!empty($check[0]) && !empty($value)){
- $check = call_user_func(preg_split("/::/", $check[0]),$displayMessage=FALSE, $class[0], $cn[0], $value, $type[0]);
- if(!$check){
- $res.= "<rowClass:entry-error/>";
- }
- }
-
- return($res);
- }
-}
-?>
diff --git a/gosa-core/plugins/addons/configViewer/class_filterProperties.inc b/gosa-core/plugins/addons/configViewer/class_filterProperties.inc
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-
-class filterCONFIGPROPERTIES {
-
- static function query($base, $scope, $filter, $attributes, $category, $objectStorage= "")
- {
- global $config;
-
- $all = $config->configRegistry->getAllProperties();
- $ret = array();
- foreach($all as $property){
-
- $entry = array();
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'cn', $property->getName());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'objectClass', $property->getStatus());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'status', $property->getStatus());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'description', $property->getDescription());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'value', $property->getValue($temporary = TRUE));
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'mandatory', $property->isMandatory());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'default', $property->getDefault());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'defaults', $property->getDefaults());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'check', $property->getCheck());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'class', $property->getClass());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'type', $property->getType());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'migrate', $property->getMigrate());
- $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'group', $property->getGroup());
- $entry['dn'] = $property->getClass().":".$property->getName();
-
- $found =TRUE;
- if(!empty($filter)){
- $tests = preg_split("/§/", $filter);
- foreach($tests as $test){
- list($name,$value) = preg_split("/=/",$test);
- $value =preg_replace("/\*/",'',$value);
- if(empty($value)) $value='.*';
- if(!isset($entry[$name][0]) || !preg_match("/{$value}/",$entry[$name][0])){
- $found = false;
- }
- }
- }
- if($found) $ret[] = $entry;
- }
-
- return($ret);
- }
-
- static function fakeLdapResult($result,$name, $value){
- if(!is_array($value)){
- $value = array($value);
- }
- $value['count'] = count($value);
- $result[] = $name;
- $result[$name] = $value;
- if(!isset($result['count'])){
- $result['count'] =0;
- }
- $result['count'] ++;
- return($result);
- }
-
- static function unifyResult($result)
- {
- $res=array();
- foreach($result as $entry){
- if(!isset($res[$entry['dn']])){
- $res[$entry['dn']]=$entry;
- }
- }
- return(array_values($res));
- }
-}
-
-?>
diff --git a/gosa-core/plugins/addons/configViewer/commandVerifier.tpl b/gosa-core/plugins/addons/configViewer/commandVerifier.tpl
+++ /dev/null
@@ -1,30 +0,0 @@
-<h3>{t}Command verifier{/t}</h3>
-<p>
- {t}Here you can execute commands in the way GOsa does and check the generated results or errors. This can be very usefull especially for the post events (postcreate, postmodify and postremove) due to the fact that these hook are executed silently.{/t}
-</p>
-
-<p>
- <b>
- {t}Please be carefull here, all commands will really be executed on your machine and may break things!{/t}
- </b>
-</p>
-
-<hr>
-
-<p>
- {t}The command to check for{/t}
- <input type='text' name='command' value="{$value}" style='width: 600px;'>
- <button type='submit' name='execute'>{t}Test{/t}</button>
-</p>
-
-{if $output}
- <hr>
- {$output}
-{/if}
-
-<hr>
-
-<div class="plugin-actions">
- <button type='submit' name='commandVerifier_save'>{msgPool type='okButton'}</button>
- <button type='submit' name='commandVerifier_cancel'>{msgPool type='cancelButton'}</button>
-</div>
diff --git a/gosa-core/plugins/addons/configViewer/main.inc b/gosa-core/plugins/addons/configViewer/main.inc
+++ /dev/null
@@ -1,52 +0,0 @@
-<?php
-/*
- This code is part of GOsa (https://gosa.gonicus.de)
- Copyright (C) 2003 Cajus Pollmeier
-
- 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
-*/
-
-
-/* Remove locks created by this plugin
-*/
-if ($remove_lock){
- if(session::is_set('propertyEditor')){
- $config->configRegistry->reload($force=TRUE);
- }
-}
-
-
-/* Remove this plugin from session
- */
-if ( $cleanup ){
- if (session::is_set('propertyEditor')){
- }
- session::un_set('propertyEditor');
-}else{
-
-
- /* Create logview object on demand */
- if (!session::is_set('propertyEditor')){
- session::set('propertyEditor',new propertyEditor($config, get_userinfo()));
- }
- $propertyEditor = session::get('propertyEditor');
-
- /* Execute formular */
- $display= $propertyEditor->execute ();
-
- /* Store changes in session */
- session::set('propertyEditor',$propertyEditor);
-}
-?>
diff --git a/gosa-core/plugins/addons/configViewer/migrate.tpl b/gosa-core/plugins/addons/configViewer/migrate.tpl
+++ /dev/null
@@ -1,18 +0,0 @@
-<div id="mainlist">
- <div class="mainlist-header">
- <p>{t}Property migration assistent{/t} - {t}Migration steps left{/t}: {$leftSteps}</p>
- <div class="mainlist-nav">
- <div style='width:100%; height: 400px; overflow: scroll; padding: 5px;'>
-
- {$content}
-
- </div>
- <hr>
- <div class="plugin-actions">
- <button name='propertyMigrate_save'>{msgPool type='okButton'}</button>
- <button name='propertyMigrate_cancel'>{msgPool type='cancelButton'}</button>
- </div>
- </div>
- </div>
-</div>
-
diff --git a/gosa-core/plugins/addons/configViewer/migration/class_migrateRDN.inc b/gosa-core/plugins/addons/configViewer/migration/class_migrateRDN.inc
+++ /dev/null
@@ -1,212 +0,0 @@
-<?php
-
-
-
-class migrateRDN implements propertyMigration
-{
- protected $property = NULL;
- protected $config = NULL;
- protected $found = array();
- protected $filter ="";
-
- // Additional suffixes or prefixes
- // e.g. for 'faiScriptRDN' (ou=scripts,) moving to new destination lets say
- // to 'ou=FAIscripts,' would break stuff with having 'ou=fai,ou=systems,ou=config'
- // prepended.
- //
- protected $suffix = "";
- protected $prefix = "";
-
- protected $title = "";
- protected $description = "";
-
-
- function __construct($config,$property)
- {
- $this->property = &$property;
- $this->config = &$config;
-
- //Set a dummy title and description
- if(empty($this->title)){
- $this->title = sprintf(_("GOsa migration of property '%s'"), $this->property->getName());
- }
- if(empty($this->description)){
- $this->description = sprintf(_("GOsa has detected objects outside of the configured storage point (%s)."), $this->property->getValue(TRUE));
- }
- }
-
- function getChanges()
- {
- return($this->found);
- }
-
- function checkForIssues()
- {
- $this->found = array();
- $ldap= $this->config->get_ldap_link();
- $ldap->cd($this->config->current['BASE']);
- $ldap2= $this->config->get_ldap_link();
- $ldap2->cd($this->config->current['BASE']);
-
- // Search for possible release deparments/containers - this enables us to
- // SKIP release based objects - we cannot move them right now.
- $releases = array();
- $ldap->search("objectClass=FAIbranch");
- while($attrs = $ldap->fetch()){
- $releases[$attrs['dn']] = $attrs['dn'];
- }
-
- // If the userRDN wasn't empty, then only search for users inside of the old userRDN.
- $initialValue = $this->prefix.$this->property->getValue().$this->suffix;
- $targetValue = $this->prefix.$this->property->getValue(TRUE).$this->suffix;
-
- $dnMatch = "";
- if(!empty($initialValue)){
- foreach(preg_split("/,/", $initialValue) as $rdnPart){
- if(empty($rdnPart)) continue;
- list($namingAttrs, $container) = preg_split("/=/",$rdnPart,2);
- $container = trim($container,', ');
- $dnMatch.= "({$namingAttrs}:dn:={$container})";
- }
- }
-
- // Search for users
- $filter = sprintf($this->filter,$dnMatch);
- $ldap->search($filter,array('dn'));
- $found = FALSE;
- while($attrs = $ldap->fetch()){
- $dn = $attrs['dn'];
- $dnTo = $dn;
-
- // If there intially was no userDN given then just add the new userRDN to the user dns
- // and create the new container objects.
- if(empty($initialValue)){
- list($namingAttrs, $container) = preg_split("/=/",$targetValue,2);
- list($name, $container) = preg_split("/,/",$dn,2);
-
- // Ensure that we handle a valid gosaDepartment container.
- while(!isset($this->config->idepartments[$container])){
-
- // This object is part of a FAI release - we better skip it here.
- if(isset($releases[$container])){
- break;
- }
-
- $container = preg_replace("/^[^,]*+,/","",$container);
- }
-
- // We haven't found a valid gosaDepartment in this dn, so skip.
- if(isset($this->config->idepartments[$container])){
-
- // Queue new containuer to be created.
- if(!preg_match("/^".preg_quote($targetValue,'/i')."/", $container)){
- $dnTo = $name.",".$targetValue.$container;
- if(!$ldap->dn_exists($targetValue.$container)){
- $this->found['add'][$targetValue.$container] = array();
- }
- if($dn != $dnTo){
- $this->found['move'][] = array('from' => $dn, 'to' => $dnTo);
- $found = TRUE;
- }
- }
- }
- }
-
- // If there intially was a userDN given then replace it with the new one.
- if(!empty($initialValue)){
-
- list($name, $container) = preg_split("/,/",$dn,2);
- if(preg_match("/^".preg_quote($initialValue,'/i')."/", $container)){
- $container = preg_replace("/^".preg_quote($initialValue,'/')."/",$targetValue,$container);
-
- // Ensure that we handle a valid gosaDepartment container.
- while(!isset($this->config->idepartments[$container])){
-
- // This object is part of a FAI release - we better skip it here.
- if(isset($releases[$container])){
- break;
- }
-
- $container = preg_replace("/^[^,]*+,/","",$container);
- }
-
- // We haven't found a valid gosaDepartment in this dn, so skip.
- if(isset($this->config->idepartments[$container])){
-
-
- $dnTo = $name.",".$targetValue.$container;
- if(!empty($targetValue) && !$ldap->dn_exists($targetValue.$container)){
- $this->found['add'][$targetValue.$container] = array();
- }
- if($dn != $dnTo){
- $this->found['move'][] = array('from' => $dn, 'to' => $dnTo);
- $found = TRUE;
- }
- }
- }
- }
- }
- return($found);
- }
-
- function execute()
- {
- $str = "<h3>".$this->title."</h3>";
- $str.= $this->description;
- $str.= "<hr>";
- if(count($this->found['add'])) {
- $str.= "<br>"._("Objects that will be added");
- $str.= "<ul>";
- foreach($this->found['add'] as $dn => $attrs){
- $str.= "<li>".$dn."</li>";
- }
- $str.= "</ul>";
- }
- if(count($this->found['move'])) {
- $str.= "<br>"._("Objects that will be moved")."<br>";
- $str.= "<ul style='list-style:none; padding: 15px;'>";
- foreach($this->found['move'] as $id => $data){
- $checked = (!isset($_POST["migrateNow".get_class($this)])) ? 'checked':'';
- $str.= "<li>
-
- <span style='white-space:nowrap;'>
- <input $checked type='checkbox' value='1' name='migrateEntry_{$id}'>";
- $str.= sprintf(_("Moving object '%s' to '%s'"), $data['from'], $data['to'])."</span></li>";
- }
- $str.="</ul>";
- }
- $str.= "<button name='migrateNow".get_class($this)."'>"._("Migrate")."</button>";
- return($str);
- }
-
- function save_object()
- {
- if(isset($_POST["migrateNow".get_class($this)])){
- $ldap = $this->config->get_ldap_link();
- $ldap->cd($this->config->current['BASE']);
-
- // Try to add the new container objects
- foreach($this->found['add'] as $dn => $data){
- $ldap->cd($this->config->current['BASE']);
- $ldap->create_missing_trees(ldap::convert($dn));
- }
-
- // Now move the objects to the new traget
- $tmp = new plugin($this->config,NULL);
- foreach($this->found['move'] as $id => $data){
- if(isset($_POST["migrateEntry_{$id}"])){
- $tmp->move($data['from'], $data['to']);
- }
- }
- $this->checkForIssues();
- }
- }
-
- function check()
- {
- return(array());
- }
-}
-
-
-?>
diff --git a/gosa-core/plugins/addons/configViewer/property-filter.xml b/gosa-core/plugins/addons/configViewer/property-filter.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<filterdef>
-
- <definition>
- <category>all</category>
- <initial>true</initial>
- <default>default</default>
- <scope>one</scope>
- <attribute>dummy</attribute>
- </definition>
-
- <search>
- <tag>default</tag>
- <label>Effective properties</label>
- <query>
- <backend>CONFIGPROPERTIES</backend>
- <filter>status=(ldap|file|modified|removed)§cn=$</filter>
- </query>
- <autocomplete>
- <attribute>status</attribute>
- <frequency>0.5</frequency>
- <characters>3</characters>
- </autocomplete>
- </search>
-
- <search>
- <tag>modified</tag>
- <label>Modified properties</label>
- <query>
- <backend>CONFIGPROPERTIES</backend>
- <filter>status=(modified|removed)§cn=$</filter>
- </query>
- <autocomplete>
- <attribute>status</attribute>
- <frequency>0.5</frequency>
- <characters>3</characters>
- </autocomplete>
- </search>
-
- <search>
- <tag>all</tag>
- <label>All properties</label>
- <query>
- <backend>CONFIGPROPERTIES</backend>
- <filter>cn=$</filter>
- </query>
- <autocomplete>
- <attribute>status</attribute>
- <frequency>0.5</frequency>
- <characters>3</characters>
- </autocomplete>
- </search>
-
- <search>
- <tag>ldap</tag>
- <label>LDAP properties</label>
- <query>
- <backend>CONFIGPROPERTIES</backend>
- <filter>status=(ldap|modified|removed)§cn=$</filter>
- </query>
- <autocomplete>
- <attribute>status</attribute>
- <frequency>0.5</frequency>
- <characters>3</characters>
- </autocomplete>
- </search>
-
- <search>
- <tag>byGroup</tag>
- <label>Search for property groups</label>
- <query>
- <backend>CONFIGPROPERTIES</backend>
- <filter>group=$</filter>
- </query>
- <autocomplete>
- <attribute>status</attribute>
- <frequency>0.5</frequency>
- <characters>3</characters>
- </autocomplete>
- </search>
-
-</filterdef>
diff --git a/gosa-core/plugins/addons/configViewer/property-list.tpl b/gosa-core/plugins/addons/configViewer/property-list.tpl
+++ /dev/null
@@ -1,42 +0,0 @@
-<script language="javascript" src="include/tooltip.js" type="text/javascript"></script>
-
-<div id="mainlist">
-
- <div class="mainlist-header">
- <p>{$HEADLINE} {$SIZELIMIT}</p>
- <div class="mainlist-nav">
- <table summary="{$HEADLINE}">
- <tr>
- <td>{$RELOAD}</td>
- <td class="left-border">{$ACTIONS}</td>
- <td class="left-border">{$FILTER}</td>
- </tr>
- </table>
- </div>
- </div>
- {$LIST}
-</div>
-
-<script type="text/javascript">
- Event.observe(window,"load",function() {
- $$("*").findAll(function(node){
- return node.getAttribute('title');
- }).each(function(node){
- var test = node.title;
- var t = new Tooltip(node,test);
- t.options.delta_x = -150;
- t.options.delta_y = -50;
- node.removeAttribute("title");
- });
- });
-</script>
-
-{if !$is_modified}
-<input type="hidden" name="ignore">
-{/if}
-
-<div class="plugin-actions">
- <button name='saveProperties'>{msgPool type='okButton'}</button>
- <button name='cancelProperties'>{msgPool type='cancelButton'}</button>
-</div>
-
diff --git a/gosa-core/plugins/addons/configViewer/property-list.xml b/gosa-core/plugins/addons/configViewer/property-list.xml
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<list>
- <definition>
- <departmentBrowser>false</departmentBrowser>
- <departmentRootVisible>false</departmentRootVisible>
- <baseMode>false</baseMode>
- <multiSelect>true</multiSelect>
- <template>property-list.tpl</template>
- <module>all</module>
- <label>List of configuration settings</label>
- <defaultSortColumn>1</defaultSortColumn>
-
- <objectType>
- <label>Property not used</label>
- <objectClass>undefined</objectClass>
- <category>all</category>
- <class>all</class>
- <image>images/lists/element.png</image>
- </objectType>
-
- <objectType>
- <label>Property will be restored</label>
- <objectClass>removed</objectClass>
- <category>all</category>
- <class>all</class>
- <image>images/lists/trash.png</image>
- </objectType>
-
- <objectType>
- <label>Modified property</label>
- <objectClass>modified</objectClass>
- <category>all</category>
- <class>all</class>
- <image>plugins/propertyEditor/images/ldap.png[new]</image>
- </objectType>
-
- <objectType>
- <label>Property configured in ldap</label>
- <objectClass>ldap</objectClass>
- <category>all</category>
- <class>all</class>
- <image>plugins/propertyEditor/images/ldap.png</image>
- </objectType>
-
- <objectType>
- <label>Property configured in config file</label>
- <objectClass>file</objectClass>
- <category>all</category>
- <class>all</class>
- <image>plugins/propertyEditor/images/file.png</image>
- </objectType>
-
- </definition>
-
- <table>
- <layout>|20px;c|||||60px;r|</layout>
-
- <column>
- <value>%{filter:objectType(dn,objectClass)}</value>
- </column>
-
- <column>
- <label>Group</label>
- <sortAttribute>group</sortAttribute>
- <sortType>string</sortType>
- <value>%{filter:propertyGroup(group,description)}</value>
- <export>true</export>
- </column>
-
- <column>
- <label>Class</label>
- <sortAttribute>group</sortAttribute>
- <sortType>string</sortType>
- <value>%{filter:propertyClass(class,description)}</value>
- <export>true</export>
- </column>
-
- <column>
- <label>Name</label>
- <sortAttribute>cn</sortAttribute>
- <sortType>string</sortType>
- <value>%{filter:propertyName(class,cn,description,mandatory)}</value>
- <export>true</export>
- </column>
-
- <column>
- <label>Value</label>
- <sortAttribute>value</sortAttribute>
- <sortType>string</sortType>
- <value>%{filter:propertyValue(class,cn,value,type,default,defaults,check,mandatory)}</value>
- <export>true</export>
- </column>
-
- <column>
- <label>Actions</label>
- <value>%{filter:actions(dn,row,objectClass)}</value>
- </column>
-
- </table>
-
- <actionmenu>
-
- <action>
- <name>remove</name>
- <type>entry</type>
- <image>images/lists/trash.png</image>
- <label>Remove</label>
- </action>
-
- <action>
- <type>exporter</type>
- </action>
-
- </actionmenu>
-
- <actiontriggers snapshot="false" copypaste="false">
-
- <action>
- <name>remove</name>
- <type>entry</type>
- <objectclass>ldap</objectclass>
- <image>images/lists/trash.png</image>
- <label>Restore to default</label>
- </action>
-
- </actiontriggers>
-
-</list>
diff --git a/gosa-core/plugins/addons/propertyEditor/class_commandVerifier.inc b/gosa-core/plugins/addons/propertyEditor/class_commandVerifier.inc
--- /dev/null
@@ -0,0 +1,77 @@
+<?php
+class commandVerifier
+{
+ private $property = NULL;
+ private $config = NULL;
+ private $command = "";
+
+ function __construct($config, $property)
+ {
+ $this->config = &$config;
+ $this->property = &$property;
+ $this->command = $this->property->getValue(TRUE);
+ }
+
+ function execute()
+ {
+ $smarty = get_smarty();
+ $output= "";
+
+ if(isset($_POST['execute'])){
+
+
+ $descriptorSpec = array(0 => array("pipe", "r"),
+ 1 => array('pipe', 'w'),
+ 2 => array('pipe', 'w'));
+ $process = proc_open($this->command, $descriptorSpec, $pipes);
+ $txOff = 0; $txLen = strlen($stdin);
+
+ $stdout = ''; $stdoutDone = FALSE;
+ $stderr = ''; $stderrDone = FALSE;
+ stream_set_blocking($pipes[0], 0); // Make stdin/stdout/stderr non-blocking
+ stream_set_blocking($pipes[1], 0);
+ stream_set_blocking($pipes[2], 0);
+ if ($txLen == 0) fclose($pipes[0]);
+ while (TRUE) {
+ $rx = array(); // The program's stdout/stderr
+ if (!$stdoutDone) $rx[] = $pipes[1];
+ if (!$stderrDone) $rx[] = $pipes[2];
+ foreach ($rx as $r) {
+ if ($r == $pipes[1]) {
+ $stdout .= fread($pipes[1], 8192);
+ if (feof($pipes[1])) { fclose($pipes[1]); $stdoutDone = TRUE; }
+ } else if ($r == $pipes[2]) {
+ $stderr .= fread($pipes[2], 8192);
+ if (feof($pipes[2])) { fclose($pipes[2]); $stderrDone = TRUE; }
+ }
+ }
+ if (!is_resource($process)) break;
+ if ($txOff >= $txLen && $stdoutDone && $stderrDone) break;
+ }
+ $code = proc_close($process);
+
+ if(!empty($stdout)) $stdout = "<pre>".htmlentities($stdout,ENT_COMPAT,'UTF-8')."</pre>";
+ if(!empty($stderr)) $stderr = "<pre>".htmlentities($stderr,ENT_COMPAT,'UTF-8')."</pre>";
+ $output = "
+ <table summary='"._("Results")."'>
+ <tr><td><b>Result:</b></td><td>$stdout</td></tr>
+ <tr><td><b>Error:</b></td><td>$stderr</td></tr>
+ <tr><td><b>Return code:</b></td><td>$code</td></tr>
+ </table>";
+ }
+ $smarty->assign('value', htmlentities($this->command,ENT_COMPAT,'UTF-8'));
+ $smarty->assign('output', $output);
+ return($smarty->fetch(get_template_path('commandVerifier.tpl', 'TRUE')));
+ }
+
+ function save_object()
+ {
+ if(isset($_POST['command'])) $this->command = get_post('command');
+ }
+
+ function save()
+ {
+ $this->property->setValue($this->command);
+ }
+}
+?>
diff --git a/gosa-core/plugins/addons/propertyEditor/class_configViewer.inc b/gosa-core/plugins/addons/propertyEditor/class_configViewer.inc
--- /dev/null
@@ -0,0 +1,272 @@
+<?php
+
+
+class propertyEditor extends management
+{
+ var $plHeadline= "Preferences";
+ var $plDescription= "Configure global and special GOsa settings like hooks and plugin parameters";
+ var $plIcon = "plugins/propertyEditor/images/plugin.png";
+
+ var $toBeMigrated = array();
+
+ function __construct($config,$ui)
+ {
+ $this->config = $config;
+ $this->ui = $ui;
+
+ // 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("property-filter.xml", true));
+ $filter->setObjectStorage($this->storagePoints);
+ }
+ $this->setFilter($filter);
+
+ // Build headpage
+ $headpage = new listing(get_template_path("property-list.xml", true));
+ $headpage->registerElementFilter("propertyName", "propertyEditor::propertyName");
+ $headpage->registerElementFilter("propertyGroup", "propertyEditor::propertyGroup");
+ $headpage->registerElementFilter("propertyClass", "propertyEditor::propertyClass");
+ $headpage->registerElementFilter("propertyValue", "propertyEditor::propertyValue");
+ $headpage->setFilter($filter);
+ parent::__construct($config, $ui, "property", $headpage);
+
+ $this->registerAction("saveProperties","saveProperties");
+ $this->registerAction("cancelProperties","cancelProperties");
+ }
+
+
+ function execute()
+ {
+ // Walk trough all properties and check if there posts for us.
+ $all = $this->config->configRegistry->getAllProperties();
+ foreach($all as $prop){
+ $post = "{$prop->getClass()}:{$prop->getName()}";
+ if(isset($_POST[$post]) && $prop->getStatus() != 'removed'){
+ $prop->setValue(get_post($post));
+ }
+
+ // Open the command verify dialog
+ if(isset($_POST["testCommand_{$post}"])){
+ $this->dialogObject = new commandVerifier($this->config,$prop);
+ }
+ }
+ if(isset($_POST['commandVerifier_save'])){
+ $this->dialogObject->save();
+ $this->closeDialogs();
+ }
+ if(isset($_POST['commandVerifier_cancel'])){
+ $this->closeDialogs();
+ }
+
+
+ // Execute registered management event listeners.
+ $this->handleActions($this->detectPostActions());
+
+ // Handle properties that have to be migrated
+ if(isset($_POST['propertyMigrate_cancel']) && count($this->toBeMigrated)){
+ unset($this->toBeMigrated[0]);
+ $this->toBeMigrated = array_values($this->toBeMigrated);
+ }
+ if(isset($_POST['propertyMigrate_save']) && count($this->toBeMigrated)){
+ $first = $this->toBeMigrated[0]->getMigrationClass();
+ $first->save_object();
+ $msgs = $first->check();
+ if(!count($msgs)){
+ $this->toBeMigrated[0]->save();
+ unset($this->toBeMigrated[0]);
+ $this->toBeMigrated = array_values($this->toBeMigrated);
+
+ // Nothing to migrate and everything is fine, reload the list now.
+ if(!count($this->toBeMigrated)){
+ $this->config->configRegistry->reload($force=TRUE);
+ }
+ }
+ }
+ if(count($this->toBeMigrated)){
+ $first = $this->toBeMigrated[0]->getMigrationClass();
+ $first->save_object();
+
+ // We've no problems with this property anymore.
+ while($first instanceOf propertyMigration && !$first->checkForIssues()){
+ $this->toBeMigrated[0]->save();
+ unset($this->toBeMigrated[0]);
+ $this->toBeMigrated = array_values($this->toBeMigrated);
+ if(count($this->toBeMigrated)){
+ $first = $this->toBeMigrated[0]->getMigrationClass();
+ }else{
+ $first = NULL;
+
+ // Nothing to migrate and everything is fine, reload the list now.
+ if(!count($this->toBeMigrated)){
+ $this->config->configRegistry->reload($force=TRUE);
+ }
+ }
+ }
+
+ if($first){
+ $content = $first->execute();
+ $smarty = get_smarty();
+ $smarty->assign('content', $content);
+ $smarty->assign('leftSteps', count($this->toBeMigrated));
+ return($smarty->fetch(get_template_path('migrate.tpl',TRUE)));
+ }
+ }
+
+ return(management::execute());
+ }
+
+ function renderList()
+ {
+ // Walk trough all properties and check if we have modified something
+ $all = $this->config->configRegistry->getAllProperties();
+ foreach($all as $prop){
+ $modified = in_array($prop->getStatus(),array('modified','removed'));
+ if($modified) break;
+ }
+
+ $smarty = get_smarty();
+ $smarty->assign('is_modified', $modified);
+ return(management::renderList());
+ }
+
+
+ function cancelProperties()
+ {
+ $this->config->configRegistry->reload($force=TRUE);
+ }
+
+ function saveProperties()
+ {
+ // Check if we've misconfigured properties and skip saving in this case.
+ $all = $this->config->configRegistry->getAllProperties();
+ $valid = TRUE;
+ foreach($all as $prop){
+ $valid &= $prop->check();
+ }
+
+ // Now save the properties.
+ if($valid){
+ $this->toBeMigrated = $this->config->configRegistry->saveChanges();
+
+ // Nothing to migrate and everything is fine, reload the list now.
+ if(!count($this->toBeMigrated)){
+ $this->config->configRegistry->reload($force=TRUE);
+ }
+ }
+ }
+
+ function detectPostActions()
+ {
+ $action = management::detectPostActions();
+ if(isset($_POST['saveProperties'])) $action['action'] = 'saveProperties';
+ if(isset($_POST['cancelProperties'])) $action['action'] = 'cancelProperties';
+ return($action);
+ }
+
+ protected function removeEntryRequested($action="",$target=array(),$all=array())
+ {
+ foreach($target as $dn){
+ list($class,$name) = preg_split("/:/", $dn);
+ if($this->config->configRegistry->propertyExists($class,$name)){
+ $prop = $this->config->configRegistry->getProperty($class,$name);
+ $prop->restoreDefault();
+ }
+ }
+ }
+
+ static function propertyGroup($group, $description = array())
+ {
+ return($group[0]);
+ }
+ static function propertyClass($class, $description = array())
+ {
+ global $config;
+ if(isset($config->configRegistry->classToName[$class[0]])){
+ $class = $config->configRegistry->classToName[$class[0]];
+ }else{
+ $class = $class[0];
+ }
+ return($class);
+ }
+ static function propertyName($class,$cn, $description,$mandatory)
+ {
+ $id = "{$class[0]}_{$cn[0]}";
+
+ $title = _("No description");
+ if(isset($description[0])) $title = htmlentities($description[0],ENT_COMPAT, 'UTF-8');
+ $title = preg_replace("/\n/", "<br>", $title);
+ $tooltip = "<div id='tooltip_{$id}' class='tooltip' style='display:none'>".$title."</div>";
+
+ $must = ($mandatory[0]) ? "<span class='required'>*</span>" : "";
+
+ return($tooltip."<span title='tooltip_{$id}'>{$cn[0]}{$must}</span>");
+ }
+ static function propertyValue($class,$cn,$value,$type,$default,$defaults,$check,$mandatory)
+ {
+ $ssize = "208px";
+ $isize = "200px";
+ $name = "{$class[0]}:{$cn[0]}";
+ $value = htmlentities($value[0],ENT_QUOTES ,'UTF-8');
+
+ // Add slashes to keep escaped values escaped after passing them to smarty.
+ $value = addslashes($value);
+
+ switch($type[0]){
+ case 'bool':
+ $res = "<select size=1 name=\"{$name}\" style='width:{$ssize}'>";
+ $false = (preg_match('/true/i', $value)) ? '' : "selected";
+ $true = (preg_match('/true/i', $value)) ? "selected" : '';
+ $res.= "<option {$false} value='false'>"._("FALSE")."</option>";
+ $res.= "<option {$true} value='true'>"._("TRUE")."</option>";
+ $res.= "</select>";
+ case 'switch':
+ if(!empty($defaults[0])){
+ $data = call_user_func(preg_split("/::/", $defaults[0]), $class[0],$cn[0],$value, $type[0]);
+ if(is_array($data)){
+ $res = "<select size=1 name=\"{$name}\" style='width:{$ssize}'>";
+ foreach($data as $oValue => $oDesc){
+ if($oValue == $value){
+ $res.="<option selected value=\"{$oValue}\">{$oDesc}</option>\n";
+ }else{
+ $res.="<option value=\"{$oValue}\">{$oDesc}</option>\n";
+ }
+ }
+ $res.= "</select>";
+ }
+ }
+ break;
+ case 'command':
+ $res = "<input style='width:{$isize}' type='text' value=\"{$value}\" name=\"{$name}\">";
+ $res.= image('images/lists/edit.png', "testCommand_{$name}", _("Test the given command."));
+ break;
+ case 'dn':
+ case 'rdn':
+ case 'uri':
+ case 'path':
+ case 'file':
+ case 'string':
+ case 'integer':
+ $res = "<input style='width:{$isize}' type='text' value=\"{$value}\" name=\"{$name}\">";
+ break;
+ default: echo $type[0].$name." ";$res = "";
+ }
+
+ // Check if it is a required value.
+ if($mandatory[0] && empty($value)){
+ $res.= "<rowClass:entry-error/>";
+ }
+
+ // Color row in red if the check methods returns false.
+ if(!empty($check[0]) && !empty($value)){
+ $check = call_user_func(preg_split("/::/", $check[0]),$displayMessage=FALSE, $class[0], $cn[0], $value, $type[0]);
+ if(!$check){
+ $res.= "<rowClass:entry-error/>";
+ }
+ }
+
+ return($res);
+ }
+}
+?>
diff --git a/gosa-core/plugins/addons/propertyEditor/class_filterProperties.inc b/gosa-core/plugins/addons/propertyEditor/class_filterProperties.inc
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+
+class filterCONFIGPROPERTIES {
+
+ static function query($base, $scope, $filter, $attributes, $category, $objectStorage= "")
+ {
+ global $config;
+
+ $all = $config->configRegistry->getAllProperties();
+ $ret = array();
+ foreach($all as $property){
+
+ $entry = array();
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'cn', $property->getName());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'objectClass', $property->getStatus());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'status', $property->getStatus());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'description', $property->getDescription());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'value', $property->getValue($temporary = TRUE));
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'mandatory', $property->isMandatory());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'default', $property->getDefault());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'defaults', $property->getDefaults());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'check', $property->getCheck());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'class', $property->getClass());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'type', $property->getType());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'migrate', $property->getMigrate());
+ $entry = filterCONFIGPROPERTIES::fakeLdapResult($entry, 'group', $property->getGroup());
+ $entry['dn'] = $property->getClass().":".$property->getName();
+
+ $found =TRUE;
+ if(!empty($filter)){
+ $tests = preg_split("/§/", $filter);
+ foreach($tests as $test){
+ list($name,$value) = preg_split("/=/",$test);
+ $value =preg_replace("/\*/",'',$value);
+ if(empty($value)) $value='.*';
+ if(!isset($entry[$name][0]) || !preg_match("/{$value}/",$entry[$name][0])){
+ $found = false;
+ }
+ }
+ }
+ if($found) $ret[] = $entry;
+ }
+
+ return($ret);
+ }
+
+ static function fakeLdapResult($result,$name, $value){
+ if(!is_array($value)){
+ $value = array($value);
+ }
+ $value['count'] = count($value);
+ $result[] = $name;
+ $result[$name] = $value;
+ if(!isset($result['count'])){
+ $result['count'] =0;
+ }
+ $result['count'] ++;
+ return($result);
+ }
+
+ static function unifyResult($result)
+ {
+ $res=array();
+ foreach($result as $entry){
+ if(!isset($res[$entry['dn']])){
+ $res[$entry['dn']]=$entry;
+ }
+ }
+ return(array_values($res));
+ }
+}
+
+?>
diff --git a/gosa-core/plugins/addons/propertyEditor/commandVerifier.tpl b/gosa-core/plugins/addons/propertyEditor/commandVerifier.tpl
--- /dev/null
@@ -0,0 +1,30 @@
+<h3>{t}Command verifier{/t}</h3>
+<p>
+ {t}Here you can execute commands in the way GOsa does and check the generated results or errors. This can be very usefull especially for the post events (postcreate, postmodify and postremove) due to the fact that these hook are executed silently.{/t}
+</p>
+
+<p>
+ <b>
+ {t}Please be carefull here, all commands will really be executed on your machine and may break things!{/t}
+ </b>
+</p>
+
+<hr>
+
+<p>
+ {t}The command to check for{/t}
+ <input type='text' name='command' value="{$value}" style='width: 600px;'>
+ <button type='submit' name='execute'>{t}Test{/t}</button>
+</p>
+
+{if $output}
+ <hr>
+ {$output}
+{/if}
+
+<hr>
+
+<div class="plugin-actions">
+ <button type='submit' name='commandVerifier_save'>{msgPool type='okButton'}</button>
+ <button type='submit' name='commandVerifier_cancel'>{msgPool type='cancelButton'}</button>
+</div>
diff --git a/gosa-core/plugins/addons/propertyEditor/main.inc b/gosa-core/plugins/addons/propertyEditor/main.inc
--- /dev/null
@@ -0,0 +1,52 @@
+<?php
+/*
+ This code is part of GOsa (https://gosa.gonicus.de)
+ Copyright (C) 2003 Cajus Pollmeier
+
+ 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
+*/
+
+
+/* Remove locks created by this plugin
+*/
+if ($remove_lock){
+ if(session::is_set('propertyEditor')){
+ $config->configRegistry->reload($force=TRUE);
+ }
+}
+
+
+/* Remove this plugin from session
+ */
+if ( $cleanup ){
+ if (session::is_set('propertyEditor')){
+ }
+ session::un_set('propertyEditor');
+}else{
+
+
+ /* Create logview object on demand */
+ if (!session::is_set('propertyEditor')){
+ session::set('propertyEditor',new propertyEditor($config, get_userinfo()));
+ }
+ $propertyEditor = session::get('propertyEditor');
+
+ /* Execute formular */
+ $display= $propertyEditor->execute ();
+
+ /* Store changes in session */
+ session::set('propertyEditor',$propertyEditor);
+}
+?>
diff --git a/gosa-core/plugins/addons/propertyEditor/migrate.tpl b/gosa-core/plugins/addons/propertyEditor/migrate.tpl
--- /dev/null
@@ -0,0 +1,18 @@
+<div id="mainlist">
+ <div class="mainlist-header">
+ <p>{t}Property migration assistent{/t} - {t}Migration steps left{/t}: {$leftSteps}</p>
+ <div class="mainlist-nav">
+ <div style='width:100%; height: 400px; overflow: scroll; padding: 5px;'>
+
+ {$content}
+
+ </div>
+ <hr>
+ <div class="plugin-actions">
+ <button name='propertyMigrate_save'>{msgPool type='okButton'}</button>
+ <button name='propertyMigrate_cancel'>{msgPool type='cancelButton'}</button>
+ </div>
+ </div>
+ </div>
+</div>
+
diff --git a/gosa-core/plugins/addons/propertyEditor/migration/class_migrateRDN.inc b/gosa-core/plugins/addons/propertyEditor/migration/class_migrateRDN.inc
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+
+
+
+class migrateRDN implements propertyMigration
+{
+ protected $property = NULL;
+ protected $config = NULL;
+ protected $found = array();
+ protected $filter ="";
+
+ // Additional suffixes or prefixes
+ // e.g. for 'faiScriptRDN' (ou=scripts,) moving to new destination lets say
+ // to 'ou=FAIscripts,' would break stuff with having 'ou=fai,ou=systems,ou=config'
+ // prepended.
+ //
+ protected $suffix = "";
+ protected $prefix = "";
+
+ protected $title = "";
+ protected $description = "";
+
+
+ function __construct($config,$property)
+ {
+ $this->property = &$property;
+ $this->config = &$config;
+
+ //Set a dummy title and description
+ if(empty($this->title)){
+ $this->title = sprintf(_("GOsa migration of property '%s'"), $this->property->getName());
+ }
+ if(empty($this->description)){
+ $this->description = sprintf(_("GOsa has detected objects outside of the configured storage point (%s)."), $this->property->getValue(TRUE));
+ }
+ }
+
+ function getChanges()
+ {
+ return($this->found);
+ }
+
+ function checkForIssues()
+ {
+ $this->found = array();
+ $ldap= $this->config->get_ldap_link();
+ $ldap->cd($this->config->current['BASE']);
+ $ldap2= $this->config->get_ldap_link();
+ $ldap2->cd($this->config->current['BASE']);
+
+ // Search for possible release deparments/containers - this enables us to
+ // SKIP release based objects - we cannot move them right now.
+ $releases = array();
+ $ldap->search("objectClass=FAIbranch");
+ while($attrs = $ldap->fetch()){
+ $releases[$attrs['dn']] = $attrs['dn'];
+ }
+
+ // If the userRDN wasn't empty, then only search for users inside of the old userRDN.
+ $initialValue = $this->prefix.$this->property->getValue().$this->suffix;
+ $targetValue = $this->prefix.$this->property->getValue(TRUE).$this->suffix;
+
+ $dnMatch = "";
+ if(!empty($initialValue)){
+ foreach(preg_split("/,/", $initialValue) as $rdnPart){
+ if(empty($rdnPart)) continue;
+ list($namingAttrs, $container) = preg_split("/=/",$rdnPart,2);
+ $container = trim($container,', ');
+ $dnMatch.= "({$namingAttrs}:dn:={$container})";
+ }
+ }
+
+ // Search for users
+ $filter = sprintf($this->filter,$dnMatch);
+ $ldap->search($filter,array('dn'));
+ $found = FALSE;
+ while($attrs = $ldap->fetch()){
+ $dn = $attrs['dn'];
+ $dnTo = $dn;
+
+ // If there intially was no userDN given then just add the new userRDN to the user dns
+ // and create the new container objects.
+ if(empty($initialValue)){
+ list($namingAttrs, $container) = preg_split("/=/",$targetValue,2);
+ list($name, $container) = preg_split("/,/",$dn,2);
+
+ // Ensure that we handle a valid gosaDepartment container.
+ while(!isset($this->config->idepartments[$container])){
+
+ // This object is part of a FAI release - we better skip it here.
+ if(isset($releases[$container])){
+ break;
+ }
+
+ $container = preg_replace("/^[^,]*+,/","",$container);
+ }
+
+ // We haven't found a valid gosaDepartment in this dn, so skip.
+ if(isset($this->config->idepartments[$container])){
+
+ // Queue new containuer to be created.
+ if(!preg_match("/^".preg_quote($targetValue,'/i')."/", $container)){
+ $dnTo = $name.",".$targetValue.$container;
+ if(!$ldap->dn_exists($targetValue.$container)){
+ $this->found['add'][$targetValue.$container] = array();
+ }
+ if($dn != $dnTo){
+ $this->found['move'][] = array('from' => $dn, 'to' => $dnTo);
+ $found = TRUE;
+ }
+ }
+ }
+ }
+
+ // If there intially was a userDN given then replace it with the new one.
+ if(!empty($initialValue)){
+
+ list($name, $container) = preg_split("/,/",$dn,2);
+ if(preg_match("/^".preg_quote($initialValue,'/i')."/", $container)){
+ $container = preg_replace("/^".preg_quote($initialValue,'/')."/",$targetValue,$container);
+
+ // Ensure that we handle a valid gosaDepartment container.
+ while(!isset($this->config->idepartments[$container])){
+
+ // This object is part of a FAI release - we better skip it here.
+ if(isset($releases[$container])){
+ break;
+ }
+
+ $container = preg_replace("/^[^,]*+,/","",$container);
+ }
+
+ // We haven't found a valid gosaDepartment in this dn, so skip.
+ if(isset($this->config->idepartments[$container])){
+
+
+ $dnTo = $name.",".$targetValue.$container;
+ if(!empty($targetValue) && !$ldap->dn_exists($targetValue.$container)){
+ $this->found['add'][$targetValue.$container] = array();
+ }
+ if($dn != $dnTo){
+ $this->found['move'][] = array('from' => $dn, 'to' => $dnTo);
+ $found = TRUE;
+ }
+ }
+ }
+ }
+ }
+ return($found);
+ }
+
+ function execute()
+ {
+ $str = "<h3>".$this->title."</h3>";
+ $str.= $this->description;
+ $str.= "<hr>";
+ if(count($this->found['add'])) {
+ $str.= "<br>"._("Objects that will be added");
+ $str.= "<ul>";
+ foreach($this->found['add'] as $dn => $attrs){
+ $str.= "<li>".$dn."</li>";
+ }
+ $str.= "</ul>";
+ }
+ if(count($this->found['move'])) {
+ $str.= "<br>"._("Objects that will be moved")."<br>";
+ $str.= "<ul style='list-style:none; padding: 15px;'>";
+ foreach($this->found['move'] as $id => $data){
+ $checked = (!isset($_POST["migrateNow".get_class($this)])) ? 'checked':'';
+ $str.= "<li>
+
+ <span style='white-space:nowrap;'>
+ <input $checked type='checkbox' value='1' name='migrateEntry_{$id}'>";
+ $str.= sprintf(_("Moving object '%s' to '%s'"), $data['from'], $data['to'])."</span></li>";
+ }
+ $str.="</ul>";
+ }
+ $str.= "<button name='migrateNow".get_class($this)."'>"._("Migrate")."</button>";
+ return($str);
+ }
+
+ function save_object()
+ {
+ if(isset($_POST["migrateNow".get_class($this)])){
+ $ldap = $this->config->get_ldap_link();
+ $ldap->cd($this->config->current['BASE']);
+
+ // Try to add the new container objects
+ foreach($this->found['add'] as $dn => $data){
+ $ldap->cd($this->config->current['BASE']);
+ $ldap->create_missing_trees(ldap::convert($dn));
+ }
+
+ // Now move the objects to the new traget
+ $tmp = new plugin($this->config,NULL);
+ foreach($this->found['move'] as $id => $data){
+ if(isset($_POST["migrateEntry_{$id}"])){
+ $tmp->move($data['from'], $data['to']);
+ }
+ }
+ $this->checkForIssues();
+ }
+ }
+
+ function check()
+ {
+ return(array());
+ }
+}
+
+
+?>
diff --git a/gosa-core/plugins/addons/propertyEditor/property-filter.xml b/gosa-core/plugins/addons/propertyEditor/property-filter.xml
--- /dev/null
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<filterdef>
+
+ <definition>
+ <category>all</category>
+ <initial>true</initial>
+ <default>default</default>
+ <scope>one</scope>
+ <attribute>dummy</attribute>
+ </definition>
+
+ <search>
+ <tag>default</tag>
+ <label>Effective properties</label>
+ <query>
+ <backend>CONFIGPROPERTIES</backend>
+ <filter>status=(ldap|file|modified|removed)§cn=$</filter>
+ </query>
+ <autocomplete>
+ <attribute>status</attribute>
+ <frequency>0.5</frequency>
+ <characters>3</characters>
+ </autocomplete>
+ </search>
+
+ <search>
+ <tag>modified</tag>
+ <label>Modified properties</label>
+ <query>
+ <backend>CONFIGPROPERTIES</backend>
+ <filter>status=(modified|removed)§cn=$</filter>
+ </query>
+ <autocomplete>
+ <attribute>status</attribute>
+ <frequency>0.5</frequency>
+ <characters>3</characters>
+ </autocomplete>
+ </search>
+
+ <search>
+ <tag>all</tag>
+ <label>All properties</label>
+ <query>
+ <backend>CONFIGPROPERTIES</backend>
+ <filter>cn=$</filter>
+ </query>
+ <autocomplete>
+ <attribute>status</attribute>
+ <frequency>0.5</frequency>
+ <characters>3</characters>
+ </autocomplete>
+ </search>
+
+ <search>
+ <tag>ldap</tag>
+ <label>LDAP properties</label>
+ <query>
+ <backend>CONFIGPROPERTIES</backend>
+ <filter>status=(ldap|modified|removed)§cn=$</filter>
+ </query>
+ <autocomplete>
+ <attribute>status</attribute>
+ <frequency>0.5</frequency>
+ <characters>3</characters>
+ </autocomplete>
+ </search>
+
+ <search>
+ <tag>byGroup</tag>
+ <label>Search for property groups</label>
+ <query>
+ <backend>CONFIGPROPERTIES</backend>
+ <filter>group=$</filter>
+ </query>
+ <autocomplete>
+ <attribute>status</attribute>
+ <frequency>0.5</frequency>
+ <characters>3</characters>
+ </autocomplete>
+ </search>
+
+</filterdef>
diff --git a/gosa-core/plugins/addons/propertyEditor/property-list.tpl b/gosa-core/plugins/addons/propertyEditor/property-list.tpl
--- /dev/null
@@ -0,0 +1,42 @@
+<script language="javascript" src="include/tooltip.js" type="text/javascript"></script>
+
+<div id="mainlist">
+
+ <div class="mainlist-header">
+ <p>{$HEADLINE} {$SIZELIMIT}</p>
+ <div class="mainlist-nav">
+ <table summary="{$HEADLINE}">
+ <tr>
+ <td>{$RELOAD}</td>
+ <td class="left-border">{$ACTIONS}</td>
+ <td class="left-border">{$FILTER}</td>
+ </tr>
+ </table>
+ </div>
+ </div>
+ {$LIST}
+</div>
+
+<script type="text/javascript">
+ Event.observe(window,"load",function() {
+ $$("*").findAll(function(node){
+ return node.getAttribute('title');
+ }).each(function(node){
+ var test = node.title;
+ var t = new Tooltip(node,test);
+ t.options.delta_x = -150;
+ t.options.delta_y = -50;
+ node.removeAttribute("title");
+ });
+ });
+</script>
+
+{if !$is_modified}
+<input type="hidden" name="ignore">
+{/if}
+
+<div class="plugin-actions">
+ <button name='saveProperties'>{msgPool type='okButton'}</button>
+ <button name='cancelProperties'>{msgPool type='cancelButton'}</button>
+</div>
+
diff --git a/gosa-core/plugins/addons/propertyEditor/property-list.xml b/gosa-core/plugins/addons/propertyEditor/property-list.xml
--- /dev/null
@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<list>
+ <definition>
+ <departmentBrowser>false</departmentBrowser>
+ <departmentRootVisible>false</departmentRootVisible>
+ <baseMode>false</baseMode>
+ <multiSelect>true</multiSelect>
+ <template>property-list.tpl</template>
+ <module>all</module>
+ <label>List of configuration settings</label>
+ <defaultSortColumn>1</defaultSortColumn>
+
+ <objectType>
+ <label>Property not used</label>
+ <objectClass>undefined</objectClass>
+ <category>all</category>
+ <class>all</class>
+ <image>images/lists/element.png</image>
+ </objectType>
+
+ <objectType>
+ <label>Property will be restored</label>
+ <objectClass>removed</objectClass>
+ <category>all</category>
+ <class>all</class>
+ <image>images/lists/trash.png</image>
+ </objectType>
+
+ <objectType>
+ <label>Modified property</label>
+ <objectClass>modified</objectClass>
+ <category>all</category>
+ <class>all</class>
+ <image>plugins/propertyEditor/images/ldap.png[new]</image>
+ </objectType>
+
+ <objectType>
+ <label>Property configured in ldap</label>
+ <objectClass>ldap</objectClass>
+ <category>all</category>
+ <class>all</class>
+ <image>plugins/propertyEditor/images/ldap.png</image>
+ </objectType>
+
+ <objectType>
+ <label>Property configured in config file</label>
+ <objectClass>file</objectClass>
+ <category>all</category>
+ <class>all</class>
+ <image>plugins/propertyEditor/images/file.png</image>
+ </objectType>
+
+ </definition>
+
+ <table>
+ <layout>|20px;c|||||60px;r|</layout>
+
+ <column>
+ <value>%{filter:objectType(dn,objectClass)}</value>
+ </column>
+
+ <column>
+ <label>Group</label>
+ <sortAttribute>group</sortAttribute>
+ <sortType>string</sortType>
+ <value>%{filter:propertyGroup(group,description)}</value>
+ <export>true</export>
+ </column>
+
+ <column>
+ <label>Class</label>
+ <sortAttribute>group</sortAttribute>
+ <sortType>string</sortType>
+ <value>%{filter:propertyClass(class,description)}</value>
+ <export>true</export>
+ </column>
+
+ <column>
+ <label>Name</label>
+ <sortAttribute>cn</sortAttribute>
+ <sortType>string</sortType>
+ <value>%{filter:propertyName(class,cn,description,mandatory)}</value>
+ <export>true</export>
+ </column>
+
+ <column>
+ <label>Value</label>
+ <sortAttribute>value</sortAttribute>
+ <sortType>string</sortType>
+ <value>%{filter:propertyValue(class,cn,value,type,default,defaults,check,mandatory)}</value>
+ <export>true</export>
+ </column>
+
+ <column>
+ <label>Actions</label>
+ <value>%{filter:actions(dn,row,objectClass)}</value>
+ </column>
+
+ </table>
+
+ <actionmenu>
+
+ <action>
+ <name>remove</name>
+ <type>entry</type>
+ <image>images/lists/trash.png</image>
+ <label>Remove</label>
+ </action>
+
+ <action>
+ <type>exporter</type>
+ </action>
+
+ </actionmenu>
+
+ <actiontriggers snapshot="false" copypaste="false">
+
+ <action>
+ <name>remove</name>
+ <type>entry</type>
+ <objectclass>ldap</objectclass>
+ <image>images/lists/trash.png</image>
+ <label>Restore to default</label>
+ </action>
+
+ </actiontriggers>
+
+</list>