summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2014-01-09 20:23:58 +0100
committerSimon Rettberg2014-01-09 20:23:58 +0100
commita12c5db601ad2c3cee2507099b692d491782d614 (patch)
tree6c648f861e09ca6dc9bab68dc5e398d6f7309ce4
parentCategories for config vars (diff)
downloadslx-admin-a12c5db601ad2c3cee2507099b692d491782d614.tar.gz
slx-admin-a12c5db601ad2c3cee2507099b692d491782d614.tar.xz
slx-admin-a12c5db601ad2c3cee2507099b692d491782d614.zip
Add pagination to syslog, change filter inputbox to use tagsinput
-rw-r--r--inc/paginate.inc.php114
-rw-r--r--inc/render.inc.php2
-rw-r--r--modules/syslog.inc.php9
-rw-r--r--script/bootstrap-tagsinput.min.js8
-rw-r--r--style/bootstrap-tagsinput.css45
-rw-r--r--style/default.css8
-rw-r--r--templates/page-syslog.html6
-rw-r--r--templates/page-tgz-list.html5
-rw-r--r--templates/pagenav.html15
-rw-r--r--updates/v243
10 files changed, 248 insertions, 7 deletions
diff --git a/inc/paginate.inc.php b/inc/paginate.inc.php
new file mode 100644
index 00000000..62345ffe
--- /dev/null
+++ b/inc/paginate.inc.php
@@ -0,0 +1,114 @@
+<?php
+
+class Paginate
+{
+ private $query;
+ private $currentPage;
+ private $perPage;
+ private $url;
+ private $totalRows = false;
+
+ /**
+ * @query - The query that will return lines to show
+ * @currentPage - 0based index of currently viewed page
+ * @perPage - Number of items to show per page
+ * @url - URL of current wegpage
+ */
+ public function __construct($query, $perPage, $url = false)
+ {
+ $this->currentPage = (isset($_GET['page']) ? (int)$_GET['page'] : 0);
+ $this->perPage = (int)$perPage;
+ if ($this->currentPage < 0) {
+ Util::traceError('Current page < 0');
+ }
+ if ($this->perPage < 1) {
+ Util::traceError('Per page < 1');
+ }
+ // Query
+ if (!preg_match('/\s*SELECT\s/is', $query)) {
+ Util::traceError('Query has to start with SELECT!');
+ }
+ // XXX: MySQL only
+ if (preg_match('/^mysql/i', CONFIG_SQL_DSN)) {
+ // Sanity: Check for LIMIT specification at the end
+ if (preg_match('/LIMIT\s+(\d+|\:\w+|\?)\s*,\s*(\d+|\:\w+|\?)(\s|;)*(\-\-.*)?$/is', $query)) {
+ Util::traceError("You cannot pass a query containing a LIMIT to the Paginator class!");
+ }
+ // Sanity: no comment or semi-colon at end (sloppy, might lead to false negatives)
+ if (preg_match('/(\-\-|;)(\s|[^\'"`])*$/is', $query)) {
+ Util::traceError("Your query must not end in a comment or semi-colon!");
+ }
+ $query .= ' LIMIT ' . ($this->currentPage * $this->perPage) . ', ' . $this->perPage;
+ // Use SQL_CALC_FOUND_ROWS
+ if (!preg_match('/^\s*SELECT\s+SQL_CALC_FOUND_ROWS/is', $query)) {
+ $query = preg_replace('/^\s*SELECT/is', 'SELECT SQL_CALC_FOUND_ROWS ', $query);
+ }
+ } else {
+ Util::traceError('Unsupported database engine');
+ }
+ // Mangle URL
+ if ($url === false) $url = $_SERVER['REQUEST_URI'];
+ if (strpos($url, '?') === false) {
+ $url .= '?';
+ } else {
+ $url = preg_replace('/(\?|&)&*page=[^&]*(&+|$)/i', '$1', $url);
+ if (substr($url, -1) !== '&') $url .= '&';
+ }
+ //
+ $this->query =$query;
+ $this->url = $url;
+ }
+
+ /**
+ * Execute the query, returning the PDO query object
+ */
+ public function exec($args = array())
+ {
+ $args[':limit_start'] = $this->currentPage;
+ $args[':limit_count'] = $this->perPage;
+ $retval = Database::simpleQuery($this->query, $args);
+ $res = Database::queryFirst('SELECT FOUND_ROWS() AS rowcount');
+ $this->totalRows = (int)$res['rowcount'];
+ return $retval;
+ }
+
+ public function render($template, $data)
+ {
+ if ($this->totalRows == 0) {
+ // Shortcut for no content
+ Render::addTemplate($template, $data);
+ return;
+ }
+ // The real thing
+ $pages = array();
+ $pageCount = floor(($this->totalRows - 1) / $this->perPage) + 1;
+ $skip = false;
+ for ($i = 0; $i < $pageCount; ++$i) {
+ if (($i > 0 && $i < $this->currentPage - 3) || ($i > $this->currentPage + 3 && $i < $pageCount - 1)) {
+ if (!$skip) {
+ $skip = true;
+ $pages[] = array(
+ 'text' => false,
+ 'current' => false
+ );
+ }
+ continue;
+ }
+ $skip = false;
+ $pages[] = array(
+ 'text' => $i + 1,
+ 'page' => $i,
+ 'current' => $i == $this->currentPage,
+ );
+ }
+ $pages = Render::parse('pagenav', array(
+ 'url' => $this->url,
+ 'pages' => $pages,
+ ));
+ $data['page'] = $this->currentPage;
+ $data['pagenav'] = $pages;
+ Render::addTemplate($template, $data);
+ }
+
+}
+
diff --git a/inc/render.inc.php b/inc/render.inc.php
index 1ab93965..a3cef516 100644
--- a/inc/render.inc.php
+++ b/inc/render.inc.php
@@ -42,6 +42,7 @@ class Render
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Bootstrap -->
<link href="style/bootstrap.min.css" rel="stylesheet" media="screen">
+ <link href="style/bootstrap-tagsinput.css" rel="stylesheet" media="screen">
<link href="style/default.css" rel="stylesheet" media="screen">
',
self::$header
@@ -55,6 +56,7 @@ class Render
' </div>
<script src="script/jquery.js"></script>
<script src="script/bootstrap.min.js"></script>
+ <script src="script/bootstrap-tagsinput.min.js"></script>
<script src="script/custom.js"></script></body>
</html>'
;
diff --git a/modules/syslog.inc.php b/modules/syslog.inc.php
index 70c383d0..f8d99de3 100644
--- a/modules/syslog.inc.php
+++ b/modules/syslog.inc.php
@@ -1,5 +1,7 @@
<?php
+require_once('inc/paginate.inc.php');
+
User::load();
if (!User::isLoggedIn()) {
@@ -14,7 +16,7 @@ function render_module()
$not = '';
if (isset($_POST['filter'])) $filter = $_POST['filter'];
if (!empty($filter)) {
- $parts = explode(' ', $filter);
+ $parts = explode(',', $filter);
$opt = array();
foreach ($parts as $part) {
$part = preg_replace('/[^a-z0-9_\-]/', '', trim($part));
@@ -29,7 +31,8 @@ function render_module()
$today = date('d.m.Y');
$yesterday = date('d.m.Y', time() - 86400);
$lines = array();
- $res = Database::simpleQuery("SELECT logid, dateline, logtypeid, clientip, description, extra FROM clientlog $opt ORDER BY logid DESC LIMIT 200");
+ $paginate = new Paginate("SELECT logid, dateline, logtypeid, clientip, description, extra FROM clientlog $opt ORDER BY logid DESC", 50);
+ $res = $paginate->exec();
while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
$day = date('d.m.Y', $row['dateline']);
// TODO: No output strings in source files!
@@ -42,7 +45,7 @@ function render_module()
$lines[] = $row;
}
- Render::addTemplate('page-syslog', array(
+ $paginate->render('page-syslog', array(
'token' => Session::get('token'),
'filter' => $filter,
'not' => $not,
diff --git a/script/bootstrap-tagsinput.min.js b/script/bootstrap-tagsinput.min.js
new file mode 100644
index 00000000..3d652628
--- /dev/null
+++ b/script/bootstrap-tagsinput.min.js
@@ -0,0 +1,8 @@
+/*
+ * bootstrap-tagsinput v0.3.9 by Tim Schlechter
+ *
+ */
+!function(a){"use strict";function b(b,c){this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect="SELECT"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute("multiple"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute("placeholder")?this.$element.attr("placeholder"):"",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('<div class="bootstrap-tagsinput"></div>'),this.$input=a('<input size="'+this.inputSize+'" type="text" placeholder="'+this.placeholderText+'"/>').appendTo(this.$container),this.$element.after(this.$container),this.build(c)}function c(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?h.text(a).html():""}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart("character",-a.value.length),b=c.text.length}else(a.selectionStart||"0"==a.selectionStart)&&(b=a.selectionStart);return b}var g={tagClass:function(){return"label label-info"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},freeInput:!0,maxTags:void 0,confirmKeys:[13],onTagExists:function(a,b){b.hide().fadeIn()}};b.prototype={constructor:b,add:function(b,c){var d=this;if(!(d.options.maxTags&&d.itemsArray.length>=d.options.maxTags||b!==!1&&!b)){if("object"==typeof b&&!d.objectItems)throw"Can't add objects when itemValue option is not set";if(!b.toString().match(/^\s*$/)){if(d.isSelect&&!d.multiple&&d.itemsArray.length>0&&d.remove(d.itemsArray[0]),"string"==typeof b&&"INPUT"===this.$element[0].tagName){var f=b.split(",");if(f.length>1){for(var g=0;g<f.length;g++)this.add(f[g],!0);return c||d.pushVal(),void 0}}var h=d.options.itemValue(b),i=d.options.itemText(b),j=d.options.tagClass(b),k=a.grep(d.itemsArray,function(a){return d.options.itemValue(a)===h})[0];if(k){if(d.options.onTagExists){var l=a(".tag",d.$container).filter(function(){return a(this).data("item")===k});d.options.onTagExists(b,l)}}else{d.itemsArray.push(b);var m=a('<span class="tag '+e(j)+'">'+e(i)+'<span data-role="remove"></span></span>');if(m.data("item",b),d.findInputWrapper().before(m),m.after(" "),d.isSelect&&!a('option[value="'+escape(h)+'"]',d.$element)[0]){var n=a("<option selected>"+e(i)+"</option>");n.data("item",b),n.attr("value",h),d.$element.append(n)}c||d.pushVal(),d.options.maxTags===d.itemsArray.length&&d.$container.addClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemAdded",{item:b}))}}}},remove:function(b,c){var d=this;d.objectItems&&(b="object"==typeof b?a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==d.options.itemValue(b)})[0]:a.grep(d.itemsArray,function(a){return d.options.itemValue(a)==b})[0]),b&&(a(".tag",d.$container).filter(function(){return a(this).data("item")===b}).remove(),a("option",d.$element).filter(function(){return a(this).data("item")===b}).remove(),d.itemsArray.splice(a.inArray(b,d.itemsArray),1)),c||d.pushVal(),d.options.maxTags>d.itemsArray.length&&d.$container.removeClass("bootstrap-tagsinput-max"),d.$element.trigger(a.Event("itemRemoved",{item:b}))},removeAll:function(){var b=this;for(a(".tag",b.$container).remove(),a("option",b.$element).remove();b.itemsArray.length>0;)b.itemsArray.pop();b.pushVal(),b.options.maxTags&&!this.isEnabled()&&this.enable()},refresh:function(){var b=this;a(".tag",b.$container).each(function(){var c=a(this),d=c.data("item"),f=b.options.itemValue(d),g=b.options.itemText(d),h=b.options.tagClass(d);if(c.attr("class",null),c.addClass("tag "+e(h)),c.contents().filter(function(){return 3==this.nodeType})[0].nodeValue=e(g),b.isSelect){var i=a("option",b.$element).filter(function(){return a(this).data("item")===d});i.attr("value",f)}})},items:function(){return this.itemsArray},pushVal:function(){var b=this,c=a.map(b.items(),function(a){return b.options.itemValue(a).toString()});b.$element.val(c,!0).trigger("change")},build:function(b){var e=this;e.options=a.extend({},g,b);var h=e.options.typeahead||{};e.objectItems&&(e.options.freeInput=!1),c(e.options,"itemValue"),c(e.options,"itemText"),c(e.options,"tagClass"),e.options.source&&(h.source=e.options.source),h.source&&a.fn.typeahead&&(d(h,"source"),e.$input.typeahead({source:function(b,c){function d(a){for(var b=[],d=0;d<a.length;d++){var g=e.options.itemText(a[d]);f[g]=a[d],b.push(g)}c(b)}this.map={};var f=this.map,g=h.source(b);a.isFunction(g.success)?g.success(d):a.when(g).then(d)},updater:function(a){e.add(this.map[a])},matcher:function(a){return-1!==a.toLowerCase().indexOf(this.query.trim().toLowerCase())},sorter:function(a){return a.sort()},highlighter:function(a){var b=new RegExp("("+this.query+")","gi");return a.replace(b,"<strong>$1</strong>")}})),e.$container.on("click",a.proxy(function(){e.$input.focus()},e)),e.$container.on("keydown","input",a.proxy(function(b){var c=a(b.target),d=e.findInputWrapper();switch(b.which){case 8:if(0===f(c[0])){var g=d.prev();g&&e.remove(g.data("item"))}break;case 46:if(0===f(c[0])){var h=d.next();h&&e.remove(h.data("item"))}break;case 37:var i=d.prev();0===c.val().length&&i[0]&&(i.before(d),c.focus());break;case 39:var j=d.next();0===c.val().length&&j[0]&&(j.after(d),c.focus());break;default:e.options.freeInput&&a.inArray(b.which,e.options.confirmKeys)>=0&&(e.add(c.val()),c.val(""),b.preventDefault())}c.attr("size",Math.max(this.inputSize,c.val().length))},e)),e.$container.on("click","[data-role=remove]",a.proxy(function(b){e.remove(a(b.target).closest(".tag").data("item"))},e)),e.options.itemValue===g.itemValue&&("INPUT"===e.$element[0].tagName?e.add(e.$element.val()):a("option",e.$element).each(function(){e.add(a(this).attr("value"),!0)}))},destroy:function(){var a=this;a.$container.off("keypress","input"),a.$container.off("click","[role=remove]"),a.$container.remove(),a.$element.removeData("tagsinput"),a.$element.show()},focus:function(){this.$input.focus()},input:function(){return this.$input},findInputWrapper:function(){for(var b=this.$input[0],c=this.$container[0];b&&b.parentNode!==c;)b=b.parentNode;return a(b)}},a.fn.tagsinput=function(c,d){var e=[];return this.each(function(){var f=a(this).data("tagsinput");if(f){var g=f[c](d);void 0!==g&&e.push(g)}else f=new b(this,c),a(this).data("tagsinput",f),e.push(f),"SELECT"===this.tagName&&a("option",a(this)).attr("selected","selected"),a(this).val(a(this).val())}),"string"==typeof c?e.length>1?e:e[0]:e},a.fn.tagsinput.Constructor=b;var h=a("<div />");a(function(){a("input[data-role=tagsinput], select[multiple][data-role=tagsinput]").tagsinput()})}(window.jQuery);
+/*
+//@ sourceMappingURL=bootstrap-tagsinput.min.js.map
+*/ \ No newline at end of file
diff --git a/style/bootstrap-tagsinput.css b/style/bootstrap-tagsinput.css
new file mode 100644
index 00000000..98cfa7f3
--- /dev/null
+++ b/style/bootstrap-tagsinput.css
@@ -0,0 +1,45 @@
+.bootstrap-tagsinput {
+ background-color: #fff;
+ border: 1px solid #ccc;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ display: inline-block;
+ padding: 4px 6px;
+ margin-bottom: 10px;
+ color: #555;
+ vertical-align: middle;
+ border-radius: 4px;
+ max-width: 100%;
+ line-height: 22px;
+}
+.bootstrap-tagsinput input {
+ border: none;
+ box-shadow: none;
+ outline: none;
+ background-color: transparent;
+ padding: 0;
+ margin: 0;
+ width: auto !important;
+ max-width: inherit;
+}
+.bootstrap-tagsinput input:focus {
+ border: none;
+ box-shadow: none;
+}
+.bootstrap-tagsinput .tag {
+ margin-right: 2px;
+ color: white;
+}
+.bootstrap-tagsinput .tag [data-role="remove"] {
+ margin-left: 8px;
+ cursor: pointer;
+}
+.bootstrap-tagsinput .tag [data-role="remove"]:after {
+ content: "x";
+ padding: 0px 2px;
+}
+.bootstrap-tagsinput .tag [data-role="remove"]:hover {
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+.bootstrap-tagsinput .tag [data-role="remove"]:hover:active {
+ box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
+}
diff --git a/style/default.css b/style/default.css
index c846f261..1a4a0be0 100644
--- a/style/default.css
+++ b/style/default.css
@@ -49,3 +49,11 @@ body {
font-size: 90%;
font-style: italic;
}
+
+.bootstrap-tagsinput {
+ width: 100%;
+ margin: 0px;
+ border-radius: 0;
+ height: 34px;
+}
+
diff --git a/templates/page-syslog.html b/templates/page-syslog.html
index c741ab6b..c16d8da1 100644
--- a/templates/page-syslog.html
+++ b/templates/page-syslog.html
@@ -3,7 +3,7 @@
<form method="post" action="?do=syslog">
<div class="input-group">
<span class="input-group-addon">Filter</span>
- <input id="filterstring" type="text" class="form-control" placeholder="event-id" value="{{filter}}" name="filter">
+ <input id="filterstring" type="text" placeholder="event-id" value="{{filter}}" name="filter" data-role="tagsinput" />
<span class="input-group-addon">
<input type="checkbox" name="not" {{#not}}checked="checked"{{/not}}> not
</span>
@@ -12,6 +12,7 @@
</span>
</div>
</form>
+ {{{pagenav}}}
<table class="table table-striped table-condensed">
<thead>
<th></th>
@@ -23,7 +24,7 @@
<tbody>
{{#list}}
<tr>
- <td><span class="glyphicon glyphicon-off" title="{{logtypeid}}" onclick="$('#filterstring').val($('#filterstring').val() + ' {{logtypeid}}')"></span></td>
+ <td><span class="glyphicon glyphicon-off" title="{{logtypeid}}" onclick="$('#filterstring').tagsinput('add', '{{logtypeid}}')"></span></td>
<td class="text-right" nowrap="nowrap">{{date}}</td>
<td>{{clientip}}</td>
<td>{{description}}</td>
@@ -35,5 +36,6 @@
{{/list}}
</tbody>
</table>
+ {{{pagenav}}}
</div>
diff --git a/templates/page-tgz-list.html b/templates/page-tgz-list.html
index bcf5ffc0..fdc11933 100644
--- a/templates/page-tgz-list.html
+++ b/templates/page-tgz-list.html
@@ -17,8 +17,9 @@
{{^files}}
<div class="row well well-sm">Keine Konfigurationspakete gefunden!</div>
{{/files}}
- <a class="btn btn-lg btn-primary" href="?do=sysconfig&amp;action=remotelist">Konfigurationen herunterladen</a>
- <a class="btn btn-lg btn-primary" href="#" data-toggle="collapse" data-target="#uploadform">Eigene Konfiguration hochladen</a>
+ <a class="btn btn-md btn-primary" href="?do=sysconfig&amp;action=remotelist">Konfigurationsvolagen</a>
+ <a class="btn btn-md btn-primary" href="#" data-toggle="collapse" data-target="#uploadform">Eigene Konfiguration hochladen</a>
+ <a class="btn btn-md btn-primary" href="/boot/default/config.tgz">Aktive Konfiguration herunterladen</a>
<div class="collapse" id="uploadform">
<div class="well well-sm" style="margin: 5px 0px">
<form method="post" action="?do=sysconfig" enctype="multipart/form-data">
diff --git a/templates/pagenav.html b/templates/pagenav.html
new file mode 100644
index 00000000..5cab6a46
--- /dev/null
+++ b/templates/pagenav.html
@@ -0,0 +1,15 @@
+<ul class="pagination pagination-sm pull-right">
+ {{#pages}}
+ {{#current}}
+ <li class="active"><a href="{{url}}page={{page}}">{{text}} <span class="sr-only">(current)</span></a></li>
+ {{/current}}
+ {{^current}}
+ {{#text}}
+ <li><a href="{{url}}page={{page}}">{{text}}</a></li>
+ {{/text}}
+ {{^text}}
+ <li class="disabled"><a href="#">&hellip;</a></li>
+ {{/text}}
+ {{/current}}
+ {{/pages}}
+</ul>
diff --git a/updates/v2 b/updates/v2
new file mode 100644
index 00000000..e67a5437
--- /dev/null
+++ b/updates/v2
@@ -0,0 +1,43 @@
+SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
+SET time_zone = "+00:00";
+
+CREATE TABLE `cat_setting` (
+ `catid` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `name` varchar(250) NOT NULL,
+ `sortval` smallint(5) unsigned NOT NULL,
+ PRIMARY KEY (`catid`),
+ KEY `sortval` (`sortval`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
+
+INSERT INTO `cat_setting` (`catid`, `name`, `sortval`) VALUES
+(0, 'Unkategorisiert', 20000),
+(1, 'Inaktivität und Abschaltung', 30),
+(2, 'Internetzugriff', 20),
+(3, 'Zeitsynchronisation', 100),
+(4, 'Grundsystem', 10);
+
+ALTER TABLE `setting` ADD `catid` INT( 10 ) UNSIGNED NOT NULL AFTER `setting` ;
+ALTER TABLE `setting` ADD FOREIGN KEY ( `catid` ) REFERENCES `openslx`.`cat_setting` (`catid`) ON DELETE RESTRICT ON UPDATE CASCADE ;
+
+INSERT INTO `setting` (`setting`, `catid`, `defaultvalue`, `permissions`, `validator`, `description`) VALUES
+ ('SLX_LOGOUT_TIMEOUT', 1, '1800', 2, 'regex:/^\\d*$/', 'Zeit /in Sekunden/, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.\r\nFeld leer lassen, um die Funktion zu deaktivieren.'),
+ ('SLX_REMOTE_LOG_SESSIONS', 0, 'anonymous', 2, 'regex:/^(yes|anonymous|no)$/', 'Legt fest, ob Logins und Logouts der Benutzer an den Satelliten gemeldet werden sollen.\r\n*yes* = Mit Benutzerkennung loggen\r\n*anonymous* = Anonym loggen\r\n*no* = Nicht loggen'),
+ ('SLX_SHUTDOWN_SCHEDULE', 1, '22:10 00:00', 2, 'regex:/^(\\s*\\d{1,2}:\\d{1,2})*$/', 'Feste Uhrzeit, zu der sich die Rechner ausschalten, auch wenn noch ein Benutzer aktiv ist.\r\nMehrere Zeitpunkte können durch Leerzeichen getrennt angegeben werden.'),
+ ('SLX_SHUTDOWN_TIMEOUT', 1, '1200', 2, 'regex:/^\\d*$/', 'Zeit in Sekunden, nach dem ein Rechner abgeschaltet wird, sofern kein Benutzer angemeldet ist.\r\nFeld leer lassen, um die Funktion zu deaktivieren.');
+
+UPDATE setting SET catid = 0 WHERE setting = 'SLX_ADDONS' LIMIT 1;
+UPDATE setting SET catid = 0 WHERE setting = 'SLX_REMOTE_LOG_SESSIONS' LIMIT 1;
+UPDATE setting SET catid = 1 WHERE setting = 'SLX_LOGOUT_TIMEOUT' LIMIT 1;
+UPDATE setting SET catid = 1 WHERE setting = 'SLX_SHUTDOWN_SCHEDULE' LIMIT 1;
+UPDATE setting SET catid = 1 WHERE setting = 'SLX_SHUTDOWN_TIMEOUT' LIMIT 1;
+UPDATE setting SET catid = 2 WHERE setting = 'SLX_NET_DOMAIN' LIMIT 1;
+UPDATE setting SET catid = 2 WHERE setting = 'SLX_PROXY_BLACKLIST' LIMIT 1;
+UPDATE setting SET catid = 2 WHERE setting = 'SLX_PROXY_IP' LIMIT 1;
+UPDATE setting SET catid = 2 WHERE setting = 'SLX_PROXY_MODE' LIMIT 1;
+UPDATE setting SET catid = 2 WHERE setting = 'SLX_PROXY_PORT' LIMIT 1;
+UPDATE setting SET catid = 2 WHERE setting = 'SLX_PROXY_TYPE' LIMIT 1;
+UPDATE setting SET catid = 3 WHERE setting = 'SLX_BIOS_CLOCK' LIMIT 1;
+UPDATE setting SET catid = 3 WHERE setting = 'SLX_NTP_SERVER' LIMIT 1;
+UPDATE setting SET catid = 4 WHERE setting = 'SLX_ROOT_PASS' LIMIT 1;
+UPDATE setting SET catid = 4 WHERE setting = 'SLX_VM_NFS' LIMIT 1;
+