From 5135886f2584631a414eb08e57d4ebdd2c48d611 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 10 Aug 2016 11:18:12 +0200 Subject: Add fallback feature to Dictionary functions --- inc/dictionary.inc.php | 12 +++++++++--- modules-available/baseconfig/page.inc.php | 2 +- modules-available/dozmod/page.inc.php | 8 ++++---- modules-available/statistics/inc/filterset.inc.php | 2 +- modules-available/translation/page.inc.php | 2 +- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/inc/dictionary.inc.php b/inc/dictionary.inc.php index cb23d0b2..634b1c3c 100644 --- a/inc/dictionary.inc.php +++ b/inc/dictionary.inc.php @@ -69,10 +69,13 @@ class Dictionary return self::$stringCache[$file] = $json; } - public static function translateFileModule($moduleId, $path, $tag) + public static function translateFileModule($moduleId, $path, $tag, $returnTagOnMissing = false) { $strings = self::getArray($moduleId, $path); if (!isset($strings[$tag])) { + if ($returnTagOnMissing) { + return '{{' . $tag . '}}'; + } return false; } return $strings[$tag]; @@ -85,12 +88,15 @@ class Dictionary return self::translateFileModule(Page::getModule()->getIdentifier(), $path, $tag); } - public static function translate($tag) + public static function translate($tag, $returnTagOnMissing = false) { $string = self::translateFile('module', $tag); if ($string !== false) return $string; - return self::translateFileModule('main', 'global-tags', $tag); + $string = self::translateFileModule('main', 'global-tags', $tag); + if ($string !== false || !$returnTagOnMissing) + return $string; + return '{{' . $tag . '}}'; } public static function getMessage($module, $id) diff --git a/modules-available/baseconfig/page.inc.php b/modules-available/baseconfig/page.inc.php index 0995a369..9ff8c086 100644 --- a/modules-available/baseconfig/page.inc.php +++ b/modules-available/baseconfig/page.inc.php @@ -103,7 +103,7 @@ class Page_BaseConfig extends Page foreach ($this->categories as $catid => $val) { Dashboard::addSubmenu( '#category_' . $catid, - Dictionary::translateFileModule($this->categories[$catid]['module'], 'config-variable-categories', $catid) + Dictionary::translateFileModule($this->categories[$catid]['module'], 'config-variable-categories', $catid, true) ); } } diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index c1c19b15..31d4cce2 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -15,10 +15,10 @@ class Page_DozMod extends Page } /* add sub-menus */ - Dashboard::addSubmenu('?do=dozmod§ion=mailconfig', Dictionary::translate('submenu_mailconfig')); - Dashboard::addSubmenu('?do=dozmod§ion=templates', Dictionary::translate('submenu_templates')); - Dashboard::addSubmenu('?do=dozmod§ion=runtimeconfig', Dictionary::translate('submenu_runtime')); - Dashboard::addSubmenu('?do=dozmod§ion=users', Dictionary::translate('submenu_users')); + 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)); + Dashboard::addSubmenu('?do=dozmod§ion=users', Dictionary::translate('submenu_users', true)); /* instantiate sub pages */ $this->mail_templates = new Page_mail_templates(); diff --git a/modules-available/statistics/inc/filterset.inc.php b/modules-available/statistics/inc/filterset.inc.php index 7cc075c3..ea25d9b1 100644 --- a/modules-available/statistics/inc/filterset.inc.php +++ b/modules-available/statistics/inc/filterset.inc.php @@ -15,7 +15,7 @@ class FilterSet { $this->sortDirection = $direction === 'DESC' ? 'DESC' : 'ASC'; - if (array_key_exists($col, Page_Statistics::$columns)) { + if (is_string($col) && array_key_exists($col, Page_Statistics::$columns)) { $isMapped = array_key_exists('map_sort', Page_Statistics::$columns[$col]); $this->sortColumn = $isMapped ? Page_Statistics::$columns[$col]['map_sort'] : $col; } else { diff --git a/modules-available/translation/page.inc.php b/modules-available/translation/page.inc.php index 563ffae0..93616cd1 100644 --- a/modules-available/translation/page.inc.php +++ b/modules-available/translation/page.inc.php @@ -474,7 +474,7 @@ class Page_Translation extends Page if ($module === false) { $module = $this->module; } - $tags = $this->loadTagsFromPhp('/Dictionary\s*::\s*translate\s*\(\s*[\'"](?[^\'"\.]*)[\'"]\s*\)/i', + $tags = $this->loadTagsFromPhp('/Dictionary\s*::\s*translate\s*\(\s*[\'"](?[^\'"\.]*)[\'"]\s*[\),]/i', $this->getModulePhpFiles($module)); foreach ($tags as &$tag) { $tag = true; -- cgit v1.2.3-55-g7522 From 0491f5070c2e1c0931aeb74d06cd47101e9fdcd9 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 10 Aug 2016 12:24:01 +0200 Subject: [baseconfig] Make shadow definition a json (sub)object; fix some display errors --- .../baseconfig/inc/baseconfigutil.inc.php | 22 ++++++++++++ modules-available/baseconfig/page.inc.php | 41 ++++++++++++---------- modules-available/baseconfig/templates/_page.html | 36 +++++++++---------- .../baseconfig_bwlp/baseconfig/settings.json | 9 ++++- 4 files changed, 71 insertions(+), 37 deletions(-) diff --git a/modules-available/baseconfig/inc/baseconfigutil.inc.php b/modules-available/baseconfig/inc/baseconfigutil.inc.php index ebaefbcf..75173ee6 100644 --- a/modules-available/baseconfig/inc/baseconfigutil.inc.php +++ b/modules-available/baseconfig/inc/baseconfigutil.inc.php @@ -47,4 +47,26 @@ class BaseConfigUtil return $categories; } + /** + * Mark variables that would be shadowed according to the given values. + * + * @param $vars list of vars as obtained from BaseConfigUtil::getVariables() + * @param $values key-value-pairs of variable assignments to work with + */ + public static function markShadowedVars(&$vars, $values) { + foreach ($vars as $key => &$var) { + if (!isset($var['shadows'])) + continue; + foreach ($var['shadows'] as $triggerVal => $destSettings) { + if (isset($values[$key]) && $values[$key] !== $triggerVal) + continue; + foreach ($destSettings as $destSetting) { + if (isset($vars[$destSetting])) { + $vars[$destSetting]['shadowed'] = true; + } + } + } + } + } + } diff --git a/modules-available/baseconfig/page.inc.php b/modules-available/baseconfig/page.inc.php index 9ff8c086..5e99f2a0 100644 --- a/modules-available/baseconfig/page.inc.php +++ b/modules-available/baseconfig/page.inc.php @@ -49,14 +49,16 @@ class Page_BaseConfig extends Page Util::redirect('?do=BaseConfig'); } } - //echo "
";
-			//var_dump($_POST);
-			//echo "
"; // Honor override/enabled checkbox $override = Request::post('override', array()); // Load all existing config options to validate input $vars = BaseConfigUtil::getVariables(); + // First, handle shadowing so we don't create warnings for empty fields + BaseConfigUtil::markShadowedVars($vars, $newValues); + // Validate input foreach ($vars as $key => $var) { + if (isset($var['shadowed'])) + continue; if ($this->targetModule === false) { // Global mode $params['enabled'] = (is_array($override) && isset($override[$key]) && $override[$key] === 'on') ? 1 : 0; @@ -180,12 +182,13 @@ class Page_BaseConfig extends Page //echo ""; $settings[$var['catid']]['settings'][$key] += array( 'item' => $this->makeInput( - $var['validator'], - $key, - $settings[$var['catid']]['settings'][$key]['displayvalue'], - $settings[$var['catid']]['settings'][$key]['shadows'] - ), - 'description' => Util::markup(Dictionary::translateFileModule($var['module'], 'config-variables', $key)) + $var['validator'], + $key, + $settings[$var['catid']]['settings'][$key]['displayvalue'], + $settings[$var['catid']]['settings'][$key]['shadows'] + ), + 'description' => Util::markup(Dictionary::translateFileModule($var['module'], 'config-variables', $key)), + 'setting' => $key, ); } //die(); @@ -264,10 +267,9 @@ class Page_BaseConfig extends Page private function makeInput($validator, $setting, $current, $shadows) { /* for the html snippet we need: */ - $tag = 'input'; - $args = array('type' => 'text', 'class' => 'form-control', 'name' => "setting[$setting]", 'id' => $setting); + $args = array('class' => 'form-control', 'name' => "setting[$setting]", 'id' => $setting); if (!empty($shadows)) { - $args['data-shadows'] = $shadows; + $args['data-shadows'] = json_encode($shadows); } $inner = ""; /* -- */ @@ -308,17 +310,20 @@ class Page_BaseConfig extends Page $tag = 'select'; unset($args['type']); $current = ''; + } else { + // Everything else is a text input for now + $tag = 'input'; + $args['value'] = $current; + $args['type'] = 'text'; + /* Password field guessing */ + if (stripos($validator, 'password') !== false) { + $args['type'] = Property::getPasswordFieldType(); + } } /* multiinput: enter multiple free-form strings*/ if ($validator === 'multiinput') { $args['class'] .= " multiinput"; - $args['value'] = $current; - } - - /* Password field guessing */ - if (stripos($validator, 'password') !== false) { - $args['type'] = Property::getPasswordFieldType(); } $output = "<$tag "; diff --git a/modules-available/baseconfig/templates/_page.html b/modules-available/baseconfig/templates/_page.html index 7bd5f6c9..11b8d8ee 100644 --- a/modules-available/baseconfig/templates/_page.html +++ b/modules-available/baseconfig/templates/_page.html @@ -70,27 +70,27 @@ + +//--> -- cgit v1.2.3-55-g7522 From ccdfb27b9eabb525db532811f5f3caf7d2606ffa Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Fri, 12 Aug 2016 17:24:47 +0200 Subject: Update translations --- modules-available/dozmod/lang/de/messages.json | 8 ++++++- modules-available/dozmod/lang/de/module.json | 10 ++++---- .../dozmod/lang/de/template-tags.json | 27 +++++++++++++++------- modules-available/dozmod/lang/en/messages.json | 8 ++++++- modules-available/dozmod/lang/en/module.json | 7 +++++- .../dozmod/lang/en/template-tags.json | 27 ++++++++++++++++++++++ modules-available/main/lang/de/messages.json | 1 + modules-available/main/lang/en/messages.json | 1 + 8 files changed, 73 insertions(+), 16 deletions(-) diff --git a/modules-available/dozmod/lang/de/messages.json b/modules-available/dozmod/lang/de/messages.json index 7944ffae..e72fb1be 100644 --- a/modules-available/dozmod/lang/de/messages.json +++ b/modules-available/dozmod/lang/de/messages.json @@ -1,5 +1,11 @@ { + "all-templates-reset": "Alle Templates wurden zur\u00fcckgesetzt", "delete-images": "L\u00f6schung: {{0}}", + "dozmod-error": "Fehler bei der Kommunikation mit dem bwLehrpool-Suite server: {{0}}", "images-pending-delete-exist": "Zur L\u00f6schung markierte Abbilder: {{0}}", - "mail-config-saved": "Mail-Konfiguration gespeichert" + "mail-config-saved": "Mail-Konfiguration gespeichert", + "nothing-submitted": "Es wurde nichts \u00fcbermittelt", + "runtimelimits-config-saved": "Einstellungen gespeichert", + "templates-saved": "Templates wurden gespeichert", + "timeout": "Zeit\u00fcberschreitung" } \ No newline at end of file diff --git a/modules-available/dozmod/lang/de/module.json b/modules-available/dozmod/lang/de/module.json index df2b5d4b..3ab1062d 100644 --- a/modules-available/dozmod/lang/de/module.json +++ b/modules-available/dozmod/lang/de/module.json @@ -1,8 +1,8 @@ { - "module_name": "Dozentenmodul", - "page_title": "Verwalten des Dozentenmoduls", + "module_name": "bwLehrpool-Suite", + "page_title": "Verwalten der bwLehrpool-Suite", "submenu_mailconfig": "Email-Konfiguration", - "submenu_runtime": "Laufzeit", - "submenu_templates": "Vorlagen E-Mail", - "submenu_users": "Benutzer" + "submenu_runtime": "Limits und Standardwerte", + "submenu_templates": "Textbausteine f\u00fcr E-Mails", + "submenu_users": "Benutzer und Berechtigungen" } \ No newline at end of file diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index f123db5b..5f2adee2 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -1,37 +1,46 @@ { "lang_asteriskRequired": "Felder mit (*) sind erforderlich", "lang_canLogin": "Nutzer dieser Einrichtung k\u00f6nnen sich am Satelliten anmelden", - "lang_defaultImagePermissionAdmin": "Administration", + "lang_defaultImagePermissionAdmin": "Administrieren", "lang_defaultImagePermissionDownload": "Download", "lang_defaultImagePermissionEdit": "Bearbeiten", - "lang_defaultImagePermissionLink": "Verkn\u00fcpfen", - "lang_defaultImagePermissions": "Standard-Berechtigungen f\u00fcr Images", - "lang_defaultLecturePermissions": "Standard-Berechtigungen f\u00fcr Vorlesungen", - "lang_delButton": "Gew\u00e4hlte Images endg\u00fcltig l\u00f6schen", + "lang_defaultImagePermissionLink": "Veranstaltung Verkn\u00fcpfen", + "lang_defaultImagePermissions": "F\u00fcr VMs", + "lang_defaultLecturePermissions": "F\u00fcr Veranstaltungen", + "lang_defaultPermissions": "Standardberechtigungen", + "lang_delButton": "Gew\u00e4hlte VMs endg\u00fcltig l\u00f6schen", "lang_description": "Beschreibung", - "lang_descriptionRuntimeConfig": "Blah blah blah", - "lang_description_delete_images": "Diese Liste zeigt Images, die entweder abgelaufen sind, oder deren Datei besch\u00e4digt, verschoben oder gel\u00f6scht wurde. Diese Images sind zur Zeit im Lehrpool nicht verf\u00fcgbar, ihre endg\u00fcltige L\u00f6schung muss aber manuell best\u00e4tigt werden, um gr\u00f6\u00dfere Katastrophen durch Softwarefehler, verstellte Systemuhren etc. zu vermeiden.", + "lang_descriptionPermissionConfig": "Dies sind die Berechtigungen, die ein Benutzer standardm\u00e4\u00dfig f\u00fcr fremde VMs\/Veranstaltungen hat. Sie werden angewandt, wenn der Besitzer keine anderweitigen Berechtigungen w\u00e4hlt.", + "lang_descriptionRuntimeLimits": "Hier k\u00f6nnen Sie verschiedene Limits festlegen, z.B. wie lange eine VM nach dem Hochladen g\u00fcltig ist. Nach Ablauf dieses Zeitraums ist der Verantwortliche gezwungen, eine neue Version der VM hochzuladen. Damit k\u00f6nnen Sie das Ansammeln von nicht mehr ben\u00f6tigten VMs eind\u00e4mmen. Weiterhin k\u00f6nnen Sie die maximale Anzahl gleichzeitiger Transfers pro Benutzer einschr\u00e4nken.", + "lang_description_delete_images": "Diese Liste zeigt VMs, die entweder abgelaufen sind, oder deren Datei besch\u00e4digt, verschoben oder gel\u00f6scht wurde. Diese Images sind zur Zeit im Lehrpool nicht verf\u00fcgbar, ihre endg\u00fcltige L\u00f6schung muss aber manuell best\u00e4tigt werden, um gr\u00f6\u00dfere Katastrophen durch Softwarefehler, verstellte Systemuhren etc. zu vermeiden.", "lang_email": "EMail", "lang_emailNotifications": "EMail-Benachrichtigungen aktiviert", + "lang_error": "Fehler", + "lang_followingPlaceholdersUnused": "Folgende Platzhalter m\u00fcssen im Template verwendet werden", "lang_hasNewer": "Neuere Version existiert", - "lang_heading": "Zu l\u00f6schende Image-Versionen", + "lang_heading": "Zu l\u00f6schende VM-Versionen", "lang_host": "Host", "lang_image": "VM", "lang_lastLogin": "Letzte Anmeldung", "lang_lecturePermissionAdmin": "Administration", "lang_lecturePermissionEdit": "Bearbeiten", + "lang_loadDefaults": "Alle Texte auf Auslieferungszustand zur\u00fccksetzen", "lang_mailConfig": "SMTP-Konfiguration zum Versenden von Mails", "lang_mailConfigHeadline": "EMail-Konfiguration", "lang_mailDescription": "F\u00fcllen Sie die folgenden Felder aus, wenn sie m\u00f6chten, dass Dozenten Benachrichtigungen per Mail bekommen, falls eine von ihnen genutzte oder erstellte VM oder Veranstaltung abl\u00e4uft. Um diese Funktion zu deaktivieren, lassen Sie eines der mit (*) gekennzeichneten Felder leer. Wenn das hier angegebene E-Mail-Konto nur zum Versenden von Mails genutzt wird, sollten Sie einen Auto-Responder einrichten f\u00fcr den Fall, dass ein Dozent auf eine der automatisch generierten Mails antwortet (bzw. eine explizit angegebene Reply-To Adresse ignoriert).", + "lang_mailTemplates": "E-Mail Templates", "lang_maxImageValidity": "Maximale G\u00fcltigkeit", "lang_maxLectureVisibility": "Maximale Sichtbarkeit", "lang_maxTransfers": "Maximale Anzahl an Uploads", + "lang_name": "Name", "lang_organization": "Einrichtung", "lang_organizationList": "Liste der Einrichtungen", "lang_organizationListHeader": "Nutzungsrechte f\u00fcr den Satelliten festlegen", "lang_owner": "Besitzer", "lang_password": "Passwort", + "lang_placeholders": "Platzhalter", "lang_port": "Port", + "lang_reallyResetTemplates": "Sind Sie sicher, dass Sie alle Texte l\u00f6schen und auf die Standardwerte zur\u00fccksetzen wollen?", "lang_replyTo": "Reply-To Adresse (z.B. Helpdesk)", "lang_runtimeConfig": "Laufzeit-Konfiguration", "lang_runtimeConfigHeadline": "Laufzeit-Konfiguration", @@ -45,6 +54,8 @@ "lang_sslNone": "Kein SSL", "lang_subHeading": "Images, die abgelaufen oder besch\u00e4digt sind", "lang_superUser": "Ist SuperUser (darf alle Veranstaltungen und VMs bearbeiten\/l\u00f6schen)", + "lang_template": "Template", + "lang_templatePageDescription": "Hier k\u00f6nnen Sie die Textbausteine bearbeiten, aus denen die Mails generiert werden, die der bwLehrpool-Server bez\u00fcglich Virtueller Maschinen und Veranstaltungen versendet. Diese Funktionalit\u00e4t unterst\u00fctzt zur Zeit keine Internationalisierung.", "lang_test": "Test-Mail senden", "lang_testConfiguration": "Um die Konfiguration zu testen, geben Sie hier eine Empf\u00e4ngeradresse ein", "lang_testRecipient": "Empf\u00e4nger", diff --git a/modules-available/dozmod/lang/en/messages.json b/modules-available/dozmod/lang/en/messages.json index 6651e32e..e1b5eea6 100644 --- a/modules-available/dozmod/lang/en/messages.json +++ b/modules-available/dozmod/lang/en/messages.json @@ -1,5 +1,11 @@ { + "all-templates-reset": "All templates have been reset", "delete-images": "Delete: {{0}}", + "dozmod-error": "Error communicating with the bwLehrpool-Suite server: {{0}}", "images-pending-delete-exist": "Images marked for deletion: {{0}}", - "mail-config-saved": "Mail config saved" + "mail-config-saved": "Mail config saved", + "nothing-submitted": "There was nothing submitted", + "runtimelimits-config-saved": "Configuration saved successfully", + "templates-saved": "Templates saved successfully", + "timeout": "Timeout" } \ No newline at end of file diff --git a/modules-available/dozmod/lang/en/module.json b/modules-available/dozmod/lang/en/module.json index e42d21ea..c54d9784 100644 --- a/modules-available/dozmod/lang/en/module.json +++ b/modules-available/dozmod/lang/en/module.json @@ -1,3 +1,8 @@ { - "module_name": "Tutor Module" + "module_name": "bwLehrpool-Suite", + "page_title": "Manage the bwLehrpool-Suite", + "submenu_mailconfig": "email configuration", + "submenu_runtime": "limits and defaults", + "submenu_templates": "templates", + "submenu_users": "users and permissions" } \ No newline at end of file diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json index 2ed11a2a..dd7f9391 100644 --- a/modules-available/dozmod/lang/en/template-tags.json +++ b/modules-available/dozmod/lang/en/template-tags.json @@ -1,25 +1,50 @@ { "lang_asteriskRequired": "Fields marked with (*) are required", "lang_canLogin": "Members of this organization can login", + "lang_defaultImagePermissionAdmin": "Administrate", + "lang_defaultImagePermissionDownload": "Download", + "lang_defaultImagePermissionEdit": "Edit", + "lang_defaultImagePermissionLink": "Link lecture", + "lang_defaultImagePermissions": "For VMs", + "lang_defaultLecturePermissions": "For lectures", + "lang_defaultPermissions": "Default permissions", "lang_delButton": "Permanently delete selected images", "lang_description": "This list shows images that reached their expire date, or where the image file in the file system is damaged or missing. You need to manually confirm the deletion of these files for safety reasons (software bugs, wrong system time, etc.).", + "lang_descriptionPermissionConfig": "These are the default permissions being used for VMs and lectures if the owner does not specify any.", + "lang_descriptionRuntimeLimits": "Here you can define some limits, e.g. how long a newly uploaded VM will be valid. This should make sure that you don't end up with a lot of old, unused VMs over time.", + "lang_description_delete_images": "This is a list of VMs that either expired, or where the disk image is damaged or missing. These VMs are not available in bwLehrpool currently, but you have to manually confirm the deletion of the disk images for safety reasons (clock skew etc.)", "lang_email": "E-Mail", "lang_emailNotifications": "E-Mail notifications enabled", + "lang_error": "Error", + "lang_followingPlaceholdersUnused": "The following placeholders are not being used", "lang_hasNewer": "Newer version exists", "lang_heading": "Images marked for deletion", "lang_host": "Host", "lang_image": "VM", "lang_lastLogin": "Last login", + "lang_lecturePermissionAdmin": "Administrate", + "lang_lecturePermissionEdit": "Edit", + "lang_loadDefaults": "Reset all templates to their defaults", "lang_mailConfig": "SMTP configuration for sending mails", "lang_mailConfigHeadline": "email configuration", "lang_mailDescription": "Fill in the following fields if you want to notify tutors\/professors\/lecturers about expiring VMs and lectures. If you leave one of the required fields blank, the feature will be disabled.", + "lang_mailTemplates": "E-Mail templates", + "lang_maxImageValidity": "New VM validity (days)", + "lang_maxLectureVisibility": "Max time lecture end date may lie in the future (days)", + "lang_maxTransfers": "Max concurrent transfers per user", + "lang_name": "Name", "lang_organization": "Organization", "lang_organizationList": "List of organizations", "lang_organizationListHeader": "Set access permissions for organizations", "lang_owner": "Owner", "lang_password": "Password", + "lang_placeholders": "Placeholders", "lang_port": "Port", + "lang_reallyResetTemplates": "Are you sure you want to reset all texts to their default values?", "lang_replyTo": "Reply-To address", + "lang_runtimeConfig": "Limits and Defaults", + "lang_runtimeConfigHeadline": "Configure limits and defaults for bwLehrpool-Suite", + "lang_runtimeConfigLimits": "Limitations", "lang_senderAddress": "Sender address", "lang_senderName": "Sender's display name", "lang_size": "Size", @@ -29,6 +54,8 @@ "lang_sslNone": "No SSL", "lang_subHeading": "Expired or damaged images", "lang_superUser": "Is super user (can edit\/delete all lectures and VMs)", + "lang_template": "Template", + "lang_templatePageDescription": "Here you can edit text fragments that are used to compose the information and reminder mails sent by the bwLehrpool server, e.g. when a lecture or VM is about to expire.", "lang_test": "Send test mail", "lang_testConfiguration": "To test the configuration, enter a recipient address here", "lang_testRecipient": "Recipient", diff --git a/modules-available/main/lang/de/messages.json b/modules-available/main/lang/de/messages.json index fc73f891..274a97bd 100644 --- a/modules-available/main/lang/de/messages.json +++ b/modules-available/main/lang/de/messages.json @@ -3,6 +3,7 @@ "empty-field": "Ein Feld wurde nicht ausgef\u00fcllt", "error-read": "Fehler beim Lesen von {{0}}", "error-write": "Fehler beim Schreiben von {{0}}", + "invalid-action": "Ung\u00fcltige Aktion '{{0}}'", "module-missing-deps": "Modul {{0}} hat fehlende Abh\u00e4ngigkeiten", "no-permission": "Keine ausreichenden Rechte, um auf diese Seite zuzugreifen", "no-such-module": "Modul {{0}} existiert nicht oder ist nicht aktiv", diff --git a/modules-available/main/lang/en/messages.json b/modules-available/main/lang/en/messages.json index 2b735eec..e7314685 100644 --- a/modules-available/main/lang/en/messages.json +++ b/modules-available/main/lang/en/messages.json @@ -3,6 +3,7 @@ "empty-field": "A field was not filled", "error-read": "Error reading {{0}}", "error-write": "Failed to write {{0}}", + "invalid-action": "Invalid action '{{0}}'", "module-missing-deps": "Module {{0}} has missing dependencies", "no-permission": "No sufficient privileges to access this page", "no-such-module": "Modul {{0}} existiert nicht", -- cgit v1.2.3-55-g7522 From 9cd15bf349c86fe72b80664f8bd1268b872f72c4 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Aug 2016 15:14:23 +0200 Subject: [locations] Fix wrong overlap function for subnet collision detection --- modules-available/locations/inc/location.inc.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules-available/locations/inc/location.inc.php b/modules-available/locations/inc/location.inc.php index a018208d..71a621db 100644 --- a/modules-available/locations/inc/location.inc.php +++ b/modules-available/locations/inc/location.inc.php @@ -362,8 +362,7 @@ class Location private static function overlap($net1, $net2) { - return ($net1['startaddr'] >= $net2['startaddr'] && $net1['startaddr'] <= $net2['endaddr']) - || ($net1['endaddr'] >= $net2['startaddr'] && $net1['endaddr'] <= $net2['endaddr']); + return ($net1['startaddr'] <= $net2['endaddr'] && $net1['endaddr'] >= $net2['startaddr']); } } -- cgit v1.2.3-55-g7522 From a5f23f0b6b009d5f5b092d6bffdca1e4cfa02d58 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Aug 2016 15:40:19 +0200 Subject: Update translations --- modules-available/dozmod/lang/de/template-tags.json | 8 ++++---- modules-available/dozmod/page.inc.php | 11 ++++++++--- modules-available/dozmod/templates/images-delete.html | 2 +- modules-available/webinterface/lang/de/template-tags.json | 3 ++- modules-available/webinterface/lang/en/template-tags.json | 3 ++- modules-available/webinterface/templates/https.html | 2 +- modules-available/webinterface/templates/passwords.html | 2 +- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index 5f2adee2..18198ab8 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -11,7 +11,7 @@ "lang_delButton": "Gew\u00e4hlte VMs endg\u00fcltig l\u00f6schen", "lang_description": "Beschreibung", "lang_descriptionPermissionConfig": "Dies sind die Berechtigungen, die ein Benutzer standardm\u00e4\u00dfig f\u00fcr fremde VMs\/Veranstaltungen hat. Sie werden angewandt, wenn der Besitzer keine anderweitigen Berechtigungen w\u00e4hlt.", - "lang_descriptionRuntimeLimits": "Hier k\u00f6nnen Sie verschiedene Limits festlegen, z.B. wie lange eine VM nach dem Hochladen g\u00fcltig ist. Nach Ablauf dieses Zeitraums ist der Verantwortliche gezwungen, eine neue Version der VM hochzuladen. Damit k\u00f6nnen Sie das Ansammeln von nicht mehr ben\u00f6tigten VMs eind\u00e4mmen. Weiterhin k\u00f6nnen Sie die maximale Anzahl gleichzeitiger Transfers pro Benutzer einschr\u00e4nken.", + "lang_descriptionRuntimeLimits": "Hier k\u00f6nnen Sie verschiedene Limits festlegen, z.B. wie lange eine VM nach dem Hochladen g\u00fcltig ist. Nach Ablauf dieses Zeitraums ist der Verantwortliche gezwungen, eine neue Version der VM hochzuladen. Damit k\u00f6nnen Sie das Ansammeln nicht mehr ben\u00f6tigter VMs eind\u00e4mmen. Weiterhin k\u00f6nnen Sie die maximale Anzahl gleichzeitiger Transfers pro Benutzer einschr\u00e4nken.", "lang_description_delete_images": "Diese Liste zeigt VMs, die entweder abgelaufen sind, oder deren Datei besch\u00e4digt, verschoben oder gel\u00f6scht wurde. Diese Images sind zur Zeit im Lehrpool nicht verf\u00fcgbar, ihre endg\u00fcltige L\u00f6schung muss aber manuell best\u00e4tigt werden, um gr\u00f6\u00dfere Katastrophen durch Softwarefehler, verstellte Systemuhren etc. zu vermeiden.", "lang_email": "EMail", "lang_emailNotifications": "EMail-Benachrichtigungen aktiviert", @@ -29,9 +29,9 @@ "lang_mailConfigHeadline": "EMail-Konfiguration", "lang_mailDescription": "F\u00fcllen Sie die folgenden Felder aus, wenn sie m\u00f6chten, dass Dozenten Benachrichtigungen per Mail bekommen, falls eine von ihnen genutzte oder erstellte VM oder Veranstaltung abl\u00e4uft. Um diese Funktion zu deaktivieren, lassen Sie eines der mit (*) gekennzeichneten Felder leer. Wenn das hier angegebene E-Mail-Konto nur zum Versenden von Mails genutzt wird, sollten Sie einen Auto-Responder einrichten f\u00fcr den Fall, dass ein Dozent auf eine der automatisch generierten Mails antwortet (bzw. eine explizit angegebene Reply-To Adresse ignoriert).", "lang_mailTemplates": "E-Mail Templates", - "lang_maxImageValidity": "Maximale G\u00fcltigkeit", - "lang_maxLectureVisibility": "Maximale Sichtbarkeit", - "lang_maxTransfers": "Maximale Anzahl an Uploads", + "lang_maxImageValidity": "G\u00fcltigkeitsdauer neuer VM-Versionen (Tage)", + "lang_maxLectureVisibility": "Sp\u00e4testes Enddatum einer Veranstaltung (Tage in der Zukunft)", + "lang_maxTransfers": "Maximale Zahl gleichzeitiger Up-\/Downloads pro Benutzer", "lang_name": "Name", "lang_organization": "Einrichtung", "lang_organizationList": "Liste der Einrichtungen", diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index 7e8db7c4..9272f9ff 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -249,9 +249,14 @@ class Page_DozMod extends Page $data['defaultLecturePermissions'] = Request::post('defaultLecturePermissions', NULL, "array"); $data['defaultImagePermissions'] = Request::post('defaultImagePermissions', NULL, "array"); - foreach(['maxImageValidityDays', 'maxLectureValidityDays', 'maxTransfers'] as $field) { - $value = Request::post($field); - $data[$field] = $value; + $intParams = [ + 'maxImageValidityDays' => array('min' => 7, 'max' => 999), + 'maxLectureValidityDays' => array('min' => 7, 'max' => 999), + 'maxTransfers' => array('min' => 1, 'max' => 10), + ]; + foreach($intParams as $field => $limits) { + $value = Request::post($field, 0, 'int'); + $data[$field] = max(min($value, $limits['max']), $limits['min']); } /* ensure types */ diff --git a/modules-available/dozmod/templates/images-delete.html b/modules-available/dozmod/templates/images-delete.html index f8836b83..b85d2c06 100644 --- a/modules-available/dozmod/templates/images-delete.html +++ b/modules-available/dozmod/templates/images-delete.html @@ -85,4 +85,4 @@ document.addEventListener("DOMContentLoaded", function() { slxChangeSingle(); }, false); ---> +//--> diff --git a/modules-available/webinterface/lang/de/template-tags.json b/modules-available/webinterface/lang/de/template-tags.json index e204adec..3ac6186c 100644 --- a/modules-available/webinterface/lang/de/template-tags.json +++ b/modules-available/webinterface/lang/de/template-tags.json @@ -4,12 +4,13 @@ "lang_caChain": "Optional k\u00f6nnen Sie hier die zum Zertifikat geh\u00f6rende Zertifikatkette (CA-Chain) einf\u00fcgen. Dies wird ben\u00f6tigt, wenn das Zertifikat nicht direkt von einer der in Browsern mitgeliferten CAs signiert wurde. Die Datei enth\u00e4lt ein oder meherere Zertifikatsbl\u00f6cke, im gleichen Format wie das oben gezeigte Zertifikat.", "lang_certificate": "Bitte f\u00fcgen Sie hier das Zertifikat ein. Das Zertifikat wird im Base64-codierten x509-Format erwartet (manchmal pem genannt). Es sieht in etwa wie folgt aus:", "lang_customCert": "Eigenes Zertifikat verwenden", - "lang_description": "Hier k\u00f6nnen Sie festlegen, ob das Web-Interface auch per HTTPS erreichbar sein soll, und welches Zertifikat daf\u00fcr verwendet werden soll.", "lang_hidePasswords": "Passw\u00f6rter maskieren", + "lang_httpsDescription": "Hier k\u00f6nnen Sie festlegen, ob das Web-Interface auch per HTTPS erreichbar sein soll, und welches Zertifikat daf\u00fcr verwendet werden soll.", "lang_httpsSettings": "HTTPS-Konfiguration", "lang_installAndRestart": "Zertifikat installieren und Webserver neustarten", "lang_noHttps": "HTTPS wieder deaktivieren, aktuelles Zertifikat l\u00f6schen", "lang_passwordFields": "Passwortfelder", + "lang_passwordsDescription": "Legen Sie fest, ob Passwortfelder in der Web-Schnittstelle maskiert werden, oder ob Ihr Inhalt sichtbar sein soll. Wenn Sie die Schnittstelle in einer sicheren Umgebung nutzen (keine neugierigen Augen), kann dies den Komfort erh\u00f6hen. Das Passwortfeld der Anmeldemaske ist von dieser Einstellung ausgenommen.", "lang_privateKey": "Bitte f\u00fcgen Sie hier den privaten Schl\u00fcssel ein, der zum obigen Zertifikat geh\u00f6rt. Er muss ebenfalls im \"pem\"-Format vorliegen, und sieht wie folgt aus:", "lang_randomCert": "Neues selbstsigniertes Zertifikat generieren", "lang_showPasswords": "Passw\u00f6rter anzeigen" diff --git a/modules-available/webinterface/lang/en/template-tags.json b/modules-available/webinterface/lang/en/template-tags.json index 4a43bdc1..31bc1cc9 100644 --- a/modules-available/webinterface/lang/en/template-tags.json +++ b/modules-available/webinterface/lang/en/template-tags.json @@ -4,12 +4,13 @@ "lang_caChain": "Here you can paste an optional certificate chain. It should only be required if you have a certificate that was not directly signed by a certificate authority known by the browsers. It should contain one or more certificate blocks, looking just like the certificate above.", "lang_certificate": "Please paste your certificate below. It has to be in base64 encoded x509 format (sometimes called pem). It should look something like this:", "lang_customCert": "Supply own certificate", - "lang_description": "Here you can set whether the web interface should be accessible via https. You can chose if you want to use a random self signed certificate, or supply your own.", "lang_hidePasswords": "Mask passwords", + "lang_httpsDescription": "Here you can set whether the web interface should be accessible via https. You can chose if you want to use a random self signed certificate, or supply your own.", "lang_httpsSettings": "HTTPS settings", "lang_installAndRestart": "Installing certificate and restarting web server", "lang_noHttps": "Disable HTTPS, delete current certificate", "lang_passwordFields": "Password fields", + "lang_passwordsDescription": "Set whether password fields should be masked or not. The password field of the login page to the web interface is always masked.", "lang_privateKey": "Please paste the private key belonging to the certificate here. It has to be in \"pem\" format too, which should look like this:", "lang_randomCert": "Genenrate new self-signed certificate", "lang_showPasswords": "Show passwords" diff --git a/modules-available/webinterface/templates/https.html b/modules-available/webinterface/templates/https.html index c6161cd6..dfd2a3fe 100644 --- a/modules-available/webinterface/templates/https.html +++ b/modules-available/webinterface/templates/https.html @@ -4,7 +4,7 @@
{{lang_httpsSettings}}
-

{{lang_description}}

+

{{lang_httpsDescription}}

{{^httpsEnabled}}

{{lang_HttpsIsDisabled}}

{{/httpsEnabled}} diff --git a/modules-available/webinterface/templates/passwords.html b/modules-available/webinterface/templates/passwords.html index f9fda016..1f23dfc4 100644 --- a/modules-available/webinterface/templates/passwords.html +++ b/modules-available/webinterface/templates/passwords.html @@ -4,7 +4,7 @@
{{lang_passwordFields}}
-

{{lang_description}}

+

{{lang_passwordsDescription}}

-- cgit v1.2.3-55-g7522 From fce78a63a56f42920ac40bbf76e67412933c8376 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Aug 2016 16:31:54 +0200 Subject: [statistics] Fix list view and sorting Broken when moving JS snippets around --- modules-available/statistics/inc/filterset.inc.php | 9 +++-- .../statistics/templates/clientlist.html | 37 +++++++++++++++++++ .../statistics/templates/filterbox.html | 43 ++-------------------- 3 files changed, 46 insertions(+), 43 deletions(-) diff --git a/modules-available/statistics/inc/filterset.inc.php b/modules-available/statistics/inc/filterset.inc.php index ea25d9b1..8f506654 100644 --- a/modules-available/statistics/inc/filterset.inc.php +++ b/modules-available/statistics/inc/filterset.inc.php @@ -16,8 +16,7 @@ class FilterSet $this->sortDirection = $direction === 'DESC' ? 'DESC' : 'ASC'; if (is_string($col) && array_key_exists($col, Page_Statistics::$columns)) { - $isMapped = array_key_exists('map_sort', Page_Statistics::$columns[$col]); - $this->sortColumn = $isMapped ? Page_Statistics::$columns[$col]['map_sort'] : $col; + $this->sortColumn = $col; } else { /* default sorting column is clientip */ $this->sortColumn = 'clientip'; @@ -42,8 +41,10 @@ class FilterSet } $join = implode('', array_unique($joins)); - - $sort = " ORDER BY " . $this->sortColumn . " " . $this->sortDirection; + $col = $this->sortColumn; + $isMapped = array_key_exists('map_sort', Page_Statistics::$columns[$col]); + $sort = " ORDER BY " . ($isMapped ? Page_Statistics::$columns[$col]['map_sort'] : $col) . " " . $this->sortDirection + . ", machineuuid ASC"; } public function getSortDirection() diff --git a/modules-available/statistics/templates/clientlist.html b/modules-available/statistics/templates/clientlist.html index f2a6ba03..3a1b52ac 100644 --- a/modules-available/statistics/templates/clientlist.html +++ b/modules-available/statistics/templates/clientlist.html @@ -87,3 +87,40 @@ {{/rows}} + + \ No newline at end of file diff --git a/modules-available/statistics/templates/filterbox.html b/modules-available/statistics/templates/filterbox.html index a5370a0b..544d1c48 100644 --- a/modules-available/statistics/templates/filterbox.html +++ b/modules-available/statistics/templates/filterbox.html @@ -29,7 +29,8 @@
- + + @@ -115,6 +116,8 @@ document.addEventListener("DOMContentLoaded", function () { var str = "{{{query}}}"; var eExp = /^(\w+)\s*([=>'); - $sortBtn.attr('onclick', 'toggleButton(\'' + v + '\');'); - }); -} - -function toggleButton(v) { - var $sortBtn = $('#sortButton-' + v); - var $col = $('#sortColumn'); - var $dir = $('#sortDirection'); - if ($col.val() == v) { - /* toggle direction */ - var newDir = $dir.val() == 'ASC' ? 'DESC' : 'ASC'; - $dir.val(newDir); - /* update button */ - var order = newDir == 'ASC' ? 'up' : 'down'; - $sortBtn.html(''); - } else { - /* remove "btn-success" from current sorting */ - $('#sortButton-'+v).removeClass('btn-success'); - $sortBtn.addClass('btn-success'); - $col.val(v); - $dir = 'ASC'; - } - refresh(); -} - function popupFilter(field) { if (field != null) { $('#columnSelect').val(field); @@ -258,7 +224,6 @@ function myOpSort(a,b) { } function refresh() { - console.log('refresh'); $queryForm.submit(); /* TODO: use AJAX */ } // --> -- cgit v1.2.3-55-g7522 From e40ee176b7a9142f61644745991cb22564392741 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Aug 2016 16:50:44 +0200 Subject: [util] traceError(): Don't output html junk if running via CLI --- inc/util.inc.php | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/inc/util.inc.php b/inc/util.inc.php index 8ad3928a..bee07765 100644 --- a/inc/util.inc.php +++ b/inc/util.inc.php @@ -14,7 +14,11 @@ class Util { if (defined('API') && API) { error_log('API ERROR: ' . $message); - error_log(print_r(debug_backtrace(), true)); + error_log(self::formatBacktracePlain(debug_backtrace())); + } + if (php_sapi_name() === 'cli') { + // Don't spam HTML when invoked via cli, above error_log should have gone to stdout/stderr + exit(1); } Header('HTTP/1.1 500 Internal Server Error'); Header('Content-Type: text/html; charset=utf-8'); @@ -38,7 +42,7 @@ class Util echo ''; } echo "

Stack Trace

"; - echo '
', self::formatBacktrace(debug_backtrace()), '
'; + echo '
', self::formatBacktraceHtml(debug_backtrace()), '
'; echo "

Globals

";
 			echo print_r($GLOBALS, true);
 			echo '
'; @@ -75,7 +79,7 @@ SADFACE; exit(0); } - public static function formatBacktrace($trace, $escape = true) + public static function formatBacktraceHtml($trace, $escape = true) { $output = ''; foreach ($trace as $idx => $line) { @@ -101,6 +105,30 @@ SADFACE; return $output; } + public static function formatBacktracePlain($trace) + { + $output = ''; + foreach ($trace as $idx => $line) { + $args = array(); + foreach ($line['args'] as $arg) { + if (is_string($arg)) { + $arg = "'$arg'"; + } elseif (is_object($arg)) { + $arg = 'instanceof ' . get_class($arg); + } elseif (is_array($arg)) { + $arg = 'Array(' . count($arg) . ')'; + } + $args[] = $arg; + } + $frame = str_pad('#' . $idx, 3, ' ', STR_PAD_LEFT); + $args = implode(', ', $args); + // Add line + $output .= "\n" . $frame . ' ' . $line['function'] . '(' + . $args . ')' . ' @ ' . $line['file'] . ':' . $line['line']; + } + return $output; + } + /** * Redirects the user via a '302 Moved' header. * An active session will be saved, any messages that haven't -- cgit v1.2.3-55-g7522 From b0ec6236bb55a887c2bdbeaed7200a890624da02 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 15 Aug 2016 16:55:33 +0200 Subject: [util] Also escape the print_r output when rendering HTML --- inc/util.inc.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inc/util.inc.php b/inc/util.inc.php index bee07765..a9ae384c 100644 --- a/inc/util.inc.php +++ b/inc/util.inc.php @@ -44,7 +44,7 @@ class Util echo "

Stack Trace

"; echo '
', self::formatBacktraceHtml(debug_backtrace()), '
'; echo "

Globals

";
-			echo print_r($GLOBALS, true);
+			echo htmlspecialchars(print_r($GLOBALS, true));
 			echo '
'; } else { echo <<'; - } self::$templateCache[$id] =& $data; return $data; } -- cgit v1.2.3-55-g7522 From bf3bb604fa82e0738fdb21d9bd4fd07000ed35bd Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 16 Aug 2016 18:05:29 +0200 Subject: [dozmod] Implement action log subpage --- modules-available/dozmod/inc/pagedozmodlog.inc.php | 156 +++++++++++++++++++++ .../dozmod/inc/pagedozmodusers.inc.php | 115 +++++++++++++++ .../dozmod/inc/pagemailtemplates.inc.php | 7 - modules-available/dozmod/lang/de/module.json | 1 + .../dozmod/lang/de/template-tags.json | 14 +- modules-available/dozmod/lang/en/module.json | 1 + .../dozmod/lang/en/template-tags.json | 14 +- modules-available/dozmod/page.inc.php | 145 +++++-------------- .../dozmod/templates/actionlog-header.html | 1 + .../dozmod/templates/actionlog-image.html | 30 ++++ .../dozmod/templates/actionlog-lecture.html | 30 ++++ .../dozmod/templates/actionlog-log.html | 41 ++++++ .../dozmod/templates/actionlog-user.html | 23 +++ modules-available/dozmod/templates/orglist.html | 34 ++--- modules-available/dozmod/templates/userlist.html | 34 +++-- 15 files changed, 498 insertions(+), 148 deletions(-) create mode 100644 modules-available/dozmod/inc/pagedozmodlog.inc.php create mode 100644 modules-available/dozmod/inc/pagedozmodusers.inc.php create mode 100644 modules-available/dozmod/templates/actionlog-header.html create mode 100644 modules-available/dozmod/templates/actionlog-image.html create mode 100644 modules-available/dozmod/templates/actionlog-lecture.html create mode 100644 modules-available/dozmod/templates/actionlog-log.html create mode 100644 modules-available/dozmod/templates/actionlog-user.html diff --git a/modules-available/dozmod/inc/pagedozmodlog.inc.php b/modules-available/dozmod/inc/pagedozmodlog.inc.php new file mode 100644 index 00000000..f31edf5b --- /dev/null +++ b/modules-available/dozmod/inc/pagedozmodlog.inc.php @@ -0,0 +1,156 @@ +action = Request::get('action', '', 'string'); + if ($this->action !== '' && $this->action !== 'showtarget' && $this->action !== 'showuser') { + Util::traceError('Invalid action for actionlog: "' . $this->action . '"'); + } + $this->uuid = Request::get('uuid', '', 'string'); + } + + protected function doRender() + { + Render::addTemplate('actionlog-header'); + if ($this->action === '') { + $this->generateLog("SELECT al.dateline, al.targetid, al.description," + . " img.displayname AS imgname, tu.firstname AS tfirstname, tu.lastname AS tlastname, l.displayname AS lecturename," + . " al.userid AS uuserid, usr.firstname AS ufirstname, usr.lastname AS ulastname" + . " FROM sat.actionlog al" + . " LEFT JOIN sat.imagebase img ON (img.imagebaseid = targetid)" + . " LEFT JOIN sat.user usr ON (usr.userid = al.userid)" + . " LEFT JOIN sat.user tu ON (tu.userid = al.targetid)" + . " LEFT JOIN sat.lecture l ON (l.lectureid = targetid)" + . " ORDER BY al.dateline DESC LIMIT 500", array(), true, true); + } elseif ($this->action === 'showuser') { + $this->listUser(); + } else { + $this->listTarget(); + } + } + + private function listUser() + { + // Query user + $user = Database::queryFirst('SELECT userid, firstname, lastname, email, lastlogin,' + . ' organization.displayname AS orgname FROM sat.user' + . ' LEFT JOIN sat.organization USING (organizationid)' + . ' WHERE userid = :uuid' + . ' LIMIT 1', array('uuid' => $this->uuid)); + if ($user === false) { + Message:addError('unknown-userid', $this->uuid); + Util::redirect('?do=dozmod§ion=actionlog'); + } + // Mangle date and render + $user['lastlogin_s'] = date('d.m.Y H:i', $user['lastlogin']); + Render::addTemplate('actionlog-user', $user); + // Finally add the actionlog + $this->generateLog("SELECT al.dateline, al.targetid, al.description," + . " img.displayname AS imgname, usr.firstname AS tfirstname, usr.lastname AS tlastname, l.displayname AS lecturename" + . " FROM sat.actionlog al" + . " LEFT JOIN sat.imagebase img ON (img.imagebaseid = targetid)" + . " LEFT JOIN sat.user usr ON (usr.userid = targetid)" + . " LEFT JOIN sat.lecture l ON (l.lectureid = targetid)" + . " WHERE al.userid = :uuid" + . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => $this->uuid), false, true); + } + + private function listTarget() + { + // We have to guess what kind of target it is + if (!$this->addImageHeader() + && !$this->addLectureHeader()) { + Message:addError('unknown-targetid', $this->uuid); + // Keep going, there might still be log entries for a deleted uuid + } + + // Finally add the actionlog + $this->generateLog("SELECT al.dateline, al.userid AS uuserid, al.description," + . " usr.firstname AS ufirstname, usr.lastname AS ulastname" + . " FROM sat.actionlog al" + . " LEFT JOIN sat.user usr ON (usr.userid = al.userid)" + . " WHERE al.targetid = :uuid" + . " ORDER BY al.dateline DESC LIMIT 500", array('uuid' => $this->uuid), true, false); + } + + private function addImageHeader() + { + $image = Database::queryFirst('SELECT o.userid AS ouserid, o.firstname AS ofirstname, o.lastname AS olastname,' + . ' u.userid AS uuserid, u.firstname AS ufirstname, u.lastname AS ulastname,' + . ' img.displayname, img.description, img.createtime, img.updatetime,' + . ' os.displayname AS osname' + . ' FROM sat.imagebase img' + . ' LEFT JOIN sat.user o ON (img.ownerid = o.userid)' + . ' LEFT JOIN sat.user u ON (img.updaterid = u.userid)' + . ' LEFT JOIN sat.operatingsystem os ON (img.osid = os.osid)' + . ' WHERE img.imagebaseid = :uuid' + . ' LIMIT 1', array('uuid' => $this->uuid)); + if ($image !== false) { + // Mangle date and render + $image['createtime_s'] = date('d.m.Y H:i', $image['createtime']); + $image['updatetime_s'] = date('d.m.Y H:i', $image['updatetime']); + $image['descriptionHtml'] = nl2br(htmlspecialchars($image['description'])); + Render::addTemplate('actionlog-image', $image); + } + return $image !== false; + } + + private function addLectureHeader() + { + $lecture = Database::queryFirst('SELECT o.userid AS ouserid, o.firstname AS ofirstname, o.lastname AS olastname,' + . ' u.userid AS uuserid, u.firstname AS ufirstname, u.lastname AS ulastname,' + . ' l.displayname, l.description, l.createtime, l.updatetime,' + . ' img.displayname AS imgname, img.imagebaseid' + . ' FROM sat.lecture l' + . ' LEFT JOIN sat.user o ON (l.ownerid = o.userid)' + . ' LEFT JOIN sat.user u ON (l.updaterid = u.userid)' + . ' LEFT JOIN sat.imageversion ver ON (ver.imageversionid = l.imageversionid)' + . ' LEFT JOIN sat.imagebase img ON (img.imagebaseid = ver.imagebaseid)' + . ' WHERE l.lectureid = :uuid' + . ' LIMIT 1', array('uuid' => $this->uuid)); + if ($lecture !== false) { + // Mangle date and render + $lecture['createtime_s'] = date('d.m.Y H:i', $lecture['createtime']); + $lecture['updatetime_s'] = date('d.m.Y H:i', $lecture['updatetime']); + $lecture['descriptionHtml'] = nl2br(htmlspecialchars($lecture['description'])); + Render::addTemplate('actionlog-lecture', $lecture); + } + return $lecture !== false; + } + + private function generateLog($query, $params, $showActor, $showTarget) + { + // query action log + $res = Database::simpleQuery($query, $params); + $events = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['dateline_s'] = date('d.m.Y H:i', $row['dateline']); + if (isset($row['imgname'])) { + $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showtarget&uuid=' . $row['targetid']; + $row['targetname'] = $row['imgname']; + } elseif (isset($row['tlastname'])) { + $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showuser&uuid=' . $row['targetid']; + $row['targetname'] = $row['tlastname'] . ', ' . $row['tfirstname']; + } elseif (isset($row['lecturename'])) { + $row['targeturl'] = '?do=dozmod§ion=actionlog&action=showtarget&uuid=' . $row['targetid']; + $row['targetname'] = $row['lecturename']; + } + $events[] = $row; + } + $data = array('events' => $events); + if ($showActor) { + $data['showActor'] = true; + } + if ($showTarget) { + $data['showTarget'] = true; + } + Render::addTemplate('actionlog-log', $data); + } + +} \ No newline at end of file diff --git a/modules-available/dozmod/inc/pagedozmodusers.inc.php b/modules-available/dozmod/inc/pagedozmodusers.inc.php new file mode 100644 index 00000000..8da07923 --- /dev/null +++ b/modules-available/dozmod/inc/pagedozmodusers.inc.php @@ -0,0 +1,115 @@ +listUsers(); + $this->listOrganizations(); + } + + protected function doAjax() + { + $action = Request::post('action', '', 'string'); + if ($action === 'setmail' || $action === 'setsu' || $action == 'setlogin') { + $this->setUserOption($action); + } elseif ($action === 'setorglogin') { + $this->setOrgOption($action); + } else { + die('No such action'); + } + } + + // Helpers + + private function listUsers() + { + $res = Database::simpleQuery('SELECT userid, firstname, lastname, email, lastlogin, user.canlogin, issuperuser, emailnotifications,' + . ' organization.displayname AS orgname FROM sat.user' + . ' LEFT JOIN sat.organization USING (organizationid)' + . ' ORDER BY lastname ASC, firstname ASC'); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['canlogin'] = $this->checked($row['canlogin']); + $row['issuperuser'] = $this->checked($row['issuperuser']); + $row['emailnotifications'] = $this->checked($row['emailnotifications']); + $row['lastlogin'] = date('d.m.Y', $row['lastlogin']); + $rows[] = $row; + } + Render::addTemplate('userlist', array('users' => $rows)); + } + + private function listOrganizations() + { + $res = Database::simpleQuery('SELECT organizationid, displayname, canlogin FROM sat.organization' + . ' ORDER BY displayname ASC'); + $rows = array(); + while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + $row['canlogin'] = $this->checked($row['canlogin']); + $rows[] = $row; + } + Render::addTemplate('orglist', array('organizations' => $rows)); + } + + private function checked($val) + { + if ($val) + return 'checked="checked"'; + return ''; + } + + private function setUserOption($option) + { + $val = (string) Request::post('value', '-'); + if ($val !== '1' && $val !== '0') + die('Nein'); + if ($option === 'setmail') { + $field = 'emailnotifications'; + } elseif ($option === 'setsu') { + $field = 'issuperuser'; + } elseif ($option === 'setlogin') { + $field = 'canlogin'; + } else { + die('Unknown'); + } + $user = (string) Request::post('userid', '?'); + $ret = Database::exec("UPDATE sat.user SET $field = :onoff WHERE userid = :userid", array( + 'userid' => $user, + 'onoff' => $val + )); + error_log("Setting $field to $val for $user - affected: $ret"); + if ($ret === false) + die('Error'); + if ($ret === 0) + die(1 - $val); + die($val); + } + + private function setOrgOption($option) + { + $val = (string) Request::post('value', '-'); + if ($val !== '1' && $val !== '0') + die('Nein'); + if ($option === 'setorglogin') { + $field = 'canlogin'; + } else { + die('Unknown'); + } + $ret = Database::exec("UPDATE sat.organization SET $field = :onoff WHERE organizationid = :organizationid", array( + 'organizationid' => (string) Request::post('organizationid', ''), + 'onoff' => $val + )); + if ($ret === false) + die('Error'); + if ($ret === 0) + die(1 - $val); + die($val); + } + +} \ No newline at end of file diff --git a/modules-available/dozmod/inc/pagemailtemplates.inc.php b/modules-available/dozmod/inc/pagemailtemplates.inc.php index 73ce0ade..ef52ec12 100644 --- a/modules-available/dozmod/inc/pagemailtemplates.inc.php +++ b/modules-available/dozmod/inc/pagemailtemplates.inc.php @@ -7,13 +7,6 @@ class Page_mail_templates extends Page protected function doPreprocess() { - User::load(); - - if (!User::hasPermission('superadmin')) { - Message::addError('main.no-permission'); - Util::redirect('?do=Main'); - } - $action = Request::post('action', 'show', 'string'); if ($action === 'show') { $this->fetchTemplates(); diff --git a/modules-available/dozmod/lang/de/module.json b/modules-available/dozmod/lang/de/module.json index 3ab1062d..5840d8af 100644 --- a/modules-available/dozmod/lang/de/module.json +++ b/modules-available/dozmod/lang/de/module.json @@ -1,6 +1,7 @@ { "module_name": "bwLehrpool-Suite", "page_title": "Verwalten der bwLehrpool-Suite", + "submenu_actionlog": "Aktions-Log", "submenu_mailconfig": "Email-Konfiguration", "submenu_runtime": "Limits und Standardwerte", "submenu_templates": "Textbausteine f\u00fcr E-Mails", diff --git a/modules-available/dozmod/lang/de/template-tags.json b/modules-available/dozmod/lang/de/template-tags.json index 18198ab8..fe558ed5 100644 --- a/modules-available/dozmod/lang/de/template-tags.json +++ b/modules-available/dozmod/lang/de/template-tags.json @@ -1,6 +1,9 @@ { + "lang_actionTarget": "Aktionsziel", "lang_asteriskRequired": "Felder mit (*) sind erforderlich", "lang_canLogin": "Nutzer dieser Einrichtung k\u00f6nnen sich am Satelliten anmelden", + "lang_createTime": "Erstellt", + "lang_currentFilter": "Aktueller Filter", "lang_defaultImagePermissionAdmin": "Administrieren", "lang_defaultImagePermissionDownload": "Download", "lang_defaultImagePermissionEdit": "Bearbeiten", @@ -13,15 +16,19 @@ "lang_descriptionPermissionConfig": "Dies sind die Berechtigungen, die ein Benutzer standardm\u00e4\u00dfig f\u00fcr fremde VMs\/Veranstaltungen hat. Sie werden angewandt, wenn der Besitzer keine anderweitigen Berechtigungen w\u00e4hlt.", "lang_descriptionRuntimeLimits": "Hier k\u00f6nnen Sie verschiedene Limits festlegen, z.B. wie lange eine VM nach dem Hochladen g\u00fcltig ist. Nach Ablauf dieses Zeitraums ist der Verantwortliche gezwungen, eine neue Version der VM hochzuladen. Damit k\u00f6nnen Sie das Ansammeln nicht mehr ben\u00f6tigter VMs eind\u00e4mmen. Weiterhin k\u00f6nnen Sie die maximale Anzahl gleichzeitiger Transfers pro Benutzer einschr\u00e4nken.", "lang_description_delete_images": "Diese Liste zeigt VMs, die entweder abgelaufen sind, oder deren Datei besch\u00e4digt, verschoben oder gel\u00f6scht wurde. Diese Images sind zur Zeit im Lehrpool nicht verf\u00fcgbar, ihre endg\u00fcltige L\u00f6schung muss aber manuell best\u00e4tigt werden, um gr\u00f6\u00dfere Katastrophen durch Softwarefehler, verstellte Systemuhren etc. zu vermeiden.", + "lang_dozmodLogHeading": "bwLehrpool-Suite Aktionslog", "lang_email": "EMail", "lang_emailNotifications": "EMail-Benachrichtigungen aktiviert", "lang_error": "Fehler", + "lang_event": "Ereignis", "lang_followingPlaceholdersUnused": "Folgende Platzhalter m\u00fcssen im Template verwendet werden", "lang_hasNewer": "Neuere Version existiert", "lang_heading": "Zu l\u00f6schende VM-Versionen", "lang_host": "Host", "lang_image": "VM", + "lang_lastEditor": "Zuletzt bearbeitet von", "lang_lastLogin": "Letzte Anmeldung", + "lang_lecture": "Veranstaltung", "lang_lecturePermissionAdmin": "Administration", "lang_lecturePermissionEdit": "Bearbeiten", "lang_loadDefaults": "Alle Texte auf Auslieferungszustand zur\u00fccksetzen", @@ -36,6 +43,7 @@ "lang_organization": "Einrichtung", "lang_organizationList": "Liste der Einrichtungen", "lang_organizationListHeader": "Nutzungsrechte f\u00fcr den Satelliten festlegen", + "lang_os": "Betriebssystem", "lang_owner": "Besitzer", "lang_password": "Passwort", "lang_placeholders": "Platzhalter", @@ -54,15 +62,19 @@ "lang_sslNone": "Kein SSL", "lang_subHeading": "Images, die abgelaufen oder besch\u00e4digt sind", "lang_superUser": "Ist SuperUser (darf alle Veranstaltungen und VMs bearbeiten\/l\u00f6schen)", + "lang_system": "System", "lang_template": "Template", "lang_templatePageDescription": "Hier k\u00f6nnen Sie die Textbausteine bearbeiten, aus denen die Mails generiert werden, die der bwLehrpool-Server bez\u00fcglich Virtueller Maschinen und Veranstaltungen versendet. Diese Funktionalit\u00e4t unterst\u00fctzt zur Zeit keine Internationalisierung.", "lang_test": "Test-Mail senden", "lang_testConfiguration": "Um die Konfiguration zu testen, geben Sie hier eine Empf\u00e4ngeradresse ein", "lang_testRecipient": "Empf\u00e4nger", + "lang_updateTime": "Letzte Bearbeitung", "lang_user": "Benutzername", + "lang_userId": "Benutzer-ID", "lang_userList": "Benutzerliste", "lang_userListDescription": "Hier k\u00f6nnen Sie individuelle Nutzer zu \"Super-Usern\" machen. Diese haben im Dozentenmodul auf alle Veranstaltungen und VMs Vollzugriff, unabh\u00e4ngig von den gesetzten Berechtigungen. Au\u00dferdem k\u00f6nnen Sie hier Benutzer vom Zugriff mittels des Dozentenmoduls ausschlie\u00dfen.", "lang_userListHeader": "Dem Satelliten bekannte Benutzer", "lang_username": "Benutzername (SMTP-Auth)", - "lang_version": "Version vom" + "lang_version": "Version vom", + "lang_when": "Wann" } \ No newline at end of file diff --git a/modules-available/dozmod/lang/en/module.json b/modules-available/dozmod/lang/en/module.json index c54d9784..742aa848 100644 --- a/modules-available/dozmod/lang/en/module.json +++ b/modules-available/dozmod/lang/en/module.json @@ -1,6 +1,7 @@ { "module_name": "bwLehrpool-Suite", "page_title": "Manage the bwLehrpool-Suite", + "submenu_actionlog": "action log", "submenu_mailconfig": "email configuration", "submenu_runtime": "limits and defaults", "submenu_templates": "templates", diff --git a/modules-available/dozmod/lang/en/template-tags.json b/modules-available/dozmod/lang/en/template-tags.json index dd7f9391..6a0434a3 100644 --- a/modules-available/dozmod/lang/en/template-tags.json +++ b/modules-available/dozmod/lang/en/template-tags.json @@ -1,6 +1,9 @@ { + "lang_actionTarget": "Action target", "lang_asteriskRequired": "Fields marked with (*) are required", "lang_canLogin": "Members of this organization can login", + "lang_createTime": "Created", + "lang_currentFilter": "Current filter", "lang_defaultImagePermissionAdmin": "Administrate", "lang_defaultImagePermissionDownload": "Download", "lang_defaultImagePermissionEdit": "Edit", @@ -13,15 +16,19 @@ "lang_descriptionPermissionConfig": "These are the default permissions being used for VMs and lectures if the owner does not specify any.", "lang_descriptionRuntimeLimits": "Here you can define some limits, e.g. how long a newly uploaded VM will be valid. This should make sure that you don't end up with a lot of old, unused VMs over time.", "lang_description_delete_images": "This is a list of VMs that either expired, or where the disk image is damaged or missing. These VMs are not available in bwLehrpool currently, but you have to manually confirm the deletion of the disk images for safety reasons (clock skew etc.)", + "lang_dozmodLogHeading": "bwLehrpool-Suite action log", "lang_email": "E-Mail", "lang_emailNotifications": "E-Mail notifications enabled", "lang_error": "Error", + "lang_event": "Event", "lang_followingPlaceholdersUnused": "The following placeholders are not being used", "lang_hasNewer": "Newer version exists", "lang_heading": "Images marked for deletion", "lang_host": "Host", "lang_image": "VM", + "lang_lastEditor": "Edited by", "lang_lastLogin": "Last login", + "lang_lecture": "Lecture", "lang_lecturePermissionAdmin": "Administrate", "lang_lecturePermissionEdit": "Edit", "lang_loadDefaults": "Reset all templates to their defaults", @@ -36,6 +43,7 @@ "lang_organization": "Organization", "lang_organizationList": "List of organizations", "lang_organizationListHeader": "Set access permissions for organizations", + "lang_os": "Operating System", "lang_owner": "Owner", "lang_password": "Password", "lang_placeholders": "Placeholders", @@ -54,15 +62,19 @@ "lang_sslNone": "No SSL", "lang_subHeading": "Expired or damaged images", "lang_superUser": "Is super user (can edit\/delete all lectures and VMs)", + "lang_system": "System", "lang_template": "Template", "lang_templatePageDescription": "Here you can edit text fragments that are used to compose the information and reminder mails sent by the bwLehrpool server, e.g. when a lecture or VM is about to expire.", "lang_test": "Send test mail", "lang_testConfiguration": "To test the configuration, enter a recipient address here", "lang_testRecipient": "Recipient", + "lang_updateTime": "Last update", "lang_user": "User name", + "lang_userId": "User id", "lang_userList": "User list", "lang_userListDescription": "Here you can promote \"super users\", which will have all permissions in the \"Dozenzenmodul\". You can also ban users from accessing this server via the \"Dozentenmodul\".", "lang_userListHeader": "Users known to this satellite", "lang_username": "User name (SMTP auth)", - "lang_version": "Version timestamp" + "lang_version": "Version timestamp", + "lang_when": "When" } \ No newline at end of file diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index 9272f9ff..7bed2380 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -2,8 +2,26 @@ class Page_DozMod extends Page { - /* sub page classes */ - private $mail_templates; + /** @var \Page sub page classes */ + private $subPage = false; + + private function setupSubPage() + { + if ($this->subPage !== false) + return; + /* different pages for different sections */ + $section = Request::any('section', 'mailconfig', 'string'); + /* instantiate sub pages */ + if ($section === 'templates') { + $this->subPage = new Page_mail_templates(); + } + if ($section === 'users') { + $this->subPage = new Page_dozmod_users(); + } + if ($section === 'actionlog') { + $this->subPage = new Page_dozmod_log(); + } + } protected function doPreprocess() { @@ -19,16 +37,11 @@ class Page_DozMod extends Page Dashboard::addSubmenu('?do=dozmod§ion=templates', Dictionary::translate('submenu_templates', true)); Dashboard::addSubmenu('?do=dozmod§ion=runtimeconfig', Dictionary::translate('submenu_runtime', true)); Dashboard::addSubmenu('?do=dozmod§ion=users', Dictionary::translate('submenu_users', true)); + Dashboard::addSubmenu('?do=dozmod§ion=actionlog', Dictionary::translate('submenu_actionlog', true)); - /* instantiate sub pages */ - $this->mail_templates = new Page_mail_templates(); - - - - /* different pages for different sections */ - $section = Request::get('section', 'mailconfig', 'string'); - if ($section == 'templates') { - $this->mail_templates->doPreprocess(); + $this->setupSubPage(); + if ($this->subPage !== false) { + $this->subPage->doPreprocess(); return; } @@ -52,15 +65,15 @@ class Page_DozMod extends Page protected function doRender() { + $this->listDeletePendingImages(); + /* different pages for different sections */ - $section = Request::get('section', 'mailconfig', 'string'); - if ($section == 'templates') { - $this->mail_templates->doRender(); + if ($this->subPage !== false) { + $this->subPage->doRender(); return; } - - $this->listDeletePendingImages(); + $section = Request::get('section', 'mailconfig', 'string'); if ($section === 'mailconfig') { // Mail config @@ -103,11 +116,6 @@ class Page_DozMod extends Page Render::addTemplate('runtimeconfig', $runtimeConf); } - // User list for making people admin - if ($section === 'users') { - $this->listUsers(); - $this->listOrganizations(); - } } private function listDeletePendingImages() @@ -159,16 +167,19 @@ class Page_DozMod extends Page protected function doAjax() { + User::load(); if (!User::hasPermission('superadmin')) return; + $this->setupSubPage(); + if ($this->subPage !== false) { + $this->subPage->doAjax(); + return; + } + $action = Request::post('action'); if ($action === 'mail') { $this->handleTestMail(); - } elseif ($action === 'setmail' || $action === 'setsu' || $action == 'setlogin') { - $this->setUserOption($action); - } elseif ($action === 'setorglogin') { - $this->setOrgOption($action); } elseif ($action === 'delimages') { die($this->handleDeleteImages()); } @@ -282,88 +293,4 @@ class Page_DozMod extends Page Util::redirect('?do=DozMod§ion=runtimeconfig'); } - private function listUsers() - { - $res = Database::simpleQuery('SELECT userid, firstname, lastname, email, lastlogin, user.canlogin, issuperuser, emailnotifications,' - . ' organization.displayname AS orgname FROM sat.user' - . ' LEFT JOIN sat.organization USING (organizationid)' - . ' ORDER BY lastname ASC, firstname ASC'); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['canlogin'] = $this->checked($row['canlogin']); - $row['issuperuser'] = $this->checked($row['issuperuser']); - $row['emailnotifications'] = $this->checked($row['emailnotifications']); - $row['lastlogin'] = date('d.m.Y', $row['lastlogin']); - $rows[] = $row; - } - Render::addTemplate('userlist', array('users' => $rows)); - } - - private function listOrganizations() - { - $res = Database::simpleQuery('SELECT organizationid, displayname, canlogin FROM sat.organization' - . ' ORDER BY displayname ASC'); - $rows = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $row['canlogin'] = $this->checked($row['canlogin']); - $rows[] = $row; - } - Render::addTemplate('orglist', array('organizations' => $rows)); - } - - private function checked($val) - { - if ($val) - return 'checked="checked"'; - return ''; - } - - private function setUserOption($option) - { - $val = (string) Request::post('value', '-'); - if ($val !== '1' && $val !== '0') - die('Nein'); - if ($option === 'setmail') { - $field = 'emailnotifications'; - } elseif ($option === 'setsu') { - $field = 'issuperuser'; - } elseif ($option === 'setlogin') { - $field = 'canlogin'; - } else { - die('Unknown'); - } - $user = (string) Request::post('userid', '?'); - $ret = Database::exec("UPDATE sat.user SET $field = :onoff WHERE userid = :userid", array( - 'userid' => $user, - 'onoff' => $val - )); - error_log("Setting $field to $val for $user - affected: $ret"); - if ($ret === false) - die('Error'); - if ($ret == 0) - die(1 - $val); - die($val); - } - - private function setOrgOption($option) - { - $val = (string) Request::post('value', '-'); - if ($val !== '1' && $val !== '0') - die('Nein'); - if ($option === 'setorglogin') { - $field = 'canlogin'; - } else { - die('Unknown'); - } - $ret = Database::exec("UPDATE sat.organization SET $field = :onoff WHERE organizationid = :organizationid", array( - 'organizationid' => (string) Request::post('organizationid', ''), - 'onoff' => $val - )); - if ($ret === false) - die('Error'); - if ($ret === 0) - die(1 - $val); - die($val); - } - } diff --git a/modules-available/dozmod/templates/actionlog-header.html b/modules-available/dozmod/templates/actionlog-header.html new file mode 100644 index 00000000..bb32efda --- /dev/null +++ b/modules-available/dozmod/templates/actionlog-header.html @@ -0,0 +1 @@ +

{{lang_dozmodLogHeading}}

\ No newline at end of file diff --git a/modules-available/dozmod/templates/actionlog-image.html b/modules-available/dozmod/templates/actionlog-image.html new file mode 100644 index 00000000..cd8c8d1d --- /dev/null +++ b/modules-available/dozmod/templates/actionlog-image.html @@ -0,0 +1,30 @@ +

{{lang_currentFilter}}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{lang_image}}{{displayname}}
{{lang_os}}{{osname}}
{{lang_owner}}{{ofirstname}} {{olastname}}
{{lang_lastEditor}}{{ufirstname}} {{ulastname}}
{{lang_createTime}}{{createtime_s}}
{{lang_updateTime}}{{updatetime_s}}
{{{descriptionHtml}}}
\ No newline at end of file diff --git a/modules-available/dozmod/templates/actionlog-lecture.html b/modules-available/dozmod/templates/actionlog-lecture.html new file mode 100644 index 00000000..4fb2b4d0 --- /dev/null +++ b/modules-available/dozmod/templates/actionlog-lecture.html @@ -0,0 +1,30 @@ +

{{lang_currentFilter}}

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{{lang_lecture}}{{displayname}}
{{lang_owner}}{{ofirstname}} {{olastname}}
{{lang_lastEditor}}{{ufirstname}} {{ulastname}}
{{lang_createTime}}{{createtime_s}}
{{lang_updateTime}}{{updatetime_s}}
{{lang_image}}{{imgname}}
{{{descriptionHtml}}}
\ No newline at end of file diff --git a/modules-available/dozmod/templates/actionlog-log.html b/modules-available/dozmod/templates/actionlog-log.html new file mode 100644 index 00000000..3b523899 --- /dev/null +++ b/modules-available/dozmod/templates/actionlog-log.html @@ -0,0 +1,41 @@ + + + + {{#showActor}} + + {{/showActor}} + {{#showTarget}} + + {{/showTarget}} + + + {{#events}} + + + {{#showActor}} + + {{/showActor}} + {{#showTarget}} + + {{/showTarget}} + + + {{/events}} +
{{lang_when}}{{lang_user}}{{lang_actionTarget}}{{lang_event}}
{{dateline_s}} + {{#uuserid}} + {{ulastname}}, {{ufirstname}} + {{/uuserid}} + {{^uuserid}} + {{lang_system}} + {{/uuserid}} + + {{#targeturl}} + {{targetname}} + {{/targeturl}} + {{^targeturl}} + {{targetname}} + {{^targetname}} + {{targetid}} + {{/targetname}} + {{/targeturl}} + {{description}}
\ No newline at end of file diff --git a/modules-available/dozmod/templates/actionlog-user.html b/modules-available/dozmod/templates/actionlog-user.html new file mode 100644 index 00000000..eefe1386 --- /dev/null +++ b/modules-available/dozmod/templates/actionlog-user.html @@ -0,0 +1,23 @@ +

{{lang_currentFilter}}

+ + + + + + + + + + + + + + + + + + + + + +
{{lang_user}}{{firstname}} {{lastname}}
{{lang_userId}}{{userid}}
{{lang_organization}}{{orgname}}
{{lang_email}}{{email}}
{{lang_lastLogin}}{{lastlogin_s}}
\ No newline at end of file diff --git a/modules-available/dozmod/templates/orglist.html b/modules-available/dozmod/templates/orglist.html index 34fa039c..bb002b3b 100644 --- a/modules-available/dozmod/templates/orglist.html +++ b/modules-available/dozmod/templates/orglist.html @@ -35,33 +35,35 @@ function seto(action, el, orgid) { var v = el.checked ? '1' : '0'; var old = el.checked == true; box.css('display', 'none'); - $.post('?do=DozMod', { token: TOKEN, action: action, organizationid: orgid, value: v }).done(function (data) { - if (data != 1 && data != 0) { + $.post('?do=DozMod', { token: TOKEN, section: 'users', action: action, organizationid: orgid, value: v }).done(function (data) { + + if (data !== '1' && data !== '0') { el.checked = !old; box.parent().css('background-color', 'red !important'); } else { el.checked = (data == 1); + box.parent().css('background-color', ''); + /* show success notification */ + $notification = $('') + .addClass('glyphicon glyphicon-saved') + .css('color', '#2ecc71') + .css('width', '0px') + .css('position', 'relative') + .css('right', '20px') + .hide(); + box.before($notification); + $notification.fadeIn('fast', function () { + $notification.fadeOut('slow', function () { $notification.remove() }); + }); } box.css('display', ''); - /* show success notification */ - $notification = $('') - .addClass('glyphicon glyphicon-saved') - .css('color', '#2ecc71') - .css('width', '0px') - .css('position', 'relative') - .css('right', '20px') - .hide(); - box.before($notification); - $notification.fadeIn('slow', function () {$notification.fadeOut('fast');}); - - - - }).fail(function() { + el.checked = !old; box.parent().css('background-color', 'red !important'); box.css('display', ''); + }); } diff --git a/modules-available/dozmod/templates/userlist.html b/modules-available/dozmod/templates/userlist.html index 79d4848b..7dd84fd4 100644 --- a/modules-available/dozmod/templates/userlist.html +++ b/modules-available/dozmod/templates/userlist.html @@ -22,7 +22,7 @@ {{#users}} - {{lastname}}, {{firstname}} + {{lastname}}, {{firstname}} {{orgname}} {{lastlogin}} {{email}} @@ -44,29 +44,35 @@ function setu(action, el, uid) { var v = el.checked ? '1' : '0'; var old = el.checked == true; box.css('display', 'none'); - $.post('?do=DozMod', { token: TOKEN, action: action, userid: uid, value: v }).done(function (data) { - if (data != 1 && data != 0) { + $.post('?do=DozMod', { token: TOKEN, section: 'users', action: action, userid: uid, value: v }).done(function (data) { + + if (data !== '1' && data !== '0') { el.checked = !old; box.parent().css('background-color', 'red !important'); } else { el.checked = (data == 1); + box.parent().css('background-color', ''); + /* show success notification */ + $notification = $('') + .addClass('glyphicon glyphicon-saved') + .css('color', '#2ecc71') + .css('width', '0px') + .css('position', 'relative') + .css('right', '20px') + .hide(); + box.before($notification); + $notification.fadeIn('fast', function () { + $notification.fadeOut('slow', function () { $notification.remove() }); + }); } - /* show success notification */ - $notification = $('') - .addClass('glyphicon glyphicon-saved') - .css('color', '#2ecc71') - .css('width', '0px') - .css('position', 'relative') - .css('right', '20px') - .hide(); - box.before($notification); - $notification.fadeIn('slow', function () {$notification.fadeOut('fast');}); - box.css('display', ''); + }).fail(function() { + el.checked = !old; box.parent().css('background-color', 'red !important'); box.css('display', ''); + }); } -- cgit v1.2.3-55-g7522 From ab891ea67100d34c8395a414d7ffdf9c9d2e9711 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 17 Aug 2016 12:19:42 +0200 Subject: [main] Show submenu as extra row when not in large mode --- modules-available/main/templates/main-menu.html | 19 ++++++++++++++----- style/default.css | 14 ++++++++++++++ 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/modules-available/main/templates/main-menu.html b/modules-available/main/templates/main-menu.html index 57f0fa88..8dc91f12 100644 --- a/modules-available/main/templates/main-menu.html +++ b/modules-available/main/templates/main-menu.html @@ -1,8 +1,5 @@
- {{#dbupdate}} - DB-Update - {{/dbupdate}} {{#warning}} {{lang_warning}} {{/warning}} @@ -34,7 +31,7 @@ {{#modules}}
  • {{displayName}}
  • {{#subMenu}} -
  • {{name}}
  • +
  • {{name}}
  • {{/subMenu}} {{/modules}} @@ -86,10 +83,22 @@ {{/user}} {{^user}} - {{lang_login}} + {{lang_login}} {{/user}}
    + + diff --git a/style/default.css b/style/default.css index 6ae03b6b..d38ca9e0 100644 --- a/style/default.css +++ b/style/default.css @@ -491,3 +491,17 @@ li.slx-submenu a { nav.navbar.sidebar { color: #eee; } + +.slx-smallsubmenu > li { + display: inline-block; +} + +.slx-smallsubmenu > li + li:before { + padding: 0 3px; + content: "\2022\00a0"; + color: #ccc; +} + +.slx-smallsubmenu a { + color: #fff; +} \ No newline at end of file -- cgit v1.2.3-55-g7522 From 35667fcedba31d809ded2a2c4eb105d75eb2f6f1 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Wed, 17 Aug 2016 12:30:53 +0200 Subject: Clean up css a bit --- modules-available/dozmod/templates/images-delete.html | 10 +++++----- modules-available/dozmod/templates/orglist.html | 2 +- modules-available/dozmod/templates/userlist.html | 8 ++++---- modules-available/locations/templates/locations.html | 12 ++++++------ modules-available/statistics/templates/clientlist.html | 2 +- modules-available/statistics/templates/kvmstate.html | 2 +- modules-available/statistics/templates/memory.html | 2 +- modules-available/statistics/templates/newclients.html | 2 +- modules-available/sysconfig/templates/custom-filelist.html | 2 +- modules-available/sysconfig/templates/custom-fileselect.html | 2 +- modules-available/sysconfig/templates/list-configs.html | 6 +++--- modules-available/sysconfig/templates/list-modules.html | 8 ++++---- style/default.css | 12 ------------ 13 files changed, 29 insertions(+), 41 deletions(-) diff --git a/modules-available/dozmod/templates/images-delete.html b/modules-available/dozmod/templates/images-delete.html index b85d2c06..0ee90835 100644 --- a/modules-available/dozmod/templates/images-delete.html +++ b/modules-available/dozmod/templates/images-delete.html @@ -27,11 +27,11 @@ {{#images}} - {{displayname}}
    {{imageversionid}} - {{version}} - {{lastname}}, {{firstname}} - - {{filesize}} + {{displayname}}
    {{imageversionid}} + {{version}} + {{lastname}}, {{firstname}} + + {{filesize}} {{/images}} diff --git a/modules-available/dozmod/templates/orglist.html b/modules-available/dozmod/templates/orglist.html index bb002b3b..482864de 100644 --- a/modules-available/dozmod/templates/orglist.html +++ b/modules-available/dozmod/templates/orglist.html @@ -16,7 +16,7 @@ {{#organizations}} - {{displayname}} + {{displayname}} diff --git a/modules-available/dozmod/templates/userlist.html b/modules-available/dozmod/templates/userlist.html index 7dd84fd4..93ef7b41 100644 --- a/modules-available/dozmod/templates/userlist.html +++ b/modules-available/dozmod/templates/userlist.html @@ -22,10 +22,10 @@ {{#users}} - {{lastname}}, {{firstname}} - {{orgname}} - {{lastlogin}} - {{email}} + {{lastname}}, {{firstname}} + {{orgname}} + {{lastlogin}} + {{email}} diff --git a/modules-available/locations/templates/locations.html b/modules-available/locations/templates/locations.html index bb13131e..5fec2e2e 100644 --- a/modules-available/locations/templates/locations.html +++ b/modules-available/locations/templates/locations.html @@ -9,10 +9,10 @@ {{#havestatistics}}{{lang_machineCount}}{{/havestatistics}} - + {{#havebaseconfig}}{{lang_editConfigVariables}}{{/havebaseconfig}} - + {{#havesysconfig}}{{lang_sysConfig}}{{/havesysconfig}} @@ -22,13 +22,13 @@
    {{locationname}} - + {{#havestatistics}} {{clientCount}} {{/havestatistics}} - + {{#havebaseconfig}}
    @@ -38,7 +38,7 @@ {{/overriddenVars}} {{/havebaseconfig}} - + {{#havesysconfig}}
    @@ -53,7 +53,7 @@ {{#unassignedCount}} {{lang_unassignedMachines}} - + {{unassignedCount}} diff --git a/modules-available/statistics/templates/clientlist.html b/modules-available/statistics/templates/clientlist.html index 3a1b52ac..ca4b971a 100644 --- a/modules-available/statistics/templates/clientlist.html +++ b/modules-available/statistics/templates/clientlist.html @@ -58,7 +58,7 @@ {{#rows}} - + {{#hasnotes}}{{/hasnotes}} {{#state_off}} diff --git a/modules-available/statistics/templates/kvmstate.html b/modules-available/statistics/templates/kvmstate.html index c44fb9ab..33a00d38 100644 --- a/modules-available/statistics/templates/kvmstate.html +++ b/modules-available/statistics/templates/kvmstate.html @@ -13,7 +13,7 @@ {{#rows}} - + {{kvmstate}} {{count}} diff --git a/modules-available/statistics/templates/memory.html b/modules-available/statistics/templates/memory.html index 2d50c47f..ae040674 100644 --- a/modules-available/statistics/templates/memory.html +++ b/modules-available/statistics/templates/memory.html @@ -13,7 +13,7 @@ {{#rows}} - + {{gb}} GiB {{count}} diff --git a/modules-available/statistics/templates/newclients.html b/modules-available/statistics/templates/newclients.html index 0d9c74df..e7d79818 100644 --- a/modules-available/statistics/templates/newclients.html +++ b/modules-available/statistics/templates/newclients.html @@ -14,7 +14,7 @@ {{#rows}} - {{hostname}} + {{hostname}} {{firstseen}} {{kvmicon}} {{gbram}} GiB diff --git a/modules-available/sysconfig/templates/custom-filelist.html b/modules-available/sysconfig/templates/custom-filelist.html index 3ad241dd..344eece3 100644 --- a/modules-available/sysconfig/templates/custom-filelist.html +++ b/modules-available/sysconfig/templates/custom-filelist.html @@ -4,7 +4,7 @@ {{#files}} {{#isdir}} - {{name}} + {{name}} {{/isdir}} {{^isdir}} {{name}} diff --git a/modules-available/sysconfig/templates/custom-fileselect.html b/modules-available/sysconfig/templates/custom-fileselect.html index 000c8d10..f14a6fde 100644 --- a/modules-available/sysconfig/templates/custom-fileselect.html +++ b/modules-available/sysconfig/templates/custom-fileselect.html @@ -16,7 +16,7 @@ {{#files}} {{#isdir}} - {{name}} + {{name}} {{/isdir}} {{^isdir}} {{name}} diff --git a/modules-available/sysconfig/templates/list-configs.html b/modules-available/sysconfig/templates/list-configs.html index ed027385..987becfd 100644 --- a/modules-available/sysconfig/templates/list-configs.html +++ b/modules-available/sysconfig/templates/list-configs.html @@ -21,7 +21,7 @@ {{#configs}} - - - diff --git a/modules-available/sysconfig/templates/list-modules.html b/modules-available/sysconfig/templates/list-modules.html index 5b2c940b..29726c5d 100644 --- a/modules-available/sysconfig/templates/list-modules.html +++ b/modules-available/sysconfig/templates/list-modules.html @@ -11,15 +11,15 @@
    +
    {{config}}
    @@ -45,7 +45,7 @@ {{/locationCount}} + +
    {{#modules}} - - - + + -
    {{moduleType}}
    {{title}}
    + {{moduleType}}
    {{title}}
    {{#allowDownload}} {{/allowDownload}} +