summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.idea/codeStyleSettings.xml11
-rw-r--r--apis/update.inc.php4
-rw-r--r--inc/defaultdata.inc.php4
-rw-r--r--inc/module.inc.php17
-rw-r--r--inc/util.inc.php13
-rw-r--r--modules-available/baseconfig-bwlp/baseconfig/categories.json8
-rw-r--r--modules-available/baseconfig-bwlp/baseconfig/settings.json122
-rw-r--r--modules-available/baseconfig/hooks/translation.inc.php16
-rw-r--r--modules-available/baseconfig/inc/baseconfigutil.inc.php42
-rw-r--r--modules-available/baseconfig/lang/de/config-variable-categories.json12
-rw-r--r--modules-available/baseconfig/lang/de/template-tags.json11
-rw-r--r--modules-available/baseconfig/lang/en/config-variable-categories.json13
-rw-r--r--modules-available/baseconfig/lang/en/template-tags.json4
-rw-r--r--modules-available/baseconfig/lang/pt/config-variable-categories.json10
-rw-r--r--modules-available/baseconfig/lang/pt/template-tags.json1
-rw-r--r--modules-available/baseconfig/page.inc.php229
-rw-r--r--modules-available/baseconfig/templates/_page.html158
-rw-r--r--modules-available/internetaccess/lang/de/messages.json4
-rw-r--r--modules-available/internetaccess/lang/en/messages.json4
-rw-r--r--modules-available/internetaccess/lang/pt/messages.json4
-rw-r--r--modules-available/locations/baseconfig/hook.json5
-rw-r--r--modules-available/locations/inc/location.inc.php (renamed from inc/location.inc.php)9
-rw-r--r--modules-available/main/lang/de/messages.json11
-rw-r--r--modules-available/main/lang/de/template-tags.json1
-rw-r--r--modules-available/main/lang/en/template-tags.json1
-rw-r--r--modules-available/main/lang/pt/global-tags.json3
-rw-r--r--style/default.css22
27 files changed, 484 insertions, 255 deletions
diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml
index 3e95d365..29def55c 100644
--- a/.idea/codeStyleSettings.xml
+++ b/.idea/codeStyleSettings.xml
@@ -10,6 +10,9 @@
<option name="LOWER_CASE_BOOLEAN_CONST" value="true" />
<option name="LOWER_CASE_NULL_CONST" value="true" />
</PHPCodeStyleSettings>
+ <XML>
+ <option name="XML_LEGACY_SETTINGS_IMPORTED" value="true" />
+ </XML>
<codeStyleSettings language="HTML">
<indentOptions>
<option name="INDENT_SIZE" value="3" />
@@ -18,6 +21,14 @@
<option name="USE_TAB_CHARACTER" value="true" />
</indentOptions>
</codeStyleSettings>
+ <codeStyleSettings language="JSON">
+ <indentOptions>
+ <option name="INDENT_SIZE" value="3" />
+ <option name="CONTINUATION_INDENT_SIZE" value="6" />
+ <option name="TAB_SIZE" value="3" />
+ <option name="USE_TAB_CHARACTER" value="true" />
+ </indentOptions>
+ </codeStyleSettings>
<codeStyleSettings language="PHP">
<option name="LINE_COMMENT_AT_FIRST_COLUMN" value="false" />
<option name="LINE_COMMENT_ADD_SPACE" value="true" />
diff --git a/apis/update.inc.php b/apis/update.inc.php
index 0c91ab2d..3ba7f9a0 100644
--- a/apis/update.inc.php
+++ b/apis/update.inc.php
@@ -321,4 +321,6 @@ function update_11()
KEY `locationid` (`locationid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;");
return true;
-} \ No newline at end of file
+}
+
+// TODO: Remove setting_distro, setting, cat_setting \ No newline at end of file
diff --git a/inc/defaultdata.inc.php b/inc/defaultdata.inc.php
index fdde4982..2d993e72 100644
--- a/inc/defaultdata.inc.php
+++ b/inc/defaultdata.inc.php
@@ -199,10 +199,6 @@ class DefaultData
'validator' => 'list:IGNORE|BUMP|EXCLUSIVE'
),
);
- foreach ($data as $entry) {
- Database::exec("INSERT IGNORE INTO setting (setting, catid, defaultvalue, permissions, validator)"
- . "VALUES (:setting, :catid, :defaultvalue, :permissions, :validator)", $entry);
- }
}
}
diff --git a/inc/module.inc.php b/inc/module.inc.php
index 894bc0f6..246505b5 100644
--- a/inc/module.inc.php
+++ b/inc/module.inc.php
@@ -19,6 +19,23 @@ class Module
return false;
return self::$modules[$name];
}
+
+ /**
+ * Check whether given module is available, that is, all dependencies are
+ * met. If the module is available, it will be activated, so all it's classes
+ * are available through the auto-loader.
+ *
+ * @param string $moduleId module to check
+ * @return bool true if module is available and activated
+ */
+ public static function isAvailable($moduleId)
+ {
+ $module = self::get($moduleId);
+ if ($module === false)
+ return false;
+ $module->activate();
+ return !$module->hasMissingDependencies();
+ }
private static function resolveDepsByName($name)
{
diff --git a/inc/util.inc.php b/inc/util.inc.php
index 5eed3ddc..c0b77f96 100644
--- a/inc/util.inc.php
+++ b/inc/util.inc.php
@@ -19,6 +19,19 @@ class Util
Header('Content-Type: text/plain; charset=utf-8');
echo "--------------------\nFlagrant system error:\n$message\n--------------------\n\n";
if (defined('CONFIG_DEBUG') && CONFIG_DEBUG) {
+ global $SLX_ERRORS;
+/*
+ 'errno' => $errno,
+ 'errstr' => $errstr,
+ 'errfile' => $errfile,
+ 'errline' => $errline,
+ */
+ if (!empty($SLX_ERRORS)) {
+ foreach ($SLX_ERRORS as $error) {
+ echo "{$error['errstr']} ({$error['errfile']}:{$error['errline']}\n";
+ }
+ echo "--------------------\n";
+ }
debug_print_backtrace();
echo "\n\nSome variables for your entertainment:\n";
print_r($GLOBALS);
diff --git a/modules-available/baseconfig-bwlp/baseconfig/categories.json b/modules-available/baseconfig-bwlp/baseconfig/categories.json
new file mode 100644
index 00000000..c33c58ab
--- /dev/null
+++ b/modules-available/baseconfig-bwlp/baseconfig/categories.json
@@ -0,0 +1,8 @@
+{
+ "power": 30,
+ "networking": 50,
+ "timesync": 100,
+ "sysconfig": 10,
+ "other": 20000,
+ "vmchooser": 20
+} \ No newline at end of file
diff --git a/modules-available/baseconfig-bwlp/baseconfig/settings.json b/modules-available/baseconfig-bwlp/baseconfig/settings.json
new file mode 100644
index 00000000..b0cbf81c
--- /dev/null
+++ b/modules-available/baseconfig-bwlp/baseconfig/settings.json
@@ -0,0 +1,122 @@
+{
+ "SLX_ADDONS": {
+ "catid": "other",
+ "defaultvalue": "vmware",
+ "permissions": "2",
+ "validator": ""
+ },
+ "SLX_BIOS_CLOCK": {
+ "catid": "timesync",
+ "defaultvalue": "off",
+ "permissions": "2",
+ "validator": "list:off|local|utc"
+ },
+ "SLX_LOGOUT_TIMEOUT": {
+ "catid": "power",
+ "defaultvalue": "2700",
+ "permissions": "2",
+ "validator": "regex:\/^\\d*$\/"
+ },
+ "SLX_NET_DOMAIN": {
+ "catid": "networking",
+ "defaultvalue": "",
+ "permissions": "2",
+ "validator": ""
+ },
+ "SLX_NTP_SERVER": {
+ "catid": "timesync",
+ "defaultvalue": "0.de.pool.ntp.org 1.de.pool.ntp.org",
+ "permissions": "2",
+ "validator": ""
+ },
+ "SLX_PROXY_BLACKLIST": {
+ "catid": "networking",
+ "defaultvalue": "",
+ "permissions": "2",
+ "validator": ""
+ },
+ "SLX_PROXY_IP": {
+ "catid": "networking",
+ "defaultvalue": "",
+ "permissions": "2",
+ "validator": ""
+ },
+ "SLX_PROXY_MODE": {
+ "catid": "networking",
+ "defaultvalue": "off",
+ "permissions": "2",
+ "validator": "list:off|on|auto"
+ },
+ "SLX_PROXY_PORT": {
+ "catid": "networking",
+ "defaultvalue": "",
+ "permissions": "2",
+ "validator": "regex:\/^\\d*$\/"
+ },
+ "SLX_PROXY_TYPE": {
+ "catid": "networking",
+ "defaultvalue": "socks5",
+ "permissions": "2",
+ "validator": "list:socks4|socks5|http-connect|http-relay"
+ },
+ "SLX_REMOTE_LOG_SESSIONS": {
+ "catid": "other",
+ "defaultvalue": "anonymous",
+ "permissions": "2",
+ "validator": "list:yes|anonymous|no"
+ },
+ "SLX_ROOT_PASS": {
+ "catid": "sysconfig",
+ "defaultvalue": "",
+ "permissions": "2",
+ "validator": "function:linuxPassword"
+ },
+ "SLX_DEMO_PASS": {
+ "catid": "sysconfig",
+ "defaultvalue": "",
+ "permissions": "2",
+ "validator": "function:linuxPassword"
+ },
+ "SLX_BWIDM_AUTH": {
+ "catid": "sysconfig",
+ "defaultvalue": "no",
+ "permissions": "2",
+ "validator": "list:yes|no"
+ },
+ "SLX_SHUTDOWN_SCHEDULE": {
+ "catid": "power",
+ "defaultvalue": "22:10 00:00",
+ "permissions": "2",
+ "validator": "regex:\/^(\\s*\\d{1,2}:\\d{1,2})*\\s*$\/"
+ },
+ "SLX_SHUTDOWN_TIMEOUT": {
+ "catid": "power",
+ "defaultvalue": "1200",
+ "permissions": "2",
+ "validator": "regex:\/^\\d*$\/"
+ },
+ "SLX_BENCHMARK_VM": {
+ "catid": "other",
+ "defaultvalue": "",
+ "permissions": "2",
+ "validator": ""
+ },
+ "SLX_VMCHOOSER_TAB": {
+ "catid": "vmchooser",
+ "defaultvalue": "AUTO",
+ "permissions": "2",
+ "validator": "list:0|1|2|AUTO"
+ },
+ "SLX_VMCHOOSER_TEMPLATES": {
+ "catid": "vmchooser",
+ "defaultvalue": "IGNORE",
+ "permissions": "2",
+ "validator": "list:IGNORE|BUMP"
+ },
+ "SLX_VMCHOOSER_FORLOCATION": {
+ "catid": "vmchooser",
+ "defaultvalue": "BUMP",
+ "permissions": "2",
+ "validator": "list:IGNORE|BUMP|EXCLUSIVE"
+ }
+}
diff --git a/modules-available/baseconfig/hooks/translation.inc.php b/modules-available/baseconfig/hooks/translation.inc.php
index 4f2cd8f7..7588fe38 100644
--- a/modules-available/baseconfig/hooks/translation.inc.php
+++ b/modules-available/baseconfig/hooks/translation.inc.php
@@ -18,10 +18,10 @@ $HANDLER['subsections'] = array(
* Configuration categories
*/
$HANDLER['grep_config-variable-categories'] = function($module) {
- $want = array();
- $res = Database::simpleQuery("SELECT catid FROM cat_setting ORDER BY catid ASC");
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $want['cat_' . $row['catid']] = true;
+ $module->activate();
+ $want = BaseConfigUtil::getCategories();
+ foreach ($want as &$entry) {
+ $entry = true;
}
return $want;
};
@@ -30,10 +30,10 @@ $HANDLER['grep_config-variable-categories'] = function($module) {
* Configuration variables
*/
$HANDLER['grep_config-variables'] = function($module) {
- $want = array();
- $res = Database::simpleQuery("SELECT setting FROM setting ORDER BY setting ASC");
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $want[$row['setting']] = true;
+ $module->activate();
+ $want = BaseConfigUtil::getVariables();
+ foreach ($want as &$entry) {
+ $entry = true;
}
return $want;
};
diff --git a/modules-available/baseconfig/inc/baseconfigutil.inc.php b/modules-available/baseconfig/inc/baseconfigutil.inc.php
new file mode 100644
index 00000000..33875156
--- /dev/null
+++ b/modules-available/baseconfig/inc/baseconfigutil.inc.php
@@ -0,0 +1,42 @@
+<?php
+
+class BaseConfigUtil
+{
+
+ /**
+ * Return all config variables to be handled directly by the baseconfig edit module.
+ * The array will contain a list of mapping of type:
+ * VARNAME => array(
+ * catid => xx,
+ * defaultvalue => xx,
+ * permissions => xx,
+ * validator => xx,
+ * )
+ *
+ * @return array all known config variables
+ */
+ public static function getVariables()
+ {
+ $settings = array();
+ foreach (glob('modules/*/baseconfig/settings.json', GLOB_NOSORT) as $file) {
+ $data = json_decode(file_get_contents($file), true);
+ if (is_array($data)) {
+ $settings += $data;
+ }
+ }
+ return $settings;
+ }
+
+ public static function getCategories()
+ {
+ $categories = array();
+ foreach (glob('modules/*/baseconfig/categories.json', GLOB_NOSORT) as $file) {
+ $data = json_decode(file_get_contents($file), true);
+ if (is_array($data)) {
+ $categories += $data;
+ }
+ }
+ return $categories;
+ }
+
+} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/de/config-variable-categories.json b/modules-available/baseconfig/lang/de/config-variable-categories.json
index b8cb6935..d8d7e91f 100644
--- a/modules-available/baseconfig/lang/de/config-variable-categories.json
+++ b/modules-available/baseconfig/lang/de/config-variable-categories.json
@@ -1,9 +1,9 @@
{
- "cat_1": "Inaktivit\u00e4t und Abschaltung",
- "cat_2": "Internetzugriff",
- "cat_3": "Zeitsynchronisation",
- "cat_4": "Grundsystem",
"cat_5": "Gemeinsames Netzlaufwerk",
- "cat_6": "Unkategorisiert",
- "cat_7": "vmchooser"
+ "networking": "Netzwerk-\/Internetzugriff",
+ "other": "Unkategorisiert",
+ "power": "Inaktivit\u00e4t und Abschaltung",
+ "sysconfig": "Grundsystem",
+ "timesync": "Zeitsynchronisation",
+ "vmchooser": "vmChooser"
} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/de/template-tags.json b/modules-available/baseconfig/lang/de/template-tags.json
index de2007d9..1c71e174 100644
--- a/modules-available/baseconfig/lang/de/template-tags.json
+++ b/modules-available/baseconfig/lang/de/template-tags.json
@@ -1,13 +1,6 @@
{
"lang_basicConfiguration": "Basiskonfiguration",
- "lang_catUser": "Benutzerverwaltung",
"lang_clientRelatedConfig": "Die Optionen auf dieser Seite beziehen sich auf das Verhalten der bwLehrpool-Clients.",
- "lang_create": "Schaffen",
- "lang_delete": "L\u00f6schen",
- "lang_newUser": "Neuer Benutzer",
- "lang_partitionMountPoint": "Mount Point",
- "lang_reset": "Zur\u00fccksetzen",
- "lang_save": "Speichern",
- "lang_userName": "Benutzername",
- "lang_userPasswd": "Passwort"
+ "lang_enableOverride": "\u00dcberschreiben",
+ "lang_reset": "Zur\u00fccksetzen"
} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/en/config-variable-categories.json b/modules-available/baseconfig/lang/en/config-variable-categories.json
index 7c0ab654..f0324e6b 100644
--- a/modules-available/baseconfig/lang/en/config-variable-categories.json
+++ b/modules-available/baseconfig/lang/en/config-variable-categories.json
@@ -1,9 +1,8 @@
{
- "cat_1": "Inactivity and Shutdown",
- "cat_2": "Internet Access",
- "cat_3": "Time Synchronization",
- "cat_4": "Basic System",
- "cat_5": "Common network share",
- "cat_6": "Uncategorized",
- "cat_7": "vmchooser"
+ "networking": "Internet Access",
+ "other": "Uncategorized",
+ "power": "Inactivity and Shutdown",
+ "sysconfig": "Basic System",
+ "timesync": "Time Synchronization",
+ "vmchooser": "vmChooser"
} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/en/template-tags.json b/modules-available/baseconfig/lang/en/template-tags.json
index 369fa081..84eb01d7 100644
--- a/modules-available/baseconfig/lang/en/template-tags.json
+++ b/modules-available/baseconfig/lang/en/template-tags.json
@@ -4,8 +4,7 @@
"lang_catUser": "User Managment",
"lang_clientRelatedConfig": "The options on this page are related to the bwLehrpool client machines.",
"lang_confirm": "Would you like to save the settings on [ \/srv\/openslx\/www\/boot\/config ] ?",
- "lang_create": "Create",
- "lang_delete": "Delete",
+ "lang_enableOverride": "Override",
"lang_helpId": "Partition Id",
"lang_helpMountPoint": "Must be a directory: \/example\/directory\/",
"lang_helpOptions": "Currently, only option 'bootable' is available",
@@ -19,7 +18,6 @@
"lang_reset": "Reset",
"lang_resetConfirm": "Do you really wish to reset the variable to their default values?",
"lang_resetDefault": "Reset Default",
- "lang_save": "Save",
"lang_userName": "Username",
"lang_userPasswd": "Password"
} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/pt/config-variable-categories.json b/modules-available/baseconfig/lang/pt/config-variable-categories.json
index b04839e8..99819f51 100644
--- a/modules-available/baseconfig/lang/pt/config-variable-categories.json
+++ b/modules-available/baseconfig/lang/pt/config-variable-categories.json
@@ -1,7 +1,7 @@
{
- "cat_1": "Inatividade e Desligamento",
- "cat_2": "Acesso \u00e0 Internet",
- "cat_3": "Sincroniza\u00e7\u00e3o de Tempo",
- "cat_4": "Sistema B\u00e1sico",
- "cat_7": "vmchooser"
+ "networking": "Acesso \u00e0 Internet",
+ "power": "Inatividade e Desligamento",
+ "sysconfig": "Sistema B\u00e1sico",
+ "timesync": "Sincroniza\u00e7\u00e3o de Tempo",
+ "vmchooser": "vmchooser"
} \ No newline at end of file
diff --git a/modules-available/baseconfig/lang/pt/template-tags.json b/modules-available/baseconfig/lang/pt/template-tags.json
index f6037d65..79e3e911 100644
--- a/modules-available/baseconfig/lang/pt/template-tags.json
+++ b/modules-available/baseconfig/lang/pt/template-tags.json
@@ -18,7 +18,6 @@
"lang_reset": "Limpar",
"lang_resetConfirm": "Voc\u00ea realmente deseja restaurar as vari\u00e1veis para seus valores padr\u00f5es?",
"lang_resetDefault": "Restaurar Padr\u00e3o",
- "lang_save": "Salvar",
"lang_userName": "Nome",
"lang_userPasswd": "Senha"
} \ No newline at end of file
diff --git a/modules-available/baseconfig/page.inc.php b/modules-available/baseconfig/page.inc.php
index 356ee2ec..5e209f4e 100644
--- a/modules-available/baseconfig/page.inc.php
+++ b/modules-available/baseconfig/page.inc.php
@@ -4,61 +4,82 @@ class Page_BaseConfig extends Page
{
private $qry_extra = array();
+ /**
+ * @var bool|string in case we're in module mode, set to the id of the module
+ */
+ private $targetModule = false;
+
protected function doPreprocess()
{
User::load();
- // Determine if we're setting global, distro or location
- if (isset($_REQUEST['distroid'])) {
- // TODO: Everything
- $this->qry_extra[] = array(
- 'name' => 'distroid',
- 'value' => (int)$_REQUEST['distroid'],
- 'table' => 'setting_distro',
- );
- if (isset($_REQUEST['locationid'])) {
- $this->qry_extra[] = array(
- 'name' => 'locationid',
- 'value' => (int)$_REQUEST['locationid'],
- 'table' => 'setting_location',
- );
- }
- }
+ // Determine if we're setting global or module specific
+ $this->getModuleSpecific();
- if (isset($_POST['setting']) && is_array($_POST['setting'])) {
- if (User::hasPermission('superadmin')) {
- // Build variables for specific sub-settings
+ $newValues = Request::post('setting');
+ if (is_array($newValues)) {
+ if (!User::hasPermission('superadmin')) {
+ Message::addError('main.no-permission');
+ Util::redirect('?do=baseconfig');
+ }
+ // Build variables for specific sub-settings
+ if (empty($this->qry_extra['field'])) {
$qry_insert = '';
$qry_values = '';
- foreach ($this->qry_extra as $item) {
- $qry_insert = ', ' . $item['name'];
- $qry_values = ', :' . $item['name'];
+ $params = array();
+ } else {
+ $qry_insert = ', ' . $this->qry_extra['field'];
+ $qry_values = ', :field_value';
+ $params = array('field_value' => $this->qry_extra['field_value']);
+ $delExtra = " AND {$this->qry_extra['field']} = :field_value ";
+ $delParams = array('field_value' => $this->qry_extra['field_value']);
+ }
+ if ($this->targetModule === false) {
+ $override = false;
+ } else {
+ // Not editing global settings
+ if ($this->getCurrentModuleName() === false) {
+ Message::addError('main.value-invalid', $this->qry_extra['field'], $this->qry_extra['field_value']);
+ Util::redirect('?do=BaseConfig');
}
- // Load all existing config options to validate input
- $res = Database::simpleQuery('SELECT setting, validator FROM setting');
- while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
- $key = $row['setting'];
- $validator = $row['validator'];
- $displayValue = (isset($_POST['setting'][$key]) ? $_POST['setting'][$key] : '');
- // Validate data first!
- $mangledValue = Validator::validate($validator, $displayValue);
- if ($mangledValue === false) {
- Message::addWarning('main.value-invalid', $key, $displayValue);
- continue;
- }
- // Now put into DB
- Database::exec("INSERT INTO setting_global (setting, value, displayvalue $qry_insert)
- VALUES (:key, :value, :displayvalue $qry_values)
- ON DUPLICATE KEY UPDATE value = :value, displayvalue = :displayvalue",
- $this->qry_extra + array(
- 'key' => $key,
- 'value' => $mangledValue,
- 'displayvalue' => $displayValue
- )
- );
+ // Honor override checkbox
+ $override = Request::post('override', array());
+ }
+ // Load all existing config options to validate input
+ $vars = BaseConfigUtil::getVariables();
+ foreach ($vars as $key => $var) {
+ if (is_array($override) && (!isset($override[$key]) || $override[$key] !== 'on')) {
+ // module mode - override not set - delete
+ $delParams['key'] = $key;
+ Database::exec("DELETE FROM {$this->qry_extra['table']} WHERE setting = :key $delExtra", $delParams);
+ continue;
}
- Message::addSuccess('settings-updated');
+ $validator = $var['validator'];
+ $displayValue = (isset($newValues[$key]) ? $newValues[$key] : '');
+ // Validate data first!
+ $mangledValue = Validator::validate($validator, $displayValue);
+ if ($mangledValue === false) {
+ Message::addWarning('main.value-invalid', $key, $displayValue);
+ continue;
+ }
+ // Now put into DB
+ Database::exec("INSERT INTO {$this->qry_extra['table']} (setting, value, displayvalue $qry_insert)"
+ . " VALUES (:key, :value, :displayvalue $qry_values)"
+ . " ON DUPLICATE KEY UPDATE value = :value, displayvalue = :displayvalue",
+ array(
+ 'key' => $key,
+ 'value' => $mangledValue,
+ 'displayvalue' => $displayValue
+ ) + $params
+ );
+ }
+ Message::addSuccess('settings-updated');
+ if ($this->targetModule === false) {
Util::redirect('?do=BaseConfig');
+ } elseif (empty($this->qry_extra['field'])) {
+ Util::redirect('?do=BaseConfig&module=' . $this->targetModule);
+ } else {
+ Util::redirect('?do=BaseConfig&module=' . $this->targetModule . '&' . $this->qry_extra['field'] . '=' . $this->qry_extra['field_value']);
}
}
}
@@ -69,31 +90,117 @@ class Page_BaseConfig extends Page
Message::addError('main.no-permission');
Util::redirect('?do=Main');
}
- // Build left joins for specific settings
- $joins = '';
- foreach ($this->qry_extra as $item) {
- $joins .= " LEFT JOIN {$item['table']} ";
+ // Check if valid submodule mode, stire name if any
+ if ($this->targetModule !== false) {
+ $this->qry_extra['subheading'] = $this->getCurrentModuleName();
+ if ($this->qry_extra['subheading'] === false) {
+ Message::addError('main.value-invalid', $this->qry_extra['field'], $this->qry_extra['field_value']);
+ Util::redirect('?do=BaseConfig');
+ }
}
- // List global config option
+ // List config options
$settings = array();
- $res = Database::simpleQuery('SELECT cat_setting.catid, setting.setting, setting.defaultvalue, setting.permissions, setting.validator, tbl.displayvalue
- FROM setting
- INNER JOIN cat_setting USING (catid)
- LEFT JOIN setting_global AS tbl USING (setting)
- ORDER BY cat_setting.sortval ASC, setting.setting ASC');
+ $vars = BaseConfigUtil::getVariables();
+ $cats = BaseConfigUtil::getCategories();
+ // Get stuff that's set in DB already
+ if (isset($this->qry_extra['field'])) {
+ $where = " WHERE {$this->qry_extra['field']} = :field_value";
+ $params = array('field_value' => $this->qry_extra['field_value']);
+ } else {
+ $where = '';
+ $params = array();
+ }
+ // Populate structure with existing config from db
+ $res = Database::simpleQuery("SELECT setting, displayvalue FROM {$this->qry_extra['table']} "
+ . " {$where} ORDER BY setting ASC", $params);
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
+ if (!isset($vars[$row['setting']]) || !is_array($vars[$row['setting']])) {
+ $unknown[] = $row['setting'];
+ continue;
+ }
+ $row += $vars[$row['setting']];
$row['description'] = Util::markup(Dictionary::translateFile('config-variables', $row['setting']));
if (is_null($row['displayvalue'])) $row['displayvalue'] = $row['defaultvalue'];
$row['item'] = $this->makeInput($row['validator'], $row['setting'], $row['displayvalue']);
- $settings[$row['catid']]['settings'][] = $row;
- if (!isset($settings[$row['catid']]['category_id'])) {
- $settings[$row['catid']]['category_name'] = Dictionary::translateFile('config-variable-categories', 'cat_' . $row['catid']);
- $settings[$row['catid']]['category_id'] = $row['catid'];
+ if (!isset($row['catid'])) {
+ $row['catid'] = 'unknown';
}
+ $settings[$row['catid']]['settings'][$row['setting']] = $row;
}
+ // Add entries that weren't in the db (global), setup override checkbox (module specific)
+ foreach ($vars as $key => $var) {
+ if (isset($settings[$var['catid']]['settings'][$key])) {
+ // Value is set in DB
+ $settings[$var['catid']]['settings'][$key]['checked'] = 'checked';
+ continue;
+ }
+ // Value is not set in DB
+ $settings[$var['catid']]['settings'][$key] = $var + array(
+ 'setting' => $key,
+ 'item' => $this->makeInput($var['validator'], $key, $var['defaultvalue'])
+ );
+ }
+ // Sort categories
+ $sortvals = array();
+ foreach ($settings as $catid => &$setting) {
+ $sortvals[] = isset($cats[$catid]) ? (int)$cats[$catid] : 99999;
+ $setting['category_id'] = $catid;
+ $setting['category_name'] = Dictionary::translateFile('config-variable-categories', 'cat_' . $catid);
+ if ($setting['category_name'] === false) {
+ $setting['category_name'] = $catid;
+ }
+ $setting['settings'] = array_values($setting['settings']);
+ }
+ unset($setting);
+ array_multisort($sortvals, SORT_ASC, SORT_NUMERIC, $settings);
Render::addTemplate('_page', array(
- 'categories' => array_values($settings)
- ));
+ 'override' => $this->targetModule !== false,
+ 'categories' => array_values($settings),
+ 'target_module' => $this->targetModule,
+ ) + $this->qry_extra);
+ }
+
+ private function getCurrentModuleName()
+ {
+ if (isset($this->qry_extra['tostring'])) {
+ $method = explode('::', $this->qry_extra['tostring']);
+ return call_user_func($method, $this->qry_extra['field_value']);
+ }
+ if (isset($this->qry_extra['field'])) {
+ return $this->targetModule . ' // ' . $this->qry_extra['field'] . '=' . $this->qry_extra['field_value'];
+ }
+ return $this->targetModule;
+ }
+
+ private function getModuleSpecific()
+ {
+ $module = Request::any('module', '', 'string');
+ if ($module === '') {
+ $this->qry_extra = array(
+ 'table' => 'setting_global',
+ );
+ return;
+ }
+ //\\//\\//\\
+ if (!Module::isAvailable($module)) {
+ Message::addError('main.no-such-module', $module);
+ Util::redirect('?do=baseconfig');
+ }
+ $file = 'modules/' . $module . '/baseconfig/hook.json';
+ if (!file_exists($file)) {
+ Message::addError('no-module-hook', $module);
+ Util::redirect('?do=baseconfig');
+ }
+ $hook = json_decode(file_get_contents($file), true);
+ if (empty($hook['table'])) {
+ Message::addError('invalid-hook', $module);
+ Util::redirect('?do=baseconfig');
+ }
+ if (isset($hook['field'])) {
+ $hook['field_value'] = Request::any($hook['field'], '0', 'string');
+ }
+ $this->targetModule = $module;
+ $this->qry_extra = $hook;
}
/**
diff --git a/modules-available/baseconfig/templates/_page.html b/modules-available/baseconfig/templates/_page.html
index da155ad2..e8b85dd3 100644
--- a/modules-available/baseconfig/templates/_page.html
+++ b/modules-available/baseconfig/templates/_page.html
@@ -1,6 +1,12 @@
<h1>{{lang_basicConfiguration}}</h1>
+<h2>{{subheading}}</h2>
<p>{{lang_clientRelatedConfig}}</p>
<form action="?do=BaseConfig" method="post">
+ <input type="hidden" name="token" value="{{token}}">
+ {{#override}}
+ <input name="module" type="hidden" value="{{target_module}}">
+ <input name="{{field}}" type="hidden" value="{{field_value}}">
+ {{/override}}
<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true">
<input type="text" name="prevent_autofill" id="prevent_autofill" value="" style="display:none;">
<input type="password" name="password_fake" id="password_fake" value="" style="display:none;">
@@ -15,11 +21,18 @@
<div class="panel-body">
<div class="list-group">
{{#settings}}
- <div class="list-group-item {{class}}">
+ <div class="list-group-item">
<div class="row">
- <div class="col-md-5">
- {{setting}}
- <div class="slx-default">{{defaultvalue}}</div>
+ <div class="col-md-5 slx-cfg-toggle">
+ <div>{{setting}}</div>
+ {{^override}}
+ <div class="slx-default">
+ {{defaultvalue}}
+ </div>
+ {{/override}}
+ {{#override}}
+ <input name="override[{{setting}}]" id="CB_{{setting}}" type="checkbox" {{checked}}> <label for="CB_{{setting}}">{{lang_enableOverride}}</label>
+ {{/override}}
</div>
<div class="col-md-5">
{{{item}}}
@@ -47,139 +60,8 @@
</div>
</div>
{{/categories}}
-
-
-
- <!-- User Managment Section -->
- <div class="panel panel-default">
- <div class="panel-heading" role="tab" id="headingUsers">
- <a data-toggle="collapse" data-parent="#accordion" href="#collapseUsers" aria-expanded="false" aria-controls="collapseUsers">
- {{lang_catUser}}
- </a>
- <span style="display:inline-block; float: right; margin-top: -7px;">
- <a class="btn btn-default " data-toggle="modal" data-target="#add-user">
- <span class="glyphicon glyphicon-plus"></span>
- </a>
- </span>
- </div>
- <div id="collapseUsers" class="accordion-body collapse" role="tabpanel" aria-labelledby="headingUsers">
- <div class="panel-body">
- <div class="list-group">
- {{#users}}
- <div class="list-group-item">
- <div class="row">
- <div class="col-md-5">
- <input name="user-{{id}}-name" type="text" class="form-control" size="30" value="{{name}}" />
- </div>
- <div class="col-md-5">
- <input name="user-{{id}}-password" type="text" class="form-control" size="30" placeholder="{{lang_userPasswd}}" />
- </div>
- <div class="col-md-2">
- <a class="btn btn-danger" href="?do=BaseConfig&deleteUser={{id}}&token={{token}}" ><span class="glyphicon glyphicon-trash"></span> {{lang_delete}}</a>
- </div>
- </div>
- </div>
- {{/users}}
- </div>
- </div>
- </div>
- </div>
</div>
- <input type="hidden" name="token" value="{{token}}">
- <button class="btn btn-lg btn-primary" type="submit">{{lang_save}}</button>
- <button class="btn btn-lg btn-primary" type="reset">{{lang_reset}}</button>
- <a class="btn btn-lg btn-primary" href="api.php?do=getconfig">Download</a>
+ <button class="btn btn-primary" type="submit">{{lang_save}}</button>
+ <button class="btn btn-default" type="reset">{{lang_reset}}</button>
+ <a class="btn btn-default" href="api.php?do=getconfig">Download</a>
</form>
-<p>
- <form method="post" action="?do=BaseConfig">
- <input type="hidden" name="token" value="{{token}}">
- <input type="hidden" name="action" value="reset">
- <button class="btn btn-default" type="submit" onclick="return confirm('{{lang_resetConfirm}}');">{{lang_resetDefault}}</button>
- </form>
-</p>
-<!-- Create User Window -->
-<form action="?do=BaseConfig" method="post">
- <div class="modal fade" id="add-user" tabindex="-1" role="dialog">
- <div class="modal-dialog">
-
- <div class="modal-content">
- <div class="modal-header">{{lang_newUser}}</div>
- <div class="modal-body">
-
- <p>
- <input name="new-user-name" placeholder="{{lang_userName}}" class="form-control" type="text">
- </p>
- <p>
- <input name="new-user-passwd" placeholder="{{lang_userPasswd}}" class="form-control" type="password">
- </p>
- <input type="submit" class="btn btn-primary" value="{{lang_create}}">
- </div>
- <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div>
- </div>
- </div>
- </div>
- <input type="hidden" name="action" value="new_user">
- <input type="hidden" name="token" value="{{token}}">
-</form>
-<!-- Create Partition Window -->
-<form action="?do=BaseConfig" method="post">
- <div class="modal fade" id="add-partition" tabindex="-1" role="dialog">
- <div class="modal-dialog">
-
- <div class="modal-content">
- <div class="modal-header">{{lang_newPartition}}</div>
- <div class="modal-body">
-
- <div class="input-group">
- <span class="input-group-addon">{{lang_partitionId}}</span>
- <input name="new-partition-id" class="form-control" type="text">
- </div>
- <p class="help-block">{{lang_helpId}}</p>
- <div class="input-group">
- <span class="input-group-addon">{{lang_partitionSize}}</span>
- <input name="new-partition-size" class="form-control" type="text">
- </div>
- <p class="help-block">{{lang_helpSize}}</p>
- <div class="input-group">
- <span class="input-group-addon">{{lang_partitionMountPoint}}</span>
- <input name="new-partition-mount-point" class="form-control" type="text">
- </div>
- <p class="help-block">{{lang_helpMountPoint}}</p>
- <div class="input-group">
- <span class="input-group-addon">{{lang_partitionOptions}}</span>
- <input name="new-partition-options" class="form-control" type="text">
- </div>
- <p class="help-block">{{lang_helpOptions}}</p>
- <input type="submit" class="btn btn-primary" value="{{lang_create}}">
- </div>
- <div class="modal-footer"><a class="btn btn-primary" data-dismiss="modal">{{lang_close}}</a></div>
- </div>
- </div>
- </div>
- <input type="hidden" name="action" value="new_partition">
- <input type="hidden" name="token" value="{{token}}">
-</form>
-<script type="text/javascript">
-
-function saveConfig(){
- if(confirm('{{lang_confirm}}'))
- window.location = 'api.php?do=getconfig&user={{user}}&save=true';
- else
- window.location = 'api.php?do=getconfig&user={{user}}';
-}
-
-document.addEventListener("DOMContentLoaded", function() {
- document.getElementById("cat-extra-6").innerHTML = "<div class='list-group'> <div class='list-group-item' style='background-color:#f5f5f5;color:#428bca;'> " +
- "{{lang_catPartition}} <span style='display:inline-block; float: right; margin-top: -7px;'> <a class='btn btn-default ' data-toggle='modal' " +
- "data-target='#add-partition'> <span class='glyphicon glyphicon-plus'></span> </a> </span> </div> {{#partitions}} <div class='list-group-item'> " +
- "<div class='row'> <div class='col-md-1'> <input name='partition-{{id}}-partition_id' type='text' class='form-control' size='30' value='{{partition_id}}'" +
- " placeholder='{{lang_partitionId}}' /> </div> <div class='col-md-1'> <input name='partition-{{id}}-size' type='text' class='form-control' size='30' " +
- "value='{{size}}' placeholder='{{lang_partitionSize}}'/> </div> <div class='col-md-4'> <input name='partition-{{id}}-mount_point' type='text' " +
- "class='form-control' size='30' value='{{mount_point}}' placeholder='{{lang_partitionMountPoint}}'/> </div> <div class='col-md-4'> <input " +
- "name='partition-{{id}}-options' type='text' class='form-control' size='30' value='{{options}}' placeholder='{{lang_partitionOptions}}'/> </div> " +
- "<div class='col-md-2'> <a class='btn btn-danger' href='?do=BaseConfig&deletePartition={{id}}&token={{token}}' ><span class='glyphicon glyphicon-trash'>" +
- "</span> {{lang_delete}}</a> </div> </div> </div> {{/partitions}} </div> </div>";
- $("[name^='switch']").bootstrapSwitch();
-}
-
-</script>
diff --git a/modules-available/internetaccess/lang/de/messages.json b/modules-available/internetaccess/lang/de/messages.json
new file mode 100644
index 00000000..1b075f70
--- /dev/null
+++ b/modules-available/internetaccess/lang/de/messages.json
@@ -0,0 +1,4 @@
+{
+ "settings-updated": "Einstellungen wurden aktualisiert",
+ "invalid-action": "Ung\u00fcltige Aktion: {{0}}"
+} \ No newline at end of file
diff --git a/modules-available/internetaccess/lang/en/messages.json b/modules-available/internetaccess/lang/en/messages.json
new file mode 100644
index 00000000..6a1af968
--- /dev/null
+++ b/modules-available/internetaccess/lang/en/messages.json
@@ -0,0 +1,4 @@
+{
+ "settings-updated": "Settings have been updated",
+ "invalid-action": "Invalid action: {{0}}"
+} \ No newline at end of file
diff --git a/modules-available/internetaccess/lang/pt/messages.json b/modules-available/internetaccess/lang/pt/messages.json
new file mode 100644
index 00000000..af5b9b22
--- /dev/null
+++ b/modules-available/internetaccess/lang/pt/messages.json
@@ -0,0 +1,4 @@
+{
+ "settings-updated": "As configura\u00e7\u00f5es foram atualizadas",
+ "invalid-action": "A\u00e7\u00e3o inv\u00e1lida: {{0}}"
+} \ No newline at end of file
diff --git a/modules-available/locations/baseconfig/hook.json b/modules-available/locations/baseconfig/hook.json
new file mode 100644
index 00000000..c295e0f6
--- /dev/null
+++ b/modules-available/locations/baseconfig/hook.json
@@ -0,0 +1,5 @@
+{
+ "table": "setting_location",
+ "field": "locationid",
+ "tostring": "Location::getName"
+} \ No newline at end of file
diff --git a/inc/location.inc.php b/modules-available/locations/inc/location.inc.php
index 39ecdf67..1a01ff24 100644
--- a/inc/location.inc.php
+++ b/modules-available/locations/inc/location.inc.php
@@ -15,6 +15,15 @@ class Location
}
return $rows;
}
+
+ public static function getName($locationId)
+ {
+ self::getLocationsAssoc();
+ $locationId = (int)$locationId;
+ if (!isset(self::$assocLocationCache[$locationId]))
+ return false;
+ return self::$assocLocationCache[$locationId]['locationname'];
+ }
public static function getLocationsAssoc()
{
diff --git a/modules-available/main/lang/de/messages.json b/modules-available/main/lang/de/messages.json
index ec645d05..245d4871 100644
--- a/modules-available/main/lang/de/messages.json
+++ b/modules-available/main/lang/de/messages.json
@@ -1,12 +1,13 @@
{
- "no-permission": "Keine ausreichenden Rechte, um auf diese Seite zuzugreifen",
- "error-write": "Fehler beim Schreiben von {{0}}",
+ "debug-mode": "Der Debug-Modus ist aktiv!",
"empty-field": "Ein Feld wurde nicht ausgef\u00fcllt",
- "value-invalid": "Der Wert {{1}} ist ung\u00fcltig f\u00fcr die Option {{0}} und wurde ignoriert",
"error-read": "Fehler beim Lesen von {{0}}",
- "taskmanager-error": "Verbindung zum Taskmanager fehlgeschlagen",
+ "error-write": "Fehler beim Schreiben von {{0}}",
+ "no-permission": "Keine ausreichenden Rechte, um auf diese Seite zuzugreifen",
+ "no-such-module": "Modul {{0}} existiert nicht oder ist nicht aktiv",
"task-error": "Ausf\u00fchrung fehlgeschlagen: {{0}}",
+ "taskmanager-error": "Verbindung zum Taskmanager fehlgeschlagen",
"taskmanager-format": "Taskmanager hat ung\u00fcltige Daten zur\u00fcckgeliefert",
"token": "Ung\u00fcltiges Token. CSRF Angriff?",
- "debug-mode": "Der Debug-Modus ist aktiv!"
+ "value-invalid": "Der Wert {{1}} ist ung\u00fcltig f\u00fcr die Option {{0}} und wurde ignoriert"
} \ No newline at end of file
diff --git a/modules-available/main/lang/de/template-tags.json b/modules-available/main/lang/de/template-tags.json
index 8a3120d3..b299cbad 100644
--- a/modules-available/main/lang/de/template-tags.json
+++ b/modules-available/main/lang/de/template-tags.json
@@ -19,5 +19,6 @@
"lang_translations": "\u00dcbersetzungen",
"lang_vmLocationNotSet": "Es ist noch kein Speicherort f\u00fcr die Virtuellen Maschinen festgelegt.",
"lang_warning": "Warnung",
+ "lang_warningDebug": "Debugmodus aktiv!",
"lang_welcome": "Willkommen"
} \ No newline at end of file
diff --git a/modules-available/main/lang/en/template-tags.json b/modules-available/main/lang/en/template-tags.json
index aeebc998..be03e53e 100644
--- a/modules-available/main/lang/en/template-tags.json
+++ b/modules-available/main/lang/en/template-tags.json
@@ -19,5 +19,6 @@
"lang_translations": "Translations",
"lang_vmLocationNotSet": "A location for the virtual machine is not set yet.",
"lang_warning": "Warning",
+ "lang_warningDebug": "Debug mode active!",
"lang_welcome": "Welcome"
} \ No newline at end of file
diff --git a/modules-available/main/lang/pt/global-tags.json b/modules-available/main/lang/pt/global-tags.json
index 7c1311ec..a462651b 100644
--- a/modules-available/main/lang/pt/global-tags.json
+++ b/modules-available/main/lang/pt/global-tags.json
@@ -1,4 +1,5 @@
{
"lang_close": "Fechar",
- "lang_next": "Pr\u00f3ximo"
+ "lang_next": "Pr\u00f3ximo",
+ "lang_save": "Salvar"
} \ No newline at end of file
diff --git a/style/default.css b/style/default.css
index 74997381..9fa2db8d 100644
--- a/style/default.css
+++ b/style/default.css
@@ -342,12 +342,12 @@ nav.sidebar li {
.main
{
- float:right;
- margin-left:240px;
- margin-top:32px;
- min-width:900px;
- position:absolute;
- width:calc(100%-200px);
+ float: right;
+ margin-left: 240px;
+ margin-top: 32px;
+ min-width: 900px;
+ position: absolute;
+ width: calc(100% - 200px);
}
.navbar-inverse,.sidebar-bg
@@ -525,6 +525,16 @@ section{
border-top-left-radius: 0;
}
+.slx-cfg-toggle > input[type=checkbox] ~ label {
+ font-weight: normal;
+}
+
+.slx-cfg-toggle > input[type=checkbox]:checked ~ label {
+ font-weight: bold;
+}
+
+/* what's this?
textarea.form-control .editor-box{
height: 520px;
}
+*/