From 89370704762a0c9b76c3ad9d69ef0a737229e351 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 21 Apr 2017 18:23:11 +0200 Subject: [dozmod] Make images pending deletion an extra section --- modules-available/dozmod/page.inc.php | 61 +++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 24 deletions(-) (limited to 'modules-available') diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index 7f1e6ee3..9635aef1 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -32,7 +32,25 @@ class Page_DozMod extends Page Util::redirect('?do=Main'); } + /* execute actions */ + $action = Request::post('action', false, 'string'); + + if ($action === 'mail') { + $this->mailHandler(); + } elseif ($action === 'runtime') { + $this->runtimeHandler(); + } elseif ($action === 'delimages') { + $result = $this->handleDeleteImages(); + if (!empty($result)) { + Message::addInfo('delete-images', $result); + } + Util::redirect('?do=DozMod'); + } elseif ($action !== false) { + Util::traceError('Invalid action: ' . $action); + } + /* add sub-menus */ + Dashboard::addSubmenu('?do=dozmod§ion=expiredimages', Dictionary::translate('submenu_expiredimages', true)); Dashboard::addSubmenu('?do=dozmod§ion=mailconfig', Dictionary::translate('submenu_mailconfig', true)); Dashboard::addSubmenu('?do=dozmod§ion=templates', Dictionary::translate('submenu_templates', true)); Dashboard::addSubmenu('?do=dozmod§ion=runtimeconfig', Dictionary::translate('submenu_runtime', true)); @@ -44,37 +62,34 @@ class Page_DozMod extends Page $this->subPage->doPreprocess(); return; } - - /* execute actions */ - $action = Request::post('action'); - - if ($action === 'mail') { - $this->mailHandler(); - } - if ($action === 'runtime') { - $this->runtimeHandler(); - } - if ($action === 'delimages') { - $result = $this->handleDeleteImages(); - if (!empty($result)) { - Message::addInfo('delete-images', $result); - } - Util::redirect('?do=DozMod'); - } } protected function doRender() { - $this->listDeletePendingImages(); - /* different pages for different sections */ if ($this->subPage !== false) { $this->subPage->doRender(); return; } - $section = Request::get('section', 'mailconfig', 'string'); + $section = Request::get('section', false, 'string'); + + if ($section === false || $section === 'expiredimages') { + $expiredImages = $this->loadExpiredImages(); + if ($section === false && empty($expiredImages)) { + $section = 'mailconfig'; + } else { + $section = 'expiredimages'; + } + } + if ($section === 'expiredimages') { + if (empty($expiredImages)) { + Message::addSuccess('no-expired-images'); + } else { + Render::addTemplate('images-delete', array('images' => $expiredImages)); + } + } if ($section === 'mailconfig') { // Mail config $mailConf = Database::queryFirst('SELECT value FROM sat.configuration WHERE parameter = :param', array('param' => 'mailconfig')); @@ -140,7 +155,7 @@ class Page_DozMod extends Page Render::addTemplate('blockstats', $data); } - private function listDeletePendingImages() + private function loadExpiredImages() { $res = Database::simpleQuery("SELECT b.displayname," . " own.firstname, own.lastname, own.email," @@ -168,9 +183,7 @@ class Page_DozMod extends Page $row['filesize'] = Util::readableFileSize($row['filesize']); $rows[] = $row; } - if (empty($rows)) - return; - Render::addTemplate('images-delete', array('images' => $rows)); + return $rows; } private function cleanMailArray() -- cgit v1.2.3-55-g7522 From e9aa7ceb89c487f5d2c2bb102f67618ebfcae08b Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 24 Apr 2017 16:05:13 +0200 Subject: [statistics_reporting] Extend remote report by hwstats, date ranges, userstats This implements #3108 --- .../statistics_reporting/hooks/cron.inc.php | 3 +- .../statistics_reporting/inc/getdata.inc.php | 1 + .../statistics_reporting/inc/queries.inc.php | 63 ++++++++++++++++++++++ .../statistics_reporting/inc/remotereport.inc.php | 62 +++++++++++++++++---- .../statistics_reporting/page.inc.php | 2 +- 5 files changed, 119 insertions(+), 12 deletions(-) (limited to 'modules-available') diff --git a/modules-available/statistics_reporting/hooks/cron.inc.php b/modules-available/statistics_reporting/hooks/cron.inc.php index afb18a23..14597f7d 100644 --- a/modules-available/statistics_reporting/hooks/cron.inc.php +++ b/modules-available/statistics_reporting/hooks/cron.inc.php @@ -7,10 +7,9 @@ if (RemoteReport::isReportingEnabled()) { while ($nextReporting <= time()) { RemoteReport::writeNextReportingTimestamp(); - $from = strtotime("-7 days", $nextReporting); $to = $nextReporting; - $statisticsReport = json_encode(RemoteReport::generateReport($from, $to)); + $statisticsReport = json_encode(RemoteReport::generateReport($to)); $params = array("action" => "statistics", "data" => $statisticsReport); diff --git a/modules-available/statistics_reporting/inc/getdata.inc.php b/modules-available/statistics_reporting/inc/getdata.inc.php index da3a9a26..ae4d5aa4 100644 --- a/modules-available/statistics_reporting/inc/getdata.inc.php +++ b/modules-available/statistics_reporting/inc/getdata.inc.php @@ -29,6 +29,7 @@ class GetData $data["medianSessionLength_s"] = self::formatSeconds($data["medianSessionLength"]); $data["totalOffTime_s"] = self::formatSeconds($data["totalOffTime"]); } + $data['uniqueUsers'] = Queries::getUniqueUserCount(self::$from, self::$to); return $data; } diff --git a/modules-available/statistics_reporting/inc/queries.inc.php b/modules-available/statistics_reporting/inc/queries.inc.php index 2269e764..1a125c9e 100644 --- a/modules-available/statistics_reporting/inc/queries.inc.php +++ b/modules-available/statistics_reporting/inc/queries.inc.php @@ -213,5 +213,68 @@ class Queries "; return "(".$queryString.")"; } + + public static function getDozmodStats($from, $to) + { + if (!Module::isAvailable('dozmod')) + return array('disabled' => true); + + $return = array(); + $return['vms'] = Database::queryFirst("SELECT Count(*) AS `total`, Sum(If(createtime >= $from, 1, 0)) AS `new`, + Sum(If(updatetime >= $from, 1, 0)) AS `updated`, Sum(If(latestversionid IS NOT NULL, 1, 0)) AS `valid` + FROM sat.imagebase + WHERE createtime <= $to"); + $return['lectures'] = Database::queryFirst("SELECT Count(*) AS `total`, Sum(If(createtime >= $from, 1, 0)) AS `new`, + Sum(If(updatetime >= $from, 1, 0)) AS `updated`, + Sum(If((($from BETWEEN starttime AND endtime) OR ($to BETWEEN starttime AND endtime)) AND isenabled <> 0, 1, 0)) AS `valid` + FROM sat.lecture + WHERE createtime <= $to"); + $return['users'] = Database::queryFirst("SELECT Count(*) AS `total`, Count(DISTINCT organizationid) AS `organizations` + FROM sat.user + WHERE lastlogin >= $from"); + return $return; + } + + public static function getAggregatedMachineStats($from) + { + $return = array(); + $return['location'] = Database::queryAll("SELECT MD5(CONCAT(locationid, :salt)) AS `location`, Count(*) AS `count` + FROM machine + WHERE lastseen >= $from + GROUP BY locationid", + array('salt' => GetData::$salt)); + $prev = 0; + $str = ' '; + foreach (array(0.5, 1, 1.5, 2, 3, 4, 6, 8, 10, 12, 16, 20, 24, 28, 32, 40, 48, 64, 72, 80, 88, 96, 128, 192, 256) as $val) { + $str .= 'WHEN mbram < ' . round(($val + $prev) * 512) . " THEN '" . $prev . "' "; + $prev = $val; + } + $return['ram'] = Database::queryAll("SELECT CASE $str ELSE 'OVER 9000' END AS `gbram`, Count(*) AS `total` + FROM machine + WHERE lastseen >= $from + GROUP BY gbram"); + foreach (array('cpumodel', 'systemmodel', 'realcores', 'kvmstate') as $key) { + $return[$key] = Database::queryAll("SELECT $key, Count(*) AS `total` + FROM machine + WHERE lastseen >= $from + GROUP BY $key"); + } + return $return; + } + + /** + * @param int $from start timestamp + * @param int $to end timestamp + * @return int count of user active in timespan + */ + public static function getUniqueUserCount($from, $to) + { + $res = Database::queryFirst("SELECT Count(DISTINCT username) as `total` + FROM statistic + WHERE (dateline BETWEEN $from AND $to) AND typeid = '.vmchooser-session-name' + GROUP BY username"); + return (int)$res['total']; + } + } diff --git a/modules-available/statistics_reporting/inc/remotereport.inc.php b/modules-available/statistics_reporting/inc/remotereport.inc.php index 4c5f604b..68a3e95e 100644 --- a/modules-available/statistics_reporting/inc/remotereport.inc.php +++ b/modules-available/statistics_reporting/inc/remotereport.inc.php @@ -63,19 +63,63 @@ class RemoteReport * Generate the multi-dimensional array containing the anonymized * (weekly) statistics to report. * - * @param int $from start timestamp * @param int $to end timestamp + * @param int[] $days list of days to generate aggregated stats for * @return array wrapped up statistics, ready for reporting */ - public static function generateReport($from, $to) { - GetData::$from = $from; - GetData::$to = $to; + public static function generateReport($to, $days = false) { + if ($days === false) { + $days = [7, 30, 90]; + } GetData::$salt = bin2hex(Util::randomBytes(20, false)); - $data = GetData::total(GETDATA_ANONYMOUS); - $data['perLocation'] = GetData::perLocation(GETDATA_ANONYMOUS); - $data['perVM'] = GetData::perVM(GETDATA_ANONYMOUS); - $data['tsFrom'] = $from; - $data['tsTo'] = $to; + GetData::$lowerTimeBound = 7; + GetData::$upperTimeBound = 20; + $result = array(); + foreach ($days as $day) { + if (isset($result['days' . $day])) + continue; + $from = strtotime("-{$day} days", $to); + GetData::$from = $from; + GetData::$to = $to; + $data = array('total' => GetData::total(GETDATA_ANONYMOUS)); + $data['perLocation'] = GetData::perLocation(GETDATA_ANONYMOUS); + $data['perVM'] = GetData::perVM(GETDATA_ANONYMOUS); + $data['tsFrom'] = $from; + $data['tsTo'] = $to; + $data['dozmod'] = Queries::getDozmodStats($from, $to); + $data['machines'] = Queries::getAggregatedMachineStats($from); + $result['days' . $day] = $data; + } + $result['server'] = self::getLocalHardware(); + $result['version'] = CONFIG_FOOTER; + return $result; + } + + private function getLocalHardware() + { + $cpuInfo = file_get_contents('/proc/cpuinfo'); + $uptime = file_get_contents('/proc/uptime'); + $memInfo = file_get_contents('/proc/meminfo'); + preg_match_all('/\b(\w+):\s+(\d+)\s/s', $memInfo, $out, PREG_SET_ORDER); + $mem = array(); + foreach ($out as $e) { + $mem[$e[1]] = $e[2]; + } + // + $data = array(); + $data['cpuCount'] = preg_match_all('/\bprocessor\s+:\s+(.*)$/m', $cpuInfo, $out); + if ($data['cpuCount'] > 0) { + $data['cpuModel'] = $out[1][0]; + } + if (preg_match('/^(\d+)\D/', $uptime, $out)) { + $data['uptime'] = $out[1]; + } + if (isset($mem['MemTotal']) && isset($mem['MemFree']) && isset($mem['SwapTotal'])) { + $data['memTotal'] = $mem['MemTotal']; + $data['memFree'] = ($mem['MemFree'] + $mem['Buffers'] + $mem['Cached']); + $data['swapTotal'] = $mem['SwapTotal']; + $data['swapUsed'] = ($mem['SwapTotal'] - $mem['SwapFree']); + } return $data; } diff --git a/modules-available/statistics_reporting/page.inc.php b/modules-available/statistics_reporting/page.inc.php index 6bd908a5..52accaea 100644 --- a/modules-available/statistics_reporting/page.inc.php +++ b/modules-available/statistics_reporting/page.inc.php @@ -58,7 +58,7 @@ class Page_Statistics_Reporting extends Page // Get report - fetch data exactly the way it would automatically be reported // so the user can know what is going on if ($this->action === 'getreport') { - $report = RemoteReport::generateReport(strtotime('-7 days'), time('now')); + $report = RemoteReport::generateReport(time()); Header('Content-Disposition: attachment; filename=remote-report.json'); Header('Content-Type: application/json; charset=utf-8'); die(json_encode($report)); -- cgit v1.2.3-55-g7522 From 0f154dc9f28c9682bba714b534dc1944984a287d Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 25 Apr 2017 15:49:59 +0200 Subject: [baseconfig_bwlp] Add SLX_AUTOSTART_UUID setting This completely implements #3070 --- modules-available/baseconfig_bwlp/baseconfig/settings.json | 6 ++++++ modules-available/baseconfig_bwlp/lang/de/config-variables.json | 1 + modules-available/baseconfig_bwlp/lang/en/config-variables.json | 1 + 3 files changed, 8 insertions(+) (limited to 'modules-available') diff --git a/modules-available/baseconfig_bwlp/baseconfig/settings.json b/modules-available/baseconfig_bwlp/baseconfig/settings.json index e9a0a894..3eebcc1f 100644 --- a/modules-available/baseconfig_bwlp/baseconfig/settings.json +++ b/modules-available/baseconfig_bwlp/baseconfig/settings.json @@ -132,5 +132,11 @@ "defaultvalue": "", "permissions": "2", "validator": "" + }, + "SLX_AUTOSTART_UUID": { + "catid": "vmchooser", + "defaultvalue": "", + "permissions": "2", + "validator": "regex:\/^([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|)$\/i" } } diff --git a/modules-available/baseconfig_bwlp/lang/de/config-variables.json b/modules-available/baseconfig_bwlp/lang/de/config-variables.json index 63ddf280..3d7bbb2f 100644 --- a/modules-available/baseconfig_bwlp/lang/de/config-variables.json +++ b/modules-available/baseconfig_bwlp/lang/de/config-variables.json @@ -1,5 +1,6 @@ { "SLX_ADDONS": "Zu ladende Addons. Zur Zeit steht nur *vmware* zur Verf\u00fcgung.", + "SLX_AUTOSTART_UUID": "Geben Sie hier eine Veranstaltungs-ID ein. Sie finden diese im Detailfenster innerhalb der bwLehrpool-Suite. Die angegebene Veranstaltung wird nach erfolgreichem Login automatisch gestartet. \r\n\r\n*Hinweis: Diese Option ist eine tempor\u00e4re \u00dcbergangsl\u00f6sung. In sp\u00e4teren Versionen wird die Funktionalit\u00e4t einfacher erreichbar sein.*", "SLX_BIOS_CLOCK": "Legt fest, ob und wie die interne Uhr des Rechners im Bezug auf die Systemzeit des \/MiniLinux\/ gesetzt werden soll.\r\n*off* = Die interne Uhr des Rechners wird nicht ver\u00e4ndert.\r\n*local* = Die interne Uhr wird auf die Lokalzeit gesetzt. Bevorzugt wenn z.B. noch eine native Windows-Installation auf dem PC vorhanden ist.\r\n*utc* = Die interne Uhr wird auf die \/Koordinierte Weltzeit\/ gesetzt. Dies ist die g\u00e4ngige Einstellung in einem reinen Linux-Umfeld.", "SLX_DEMO_PASS": "Passwort f\u00fcr den eingebauten *demo*-Account. Leer lassen, um das Einloggen zu verbieten.\r\nDas Passwort wird wie das root-Passwort nur gehasht an den Client \u00fcbertragen.", "SLX_LOGOUT_TIMEOUT": "Zeit \/in Sekunden\/, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.Feld leer lassen, um die Funktion zu deaktivieren.", diff --git a/modules-available/baseconfig_bwlp/lang/en/config-variables.json b/modules-available/baseconfig_bwlp/lang/en/config-variables.json index ad1601c3..b6022245 100644 --- a/modules-available/baseconfig_bwlp/lang/en/config-variables.json +++ b/modules-available/baseconfig_bwlp/lang/en/config-variables.json @@ -1,5 +1,6 @@ { "SLX_ADDONS": "Addons to load. Currently, only *vmware* is available.", + "SLX_AUTOSTART_UUID": "Insert a lecture-id which you'll find in the bwLehrpool-Suite detail window of a lecture. This will automatically start the given lecture after a successful login.\r\n\r\n*This solution is only temporary*", "SLX_BIOS_CLOCK": "Specifies whether and how the internal clock of the computer should be set in relation to the system time of the \/MiniLinux\/.\r\n*off* = The internal clock of the computer is not changed.\r\n*local* = The internal clock is set to local time. Preferably if, for example, there is still a native Windows installation available on the PC.\r\n*utc* = The internal clock is set to the \/Coordinated Universal Time\/. This is the most common setup in a pure Linux environment.", "SLX_DEMO_PASS": "Password for the *demo* account. Leave empty to disallow logging in as the demo user.\r\nLike the root password, the demo user's password will be sent to the client in its hashed form.", "SLX_LOGOUT_TIMEOUT": "Time \/in seconds\/, in which a user session may remain without action before it is terminated.Leave field blank to disable the function.", -- cgit v1.2.3-55-g7522 From 43f3dcb67ce133c9d0b790b4033ee0ee66085228 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 26 Apr 2017 10:28:32 +0200 Subject: [baseconfig_bwlp] Update translations --- modules-available/baseconfig_bwlp/lang/de/config-variables.json | 2 +- modules-available/baseconfig_bwlp/lang/en/config-variables.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'modules-available') diff --git a/modules-available/baseconfig_bwlp/lang/de/config-variables.json b/modules-available/baseconfig_bwlp/lang/de/config-variables.json index 3d7bbb2f..a19c89ac 100644 --- a/modules-available/baseconfig_bwlp/lang/de/config-variables.json +++ b/modules-available/baseconfig_bwlp/lang/de/config-variables.json @@ -1,6 +1,6 @@ { "SLX_ADDONS": "Zu ladende Addons. Zur Zeit steht nur *vmware* zur Verf\u00fcgung.", - "SLX_AUTOSTART_UUID": "Geben Sie hier eine Veranstaltungs-ID ein. Sie finden diese im Detailfenster innerhalb der bwLehrpool-Suite. Die angegebene Veranstaltung wird nach erfolgreichem Login automatisch gestartet. \r\n\r\n*Hinweis: Diese Option ist eine tempor\u00e4re \u00dcbergangsl\u00f6sung. In sp\u00e4teren Versionen wird die Funktionalit\u00e4t einfacher erreichbar sein.*", + "SLX_AUTOSTART_UUID": "ID einer Veranstaltung die automatisch gestartet werden soll. Die Veranstaltungs-ID finden Sie im Detailfenster innerhalb der bwLehrpool-Suite.\r\n\r\n*Hinweis: Diese Option ist eine tempor\u00e4re \u00dcbergangsl\u00f6sung. In sp\u00e4teren Versionen wird die Funktionalit\u00e4t einfacher erreichbar sein.*", "SLX_BIOS_CLOCK": "Legt fest, ob und wie die interne Uhr des Rechners im Bezug auf die Systemzeit des \/MiniLinux\/ gesetzt werden soll.\r\n*off* = Die interne Uhr des Rechners wird nicht ver\u00e4ndert.\r\n*local* = Die interne Uhr wird auf die Lokalzeit gesetzt. Bevorzugt wenn z.B. noch eine native Windows-Installation auf dem PC vorhanden ist.\r\n*utc* = Die interne Uhr wird auf die \/Koordinierte Weltzeit\/ gesetzt. Dies ist die g\u00e4ngige Einstellung in einem reinen Linux-Umfeld.", "SLX_DEMO_PASS": "Passwort f\u00fcr den eingebauten *demo*-Account. Leer lassen, um das Einloggen zu verbieten.\r\nDas Passwort wird wie das root-Passwort nur gehasht an den Client \u00fcbertragen.", "SLX_LOGOUT_TIMEOUT": "Zeit \/in Sekunden\/, die eine Benutzersitzung ohne Aktion sein darf, bevor sie beendet wird.Feld leer lassen, um die Funktion zu deaktivieren.", diff --git a/modules-available/baseconfig_bwlp/lang/en/config-variables.json b/modules-available/baseconfig_bwlp/lang/en/config-variables.json index b6022245..64788fee 100644 --- a/modules-available/baseconfig_bwlp/lang/en/config-variables.json +++ b/modules-available/baseconfig_bwlp/lang/en/config-variables.json @@ -1,6 +1,6 @@ { "SLX_ADDONS": "Addons to load. Currently, only *vmware* is available.", - "SLX_AUTOSTART_UUID": "Insert a lecture-id which you'll find in the bwLehrpool-Suite detail window of a lecture. This will automatically start the given lecture after a successful login.\r\n\r\n*This solution is only temporary*", + "SLX_AUTOSTART_UUID": "ID of a lecture which is automatically started. The lecture-ID is found in the detail window of a lecture in the bwLehrpool-Suite. \r\n\r\n*This solution is only temporary. In later versions this feature will probably be moved to another section*", "SLX_BIOS_CLOCK": "Specifies whether and how the internal clock of the computer should be set in relation to the system time of the \/MiniLinux\/.\r\n*off* = The internal clock of the computer is not changed.\r\n*local* = The internal clock is set to local time. Preferably if, for example, there is still a native Windows installation available on the PC.\r\n*utc* = The internal clock is set to the \/Coordinated Universal Time\/. This is the most common setup in a pure Linux environment.", "SLX_DEMO_PASS": "Password for the *demo* account. Leave empty to disallow logging in as the demo user.\r\nLike the root password, the demo user's password will be sent to the client in its hashed form.", "SLX_LOGOUT_TIMEOUT": "Time \/in seconds\/, in which a user session may remain without action before it is terminated.Leave field blank to disable the function.", -- cgit v1.2.3-55-g7522 From 2a368cb3e597e35b467a6aebbaf35d42747681f5 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 26 Apr 2017 15:34:58 +0200 Subject: [baseconfig] Display inherited value and source when editing module specific settings This optionally requires a callback to find the inheritance source in the module in question. The locations module was updated accordingly. This implements #3120 --- .../baseconfig/lang/de/template-tags.json | 4 +- .../baseconfig/lang/en/template-tags.json | 4 +- modules-available/baseconfig/page.inc.php | 65 ++++++++++++++++------ modules-available/baseconfig/templates/_page.html | 16 ++++-- modules-available/locations/baseconfig/hook.json | 3 +- modules-available/locations/inc/location.inc.php | 16 ++++++ 6 files changed, 81 insertions(+), 27 deletions(-) (limited to 'modules-available') diff --git a/modules-available/baseconfig/lang/de/template-tags.json b/modules-available/baseconfig/lang/de/template-tags.json index cdd54f6a..7d6da790 100644 --- a/modules-available/baseconfig/lang/de/template-tags.json +++ b/modules-available/baseconfig/lang/de/template-tags.json @@ -1,7 +1,9 @@ { "lang_basicConfiguration": "Basiskonfiguration", "lang_clientRelatedConfig": "Die Optionen auf dieser Seite beziehen sich auf das Verhalten der bwLehrpool-Clients.", + "lang_defaultValue": "Standard", "lang_editOverrideNotice": "Sie bearbeiten die Einstellungen f\u00fcr einen Unterbereich", "lang_enableOverride": "\u00dcberschreiben", - "lang_settingActive": "Einstellung aktiv" + "lang_inheritSource": "Geerbt von", + "lang_settingActive": "Einstellung aktivieren" } \ 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 8e75e5ac..1a32cb0d 100644 --- a/modules-available/baseconfig/lang/en/template-tags.json +++ b/modules-available/baseconfig/lang/en/template-tags.json @@ -1,7 +1,9 @@ { "lang_basicConfiguration": "Basic Configuration", "lang_clientRelatedConfig": "The options on this page are related to the bwLehrpool client machines.", + "lang_defaultValue": "Default", "lang_editOverrideNotice": "You're editing the settings of a sub-section", "lang_enableOverride": "Override", - "lang_settingActive": "Setting active" + "lang_inheritSource": "Inherited from", + "lang_settingActive": "Enable setting" } \ No newline at end of file diff --git a/modules-available/baseconfig/page.inc.php b/modules-available/baseconfig/page.inc.php index 5e99f2a0..bd9d6683 100644 --- a/modules-available/baseconfig/page.inc.php +++ b/modules-available/baseconfig/page.inc.php @@ -124,9 +124,6 @@ class Page_BaseConfig extends Page Util::redirect('?do=BaseConfig'); } } - // List config options - $settings = array(); - $vars = BaseConfigUtil::getVariables(); // Get stuff that's set in DB already if ($this->targetModule === false) { $fields = ', enabled'; @@ -141,19 +138,28 @@ class Page_BaseConfig extends Page $where = ''; $params = array(); } + // List config options + $settings = array(); + $vars = BaseConfigUtil::getVariables(); + // Remember missing variables + $missing = $vars; // Populate structure with existing config from db - $res = Database::simpleQuery("SELECT setting, value, displayvalue $fields 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; + $this->fillSettings($vars, $settings, $missing, $this->qry_extra['table'], $fields, $where, $params, false); + if (isset($this->qry_extra['getfallback']) && !empty($missing)) { + $method = explode('::', $this->qry_extra['getfallback']); + $fieldValue = $this->qry_extra['field_value']; + $tries = 0; + while (++$tries < 100 && !empty($missing)) { + $ret = call_user_func($method, $fieldValue); + if ($ret === false) + break; + $fieldValue = $ret['value']; + $params = array('field_value' => $fieldValue); + $this->fillSettings($vars, $settings, $missing, $this->qry_extra['table'], $fields, $where, $params, $ret['display']); } - $row += $vars[$row['setting']]; - if (!isset($row['catid'])) { - $row['catid'] = 'unknown'; - } - $settings[$row['catid']]['settings'][$row['setting']] = $row; + } + if ($this->targetModule !== false && !empty($missing)) { + $this->fillSettings($vars, $settings, $missing, 'setting_global', '', '', array(), 'Global'); } // Add entries that weren't in the db (global), setup override checkbox (module specific) foreach ($vars as $key => $var) { @@ -162,10 +168,7 @@ class Page_BaseConfig extends Page if (!isset($settings[$var['catid']]['settings'][$key]['enabled']) || $settings[$var['catid']]['settings'][$key]['enabled'] == 1) { $settings[$var['catid']]['settings'][$key]['checked'] = 'checked'; } - } elseif (isset($settings[$var['catid']]['settings'][$key])) { - // Module specific - value is set in DB - $settings[$var['catid']]['settings'][$key]['checked'] = 'checked'; - } else { + } elseif (!isset($settings[$var['catid']]['settings'][$key])) { // Module specific - value is not set in DB $settings[$var['catid']]['settings'][$key] = $var + array( 'setting' => $key @@ -216,6 +219,32 @@ class Page_BaseConfig extends Page Module::isAvailable('bootstrap_switch'); } + private function fillSettings($vars, &$settings, &$missing, $table, $fields, $where, $params, $sourceName) + { + $res = Database::simpleQuery("SELECT setting, value, displayvalue $fields FROM $table " + . " {$where} ORDER BY setting ASC", $params); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + if (!isset($missing[$row['setting']])) + continue; + if (!isset($vars[$row['setting']]) || !is_array($vars[$row['setting']])) { + $unknown[] = $row['setting']; + continue; + } + unset($missing[$row['setting']]); + if ($sourceName !== false) { + $row['defaultvalue'] = ''; + $row['defaultsource'] = $sourceName; + } elseif ($this->targetModule !== false) { + $row['checked'] = 'checked'; + } + $row += $vars[$row['setting']]; + if (!isset($row['catid'])) { + $row['catid'] = 'unknown'; + } + $settings[$row['catid']]['settings'][$row['setting']] = $row; + } + } + private function getCurrentModuleName() { if (isset($this->qry_extra['tostring'])) { diff --git a/modules-available/baseconfig/templates/_page.html b/modules-available/baseconfig/templates/_page.html index 7f380495..e0be35bc 100644 --- a/modules-available/baseconfig/templates/_page.html +++ b/modules-available/baseconfig/templates/_page.html @@ -25,18 +25,22 @@
{{setting}}
- {{^override}}
+ {{#defaultvalue}}{{lang_defaultValue}}:{{/defaultvalue}} {{defaultvalue}}
- - {{/override}} - {{#override}} - - {{/override}} + +
{{{item}}} +
+ {{#defaultsource}}{{lang_inheritSource}}:{{/defaultsource}} + {{defaultsource}} +
diff --git a/modules-available/locations/baseconfig/hook.json b/modules-available/locations/baseconfig/hook.json index c295e0f6..b7b3581b 100644 --- a/modules-available/locations/baseconfig/hook.json +++ b/modules-available/locations/baseconfig/hook.json @@ -1,5 +1,6 @@ { "table": "setting_location", "field": "locationid", - "tostring": "Location::getName" + "tostring": "Location::getName", + "getfallback": "Location::getBaseconfigParent" } \ No newline at end of file diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php index 73080094..9977379f 100644 --- a/modules-available/locations/inc/location.inc.php +++ b/modules-available/locations/inc/location.inc.php @@ -279,6 +279,22 @@ class Location return $matchingLocations; } + /** + * @param $locationId + * @return bool|array ('value' => x, 'display' => y), false if no parent or unknown id + */ + public static function getBaseconfigParent($locationId) + { + settype($locationId, 'integer'); + $locations = Location::getLocationsAssoc(); + if (!isset($locations[$locationId])) + return false; + $locationId = (int)$locations[$locationId]['parentlocationid']; + if (!isset($locations[$locationId])) + return false; + return array('value' => $locationId, 'display' => $locations[$locationId]['locationname']); + } + /** * @return array list of subnets as numeric array */ -- cgit v1.2.3-55-g7522