diff options
Diffstat (limited to 'modules-available/sysconfig')
36 files changed, 711 insertions, 644 deletions
diff --git a/modules-available/sysconfig/addconfig.inc.php b/modules-available/sysconfig/addconfig.inc.php index a22cdc46..27af31e8 100644 --- a/modules-available/sysconfig/addconfig.inc.php +++ b/modules-available/sysconfig/addconfig.inc.php @@ -9,21 +9,17 @@ abstract class AddConfig_Base /** * Holds the instance for the currently executing step - * @var \AddConfig_Base + * @var AddConfig_Base */ - private static $instance = false; + private static $instance = null; /** * Config being edited (if any) - * @var \ConfigTgz + * @var ?ConfigTgz */ - protected $edit = false; + protected $edit = null; - /** - * - * @param string $step - */ - public static function setStep($step) + public static function setStep(string $step) { if (empty($step) || !class_exists($step) || get_parent_class($step) !== 'AddConfig_Base') { Message::addError('invalid-action', $step); @@ -32,18 +28,12 @@ abstract class AddConfig_Base self::$instance = new $step(); if (($editId = Request::any('edit', 0, 'int')) !== 0) { self::$instance->edit = ConfigTgz::get($editId); - if (self::$instance->edit === false) - Util::traceError('Invalid config id for editing'); + if (self::$instance->edit === null) + ErrorHandler::traceError('Invalid config id for editing'); Util::addRedirectParam('edit', self::$instance->edit->id()); } } - protected function tmError() - { - Message::addError('main.taskmanager-error'); - Util::redirect('?do=SysConfig'); - } - /** * Called before any HTML rendering happens, so you can * prepare stuff, validate input, and optionally redirect @@ -73,25 +63,25 @@ abstract class AddConfig_Base public static function preprocess() { - if (self::$instance === false) { - Util::traceError('No step instance yet'); + if (self::$instance === null) { + ErrorHandler::traceError('No step instance yet'); } self::$instance->preprocessInternal(); } public static function render() { - if (self::$instance === false) - Util::traceError('No step instance yet'); - if (self::$instance->edit !== false) + if (self::$instance === null) + ErrorHandler::traceError('No step instance yet'); + if (self::$instance->edit !== null) Message::addInfo('replacing-config', self::$instance->edit->title()); self::$instance->renderInternal(); } public static function ajax() { - if (self::$instance === false) { - Util::traceError('No step instance yet'); + if (self::$instance === null) { + ErrorHandler::traceError('No step instance yet'); } self::$instance->ajaxInternal(); } @@ -110,7 +100,7 @@ class AddConfig_Start extends AddConfig_Base $mods = ConfigModule::getList(); $res = Database::simpleQuery("SELECT moduleid, title, moduletype, filepath FROM configtgz_module" . " ORDER BY title ASC"); // Move to ConfigModule - if ($this->edit === false) { + if ($this->edit === null) { $active = array(); } else { $active = $this->edit->getModuleIds(); @@ -122,7 +112,7 @@ class AddConfig_Start extends AddConfig_Base $modGroups[$mod['group']] =& $mod; } unset($mod); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { if (!isset($mods[$row['moduletype']])) { $mods[$row['moduletype']] = array( 'unique' => false, @@ -140,7 +130,7 @@ class AddConfig_Start extends AddConfig_Base $row['active'] = in_array($row['moduleid'], $active); $group['modules'][] = $row; } - if ($this->edit !== false) { + if ($this->edit !== null) { $title = $this->edit->title(); } else { $title = Request::any('title', '', 'string'); @@ -162,7 +152,7 @@ class AddConfig_Start extends AddConfig_Base 'step' => 'AddConfig_Finish', 'groups' => array_values($modGroups), 'title' => $title, - 'edit' => ($this->edit !== false ? $this->edit->id() : false) + 'edit' => $this->edit === null ? null : $this->edit->id(), )); } @@ -174,9 +164,9 @@ class AddConfig_Start extends AddConfig_Base class AddConfig_Finish extends AddConfig_Base { /** - * @var ConfigTgz + * @var ?ConfigTgz */ - private $config = false; + private $config = null; protected function preprocessInternal() { @@ -186,13 +176,13 @@ class AddConfig_Finish extends AddConfig_Base Message::addError('missing-file'); Util::redirect('?do=SysConfig&action=addconfig'); } - if ($this->edit === false) { + if ($this->edit === null) { $this->config = ConfigTgz::insert($title, $modules); } else { $this->edit->update($title, $modules); $this->config = $this->edit; } - if ($this->config === false || $this->config->generate(true, 150) === false) { + if ($this->config->generate(true, 150) === false) { Message::addError('unsuccessful-action'); Util::redirect('?do=SysConfig&action=addconfig'); } diff --git a/modules-available/sysconfig/addmodule.inc.php b/modules-available/sysconfig/addmodule.inc.php index 91fee45d..4564537e 100644 --- a/modules-available/sysconfig/addmodule.inc.php +++ b/modules-available/sysconfig/addmodule.inc.php @@ -9,34 +9,39 @@ abstract class AddModule_Base /** * Holds the instance for the currently executing step - * @var \AddModule_Base + * + * @var AddModule_Base */ private static $instance = false; /** * Instance of ConfigModule we're editing. False if not editing but creating. - * @var \ConfigModule + * + * @var ?ConfigModule */ - protected $edit = false; + protected $edit = null; /** * * @param string $step name of class representing the current step * @param int $editId (optional) overwrite for the request parameter 'edit' */ - public static function setStep($step, $editId = false) + public static function setStep(string $step, int $editId = null): void { if (empty($step) || !class_exists($step) || get_parent_class($step) !== 'AddModule_Base') { Message::addError('invalid-action', $step); Util::redirect('?do=SysConfig'); } self::$instance = new $step(); - if ($editId = $editId ? $editId : Request::any('edit')) { + if ($editId === null) { + $editId = Request::any('edit', 0, 'int'); + } + if ($editId !== 0) { self::$instance->edit = ConfigModule::get($editId); - if (self::$instance->edit === false) - Util::traceError('Invalid module id for editing'); + if (self::$instance->edit === null) + ErrorHandler::traceError('Invalid module id for editing'); if ($step !== 'AddModule_Assign' && !preg_match('/^' . self::$instance->edit->moduleType() . '_/', $step)) - Util::traceError('Module to edit is of different type!'); + ErrorHandler::traceError('Module to edit is of different type!'); Util::addRedirectParam('edit', self::$instance->edit->id()); } } @@ -90,7 +95,7 @@ abstract class AddModule_Base public static function preprocess() { if (self::$instance === false) { - Util::traceError('No step instance yet'); + ErrorHandler::traceError('No step instance yet'); } self::$instance->preprocessInternal(); } @@ -98,9 +103,9 @@ abstract class AddModule_Base public static function render() { if (self::$instance === false) { - Util::traceError('No step instance yet'); + ErrorHandler::traceError('No step instance yet'); } - if (get_class(self::$instance) !== 'AddModule_Assign' && self::$instance->edit !== false) { + if (get_class(self::$instance) !== 'AddModule_Assign' && self::$instance->edit !== null) { Message::addInfo('replacing-module', self::$instance->edit->title()); } self::$instance->renderInternal(); @@ -109,7 +114,7 @@ abstract class AddModule_Base public static function ajax() { if (self::$instance === false) { - Util::traceError('No step instance yet'); + ErrorHandler::traceError('No step instance yet'); } self::$instance->ajaxInternal(); } @@ -155,7 +160,7 @@ class AddModule_Assign extends AddModule_Base if (ConfigModule::getList()[$moduleType]['unique']) { $moduleIds = []; - foreach (ConfigModule::getAll($moduleType) as $module) { + foreach (ConfigModule::getAll($moduleType) ?? [] as $module) { $moduleIds[] = $module->id(); } @@ -209,41 +214,26 @@ class AddModule_Assign extends AddModule_Base * Helper functions to set/get a batch of vars from/to post variables or a module */ -/** - * - * @param \ConfigModule $module - * @param array $array - * @param array $keys - */ -function moduleToArray($module, &$array, $keys) +function moduleToArray(ConfigModule $module, array &$array, array $keys): void { foreach ($keys as $key) { $array[$key] = $module->getData($key); } } -/** - * - * @param \ConfigModule $module - * @param array $array - * @param array $keys - */ -function arrayToModule($module, $array, $keys) +function arrayToModule(ConfigModule $module, array $array, array $keys): void { foreach ($keys as $key) { $module->setData($key, $array[$key]); } } -/** - * - * @param array $array - * @param array $keys - */ -function postToArray(&$array, $keys, $ignoreMissing = false) + +function postToArray(array &$array, array $keys, $ignoreMissing = false): void { foreach ($keys as $key) { $val = Request::post($key, '--not-in-post'); - if ($ignoreMissing && $val === '--not-in-post') continue; + if ($ignoreMissing && $val === '--not-in-post') + continue; $array[$key] = $val; } } diff --git a/modules-available/sysconfig/addmodule_adauth.inc.php b/modules-available/sysconfig/addmodule_adauth.inc.php index f2ac206e..42187171 100644 --- a/modules-available/sysconfig/addmodule_adauth.inc.php +++ b/modules-available/sysconfig/addmodule_adauth.inc.php @@ -15,7 +15,7 @@ class AdAuth_Start extends AddModule_Base { $ADAUTH_COMMON_FIELDS = array('title', 'server', 'searchbase', 'binddn', 'bindpw', 'home', 'homeattr', 'ssl', 'genuid', 'certificate', 'mapping', 'nohomewarn'); $data = array(); - if ($this->edit !== false) { + if ($this->edit !== null) { moduleToArray($this->edit, $data, $ADAUTH_COMMON_FIELDS); $data['title'] = $this->edit->title(); $data['edit'] = $this->edit->id(); @@ -35,7 +35,7 @@ class AdAuth_Start extends AddModule_Base } $data['step'] = 'AdAuth_CheckConnection'; $data['map_empty'] = true; - $data['mapping'] = ConfigModuleBaseLdap::getMapping(isset($data['mapping']) ? $data['mapping'] : false, $data['map_empty']); + $data['mapping'] = ConfigModuleBaseLdap::getMapping($data['mapping'] ?? null, $data['map_empty']); Render::addDialog(Dictionary::translateFile('config-module', 'adAuth_title'), false, 'ad-start', $data); } @@ -89,13 +89,12 @@ class AdAuth_CheckConnection extends AddModule_Base )); if (!isset($this->scanTask['id'])) { AddModule_Base::setStep('AdAuth_Start'); // Continues with AdAuth_Start for render() - return; } } protected function renderInternal() { - $mapping = Request::post('mapping', false, 'array'); + $mapping = Request::post('mapping', null, 'array'); $data = array( 'edit' => Request::post('edit'), 'title' => Request::post('title'), @@ -131,7 +130,7 @@ class AdAuth_SelfSearch extends AddModule_Base protected function preprocessInternal() { - $server = $binddn = $port = null; + $server = $binddn = null; $searchbase = Request::post('searchbase', ''); $bindpw = Request::post('bindpw'); $ssl = Request::post('ssl', 'off') === 'on'; @@ -140,14 +139,8 @@ class AdAuth_SelfSearch extends AddModule_Base AddModule_Base::setStep('AdAuth_Start'); // Continues with AdAuth_Start for render() return; } - foreach (['server', 'binddn', 'port'] as $var) { - $$var = Request::post($var, null); - if (empty($$var)) { - Message::addError('main.parameter-empty', $var); - AddModule_Base::setStep('AdAuth_Start'); // Continues with AdAuth_Start for render() - return; - } - } + $server = Request::post('server', Request::REQUIRED, 'string'); + $binddn = Request::post('binddn', Request::REQUIRED, 'string'); $this->originalBindDn = ''; // Fix bindDN if short name given // @@ -195,7 +188,7 @@ class AdAuth_SelfSearch extends AddModule_Base protected function renderInternal() { - $mapping = Request::post('mapping', false, 'array'); + $mapping = Request::post('mapping', null, 'array'); $data = array( 'edit' => Request::post('edit'), 'title' => Request::post('title'), @@ -288,7 +281,7 @@ class AdAuth_HomeAttrCheck extends AddModule_Base 'certificate' => Request::post('certificate', ''), 'originalbinddn' => Request::post('originalbinddn'), 'tryHomeAttr' => true, - 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', false, 'array')), + 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', null, 'array')), 'prev' => 'AdAuth_Start', 'next' => 'AdAuth_CheckCredentials' )) @@ -359,7 +352,7 @@ class AdAuth_CheckCredentials extends AddModule_Base 'fingerprint' => Request::post('fingerprint'), 'certificate' => Request::post('certificate', ''), 'originalbinddn' => Request::post('originalbinddn'), - 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', false, 'array')), + 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', null, 'array')), 'prev' => 'AdAuth_Start', 'next' => 'AdAuth_HomeDir' )) @@ -423,11 +416,11 @@ class AdAuth_HomeDir extends AddModule_Base 'fingerprint' => Request::post('fingerprint'), 'certificate' => Request::post('certificate', ''), 'originalbinddn' => Request::post('originalbinddn'), - 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', false, 'array')), + 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', null, 'array')), 'prev' => 'AdAuth_Start', 'next' => 'AdAuth_Finish' ); - if ($this->edit !== false) { + if ($this->edit !== null) { foreach (self::getAttributes() as $key) { if ($this->edit->getData($key)) { $data[$key . '_c'] = 'checked="checked"'; @@ -448,13 +441,13 @@ class AdAuth_HomeDir extends AddModule_Base foreach (range('D', 'Z') as $l) { $data['drives'][] = array( 'drive' => $l . ':', - 'selected' => (strtoupper($letter{0}) === $l) ? 'selected="selected"' : '' + 'selected' => (strtoupper($letter[0]) === $l) ? 'selected="selected"' : '' ); } Render::addDialog(Dictionary::translateFile('config-module', 'adAuth_title'), false, 'ad_ldap-homedir', $data); } - public static function getAttributes() + public static function getAttributes(): array { return array('shareRemapMode', 'shareRemapCreate', 'shareDocuments', 'shareDownloads', 'shareDesktop', 'shareMedia', 'shareOther', 'shareHomeDrive', 'shareDomain', 'credentialPassthrough'); @@ -472,10 +465,11 @@ class AdAuth_Finish extends AddModule_Base $title = Request::post('title'); if (empty($title)) $title = 'AD: ' . Request::post('server'); - if ($this->edit === false) + if ($this->edit === null) { $module = ConfigModule::getInstance('AdAuth'); - else + } else { $module = $this->edit; + } $ssl = Request::post('ssl', 'off') === 'on'; foreach (['searchbase', 'binddn', 'server', 'bindpw', 'home', 'nohomewarn', 'homeattr', 'certificate', 'genuid', 'ldapAttrMountOpts', 'shareHomeMountOpts'] as $key) { @@ -499,7 +493,7 @@ class AdAuth_Finish extends AddModule_Base } else { $module->setData('fingerprint', ''); } - if ($this->edit !== false) + if ($this->edit !== null) $ret = $module->update($title); else $ret = $module->insert($title); @@ -507,7 +501,7 @@ class AdAuth_Finish extends AddModule_Base Message::addError('main.value-invalid', 'any', 'any'); $tgz = false; } else { - $tgz = $module->generate($this->edit === false); + $tgz = $module->generate($this->edit === null); } if ($tgz === false) { AddModule_Base::setStep('AdAuth_Start'); // Continues with AdAuth_Start for render() @@ -517,9 +511,8 @@ class AdAuth_Finish extends AddModule_Base 'tm-config' => $tgz, ); - if ($this->edit === false) { + if ($this->edit === null) { AddModule_Base::setStep('AddModule_Assign', $module->id()); - return; } } diff --git a/modules-available/sysconfig/addmodule_branding.inc.php b/modules-available/sysconfig/addmodule_branding.inc.php index d941a7a7..54b2ad57 100644 --- a/modules-available/sysconfig/addmodule_branding.inc.php +++ b/modules-available/sysconfig/addmodule_branding.inc.php @@ -11,7 +11,7 @@ class Branding_Start extends AddModule_Base { Render::addDialog(Dictionary::translateFile('config-module', 'branding_title'), false, 'branding-start', array( 'step' => 'Branding_ProcessFile', - 'edit' => $this->edit ? $this->edit->id() : false + 'edit' => $this->edit == null ? null : $this->edit->id(), )); } @@ -22,7 +22,6 @@ class Branding_ProcessFile extends AddModule_Base private $task; private $svgFile; - private $tarFile; protected function preprocessInternal() { @@ -48,14 +47,16 @@ class Branding_ProcessFile extends AddModule_Base if (strpos($url, '://') === false) $url = "http://$url"; $title = false; - if (!$this->downloadSvg($this->svgFile, $url, $title)) + if (!Branding_ProcessFile::downloadSvg($this->svgFile, $url, $title)) { + @unlink($this->svgFile); Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); + } Session::set('logo_name', $title); } chmod($this->svgFile, 0644); - $this->tarFile = '/tmp/bwlp-' . time() . '-' . mt_rand() . '.tgz'; + $tarFile = '/tmp/bwlp-' . time() . '-' . mt_rand() . '.tgz'; $this->task = Taskmanager::submit('BrandingGenerator', array( - 'tarFile' => $this->tarFile, + 'tarFile' => $tarFile, 'svgFile' => $this->svgFile )); $this->task = Taskmanager::waitComplete($this->task, 5000); @@ -64,8 +65,7 @@ class Branding_ProcessFile extends AddModule_Base Taskmanager::addErrorMessage($this->task); Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); } - Session::set('logo_tgz', $this->tarFile); - Session::save(); + Session::set('logo_tgz', $tarFile); } protected function renderInternal() @@ -75,13 +75,13 @@ class Branding_ProcessFile extends AddModule_Base $png = base64_encode(file_get_contents($this->task['data']['pngFile'])); if (filesize($this->svgFile) < 1000000) $svg = base64_encode(file_get_contents($this->svgFile)); - Render::addDialog(Dictionary::translate('config-module', 'branding_title'), false, 'branding-check', array( + Render::addDialog(Dictionary::translateFile('config-module', 'branding_title'), false, 'branding-check', array( 'png' => $png, 'svg' => $svg, - 'error' => $this->task['data']['error'], + 'error' => $this->task['data']['error'] ?? $this->task['statusCode'], 'step' => 'Branding_Finish', - 'edit' => $this->edit ? $this->edit->id() : false, - 'title' => $this->edit ? $this->edit->title() : false + 'edit' => $this->edit === null ? null : $this->edit->id(), + 'title' => $this->edit === null ? null : $this->edit->title(), ) ); @unlink($this->svgFile); @@ -96,39 +96,56 @@ class Branding_ProcessFile extends AddModule_Base * @return boolean true of download succeeded, false on download error (also returns true if downloaded file doesn't * seem to be svg!) */ - private function downloadSvg($svgName, $url, &$title) + private static function downloadSvg(string $svgName, string $url, &$title): bool { $title = false; - // [wikipedia] Did someone paste a link to a thumbnail of the svg? Let's fix that... - if (preg_match('#^(.*)/thumb/(.*\.svg)/.*\.svg#', $url, $out)) { - $url = $out[1] . '/' . $out[2]; - } for ($i = 0; $i < 5; ++$i) { + // [wikipedia] Did someone paste a link to a thumbnail of the svg? Let's fix that... + if (preg_match('#^(.*)/thumb/(.*\.svg)/.*\.svg#', $url, $out)) { + $url = $out[1] . '/' . $out[2]; + } $code = 400; if (!Download::toFile($svgName, $url, 3, $code) || $code < 200 || $code > 299) { Message::addError('remote-timeout', $url, $code); return false; } - $content = FileUtil::readFile($svgName, 25000); + $content = FileUtil::readFile($svgName, 250000); // Is svg file? if (strpos($content, '<svg') !== false) return true; // Found an svg tag - don't try to find links to the actual image // [wikipedia] Try to be nice and detect links that might give a hint where the svg can be found - if (preg_match_all('#href="([^"]*upload.wikimedia.org/[^"]*/[^"]*/[^"]*\.svg|[^"]+/[^"]+:[^"]+\.svg[^"]*)"#', $content, $out, PREG_PATTERN_ORDER)) { + $out1 = $out2 = $out3 = null; + if (preg_match_all('#href="([^"]*upload.wikimedia.org/[^"]*/[^"]*/[^"]*\.svg)"#', $content, $out1, PREG_PATTERN_ORDER) + || preg_match_all('#src="([^"]*upload.wikimedia.org/[^"]*/thumb/[^"]*\.svg/[^"]+\.svg[^"]*)"#', $content, $out2, PREG_PATTERN_ORDER) + || preg_match_all('#href="([^"]+/[^"]+:[^"]+\.svg)"#', $content, $out3, PREG_PATTERN_ORDER)) { if ($title === false && preg_match('#<title>([^<]*)</title>#i', $content, $tout)) { $title = trim(preg_replace('/\W*Wikipedia.*/', '', $tout[1])); } $new = false; - foreach ($out[1] as $res) { + $out = []; + if (isset($out1[1])) { + $out += $out1[1]; + } + if (isset($out2[1])) { + $out += $out2[1]; + } + if (isset($out3[1])) { + $out += $out3[1]; + } + foreach ($out as $res) { + error_log("Match '$res'"); + if (!preg_match('/hochschule|univers|logo|siegel/i', $res)) + continue; if (strpos($res, 'action=edit') !== false) continue; - $new = $this->internetCombineUrl($url, html_entity_decode($res, ENT_COMPAT, 'UTF-8')); + $new = Branding_ProcessFile::internetCombineUrl($url, html_entity_decode($res, ENT_COMPAT, 'UTF-8')); if ($new !== $url) break; } if ($new === $url || $new === false) break; + error_log("New: '$new'"); $url = $new; continue; } @@ -145,7 +162,7 @@ class Branding_ProcessFile extends AddModule_Base * @param string $relative relative url that will be converted to an absolute url * @return string combined absolute url */ - private function internetCombineUrl($absolute, $relative) + private static function internetCombineUrl(string $absolute, string $relative): string { $p = parse_url($relative); if (!empty($p["scheme"])) @@ -154,8 +171,8 @@ class Branding_ProcessFile extends AddModule_Base $parsed = parse_url($absolute); $path = dirname($parsed['path']); - if ($relative{0} === '/') { - if ($relative{1} === '/') + if ($relative[0] === '/') { + if ($relative[1] === '/') return "{$parsed['scheme']}:$relative"; $cparts = array_filter(explode("/", $relative)); } else { @@ -197,9 +214,9 @@ class Branding_Finish extends AddModule_Base protected function preprocessInternal() { $title = Request::post('title'); - if ($title === false || empty($title)) + if (empty($title)) $title = Session::get('logo_name'); - if ($title === false || empty($title)) { + if (empty($title)) { Message::addError('missing-title'); // TODO: Ask for title again instead of starting over Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); } @@ -208,30 +225,26 @@ class Branding_Finish extends AddModule_Base Message::addError('main.error-read', $tgz); Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); } - if ($this->edit === false) + if ($this->edit === null) { $module = ConfigModule::getInstance('Branding'); - else + } else { $module = $this->edit; - if ($module === false) { - Message::addError('main.error-read', 'branding.inc.php'); - Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); } $module->setData('tmpFile', $tgz); - if ($this->edit !== false) + if ($this->edit !== null) $ret = $module->update($title); else $ret = $module->insert($title); if (!$ret) Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); - elseif ($module->generate($this->edit === false, NULL, 200) === false) + elseif ($module->generate($this->edit === null, NULL, 200) === false) Util::redirect('?do=SysConfig&action=addmodule&step=Branding_Start'); Session::set('logo_tgz', false); Session::set('logo_name', false); - Session::save(); // Yay - if ($this->edit !== false) + if ($this->edit !== null) { Message::addSuccess('module-edited'); - else { + } else { Message::addSuccess('module-added'); AddModule_Base::setStep('AddModule_Assign', $module->id()); return; diff --git a/modules-available/sysconfig/addmodule_custommodule.inc.php b/modules-available/sysconfig/addmodule_custommodule.inc.php index f7ab863e..3afdad0a 100644 --- a/modules-available/sysconfig/addmodule_custommodule.inc.php +++ b/modules-available/sysconfig/addmodule_custommodule.inc.php @@ -14,7 +14,7 @@ class CustomModule_Start extends AddModule_Base Session::set('mod_temp', false); Render::addDialog(Dictionary::translateFile('config-module', 'custom_title'), false, 'custom-upload', array( 'step' => 'CustomModule_ProcessUpload', - 'edit' => $this->edit ? $this->edit->id() : false + 'edit' => $this->edit === null ? null : $this->edit->id(), )); } @@ -55,7 +55,7 @@ class CustomModule_ProcessUpload extends AddModule_Base protected function renderInternal() { - $status = Taskmanager::waitComplete($this->taskId); + $status = Taskmanager::waitComplete($this->taskId, 7500); Taskmanager::release($this->taskId); $userGroupWarn = false; $tempfile = Session::get('mod_temp'); @@ -69,21 +69,20 @@ class CustomModule_ProcessUpload extends AddModule_Base } $list = SysConfig::archiveContentsFromTask($status, $userGroupWarn); - if ($this->edit !== false) { + if ($this->edit !== null) { $title = $this->edit->title(); } else if (isset($_FILES['modulefile']['name'])) { $title = basename($_FILES['modulefile']['name']); } else { $title = ''; } - Render::addDialog(Dictionary::translate('config-module', 'custom_title'), false, 'custom-fileselect', array( + Render::addDialog(Dictionary::translateFile('config-module', 'custom_title'), false, 'custom-fileselect', array( 'step' => 'CustomModule_CompressModule', 'files' => $list, - 'edit' => $this->edit ? $this->edit->id() : false, + 'edit' => $this->edit === null ? null : $this->edit->id(), 'title' => $title, 'userGroupWarn' => $userGroupWarn, )); - Session::save(); } } @@ -108,7 +107,7 @@ class CustomModule_CompressModule extends AddModule_Base 'outputFile' => $destFile, 'forceRoot' => Request::post('force-owner', 0, 'int') !== 0, ), true); - $status = Taskmanager::waitComplete($taskId, 5000); + $status = Taskmanager::waitComplete($taskId, 10000); unlink($tempfile); if (!isset($status['statusCode'])) { $this->tmError(); @@ -117,29 +116,26 @@ class CustomModule_CompressModule extends AddModule_Base $this->taskError($status); } // Seems ok, create entry - if ($this->edit === false) + if ($this->edit === null) { $module = ConfigModule::getInstance('CustomModule'); - else + } else { $module = $this->edit; - if ($module === false) { - Message::addError('main.error-read', 'custommodule.inc.php'); - Util::redirect('?do=SysConfig&action=addmodule&step=CustomModule_Start'); } $module->setData('tmpFile', $destFile); - if ($this->edit !== false) + if ($this->edit !== null) { $ret = $module->update($title); - else + } else { $ret = $module->insert($title); + } if (!$ret) Util::redirect('?do=SysConfig&action=addmodule&step=CustomModule_Start'); - elseif (!$module->generate($this->edit === false, NULL, 200)) + elseif (!$module->generate($this->edit === null, NULL, 200)) Util::redirect('?do=SysConfig&action=addmodule&step=CustomModule_Start'); Session::set('mod_temp', false); - Session::save(); // Yay - if ($this->edit !== false) + if ($this->edit !== null) { Message::addSuccess('module-edited'); - else { + } else { Message::addSuccess('module-added'); AddModule_Base::setStep('AddModule_Assign', $module->id()); return; diff --git a/modules-available/sysconfig/addmodule_ldapauth.inc.php b/modules-available/sysconfig/addmodule_ldapauth.inc.php index 606ce381..6a385d9c 100644 --- a/modules-available/sysconfig/addmodule_ldapauth.inc.php +++ b/modules-available/sysconfig/addmodule_ldapauth.inc.php @@ -11,7 +11,7 @@ class LdapAuth_Start extends AddModule_Base { $LDAPAUTH_COMMON_FIELDS = array('title', 'server', 'searchbase', 'binddn', 'bindpw', 'home', 'homeattr', 'ssl', 'genuid', 'certificate', 'mapping', 'nohomewarn'); $data = array(); - if ($this->edit !== false) { + if ($this->edit !== null) { moduleToArray($this->edit, $data, $LDAPAUTH_COMMON_FIELDS); $data['title'] = $this->edit->title(); $data['edit'] = $this->edit->id(); @@ -27,7 +27,7 @@ class LdapAuth_Start extends AddModule_Base } $data['step'] = 'LdapAuth_CheckConnection'; $data['map_empty'] = true; - $data['mapping'] = ConfigModuleBaseLdap::getMapping(isset($data['mapping']) ? $data['mapping'] : false, $data['map_empty']); + $data['mapping'] = ConfigModuleBaseLdap::getMapping($data['mapping'] ?? null, $data['map_empty']); Render::addDialog(Dictionary::translateFile('config-module', 'ldapAuth_title'), false, 'ldap-start', $data); } @@ -64,7 +64,6 @@ class LdapAuth_CheckConnection extends AddModule_Base )); if (!isset($this->scanTask['id'])) { AddModule_Base::setStep('LdapAuth_Start'); // Continues with LdapAuth_Start for render() - return; } } @@ -82,7 +81,7 @@ class LdapAuth_CheckConnection extends AddModule_Base 'genuid' => Request::post('genuid'), 'certificate' => Request::post('certificate', ''), 'taskid' => $this->scanTask['id'], - 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', false, 'array')), + 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', null, 'array')), ); $data['prev'] = 'LdapAuth_Start'; $data['next'] = 'LdapAuth_CheckCredentials'; @@ -153,7 +152,7 @@ class LdapAuth_CheckCredentials extends AddModule_Base 'genuid' => Request::post('genuid'), 'fingerprint' => Request::post('fingerprint'), 'certificate' => Request::post('certificate', ''), - 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', false, 'array')), + 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', null, 'array')), 'prev' => 'LdapAuth_Start', 'next' => 'LdapAuth_HomeDir', )) @@ -194,11 +193,11 @@ class LdapAuth_HomeDir extends AddModule_Base 'fingerprint' => Request::post('fingerprint'), 'certificate' => Request::post('certificate', ''), 'originalbinddn' => Request::post('originalbinddn'), - 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', false, 'array')), + 'mapping' => ConfigModuleBaseLdap::getMapping(Request::post('mapping', null, 'array')), 'prev' => 'LdapAuth_Start', 'next' => 'LdapAuth_Finish', ); - if ($this->edit !== false) { + if ($this->edit !== null) { foreach (self::getAttributes() as $key) { if ($this->edit->getData($key)) { $data[$key . '_c'] = 'checked="checked"'; @@ -219,13 +218,13 @@ class LdapAuth_HomeDir extends AddModule_Base foreach (range('D', 'Z') as $l) { $data['drives'][] = array( 'drive' => $l . ':', - 'selected' => (strtoupper($letter{0}) === $l) ? 'selected="selected"' : '' + 'selected' => (strtoupper($letter[0]) === $l) ? 'selected="selected"' : '' ); } Render::addDialog(Dictionary::translateFile('config-module', 'ldapAuth_title'), false, 'ad_ldap-homedir', $data); } - public static function getAttributes() + public static function getAttributes(): array { return array('shareRemapMode', 'shareRemapCreate', 'shareDocuments', 'shareDownloads', 'shareDesktop', 'shareMedia', 'shareOther', 'shareHomeDrive', 'shareDomain', 'credentialPassthrough'); @@ -243,10 +242,11 @@ class LdapAuth_Finish extends AddModule_Base $title = Request::post('title'); if (empty($title)) $title = 'LDAP: ' . Request::post('server'); - if ($this->edit === false) + if ($this->edit === null) { $module = ConfigModule::getInstance('LdapAuth'); - else + } else { $module = $this->edit; + } $ssl = Request::post('ssl', 'off') === 'on'; foreach (['searchbase', 'binddn', 'server', 'bindpw', 'home', 'nohomewarn', 'certificate', 'genuid', 'ldapAttrMountOpts', 'shareHomeMountOpts'] as $key) { @@ -270,15 +270,16 @@ class LdapAuth_Finish extends AddModule_Base } else { $module->setData('fingerprint', ''); } - if ($this->edit !== false) + if ($this->edit !== null) { $ret = $module->update($title); - else + } else { $ret = $module->insert($title); + } if (!$ret) { Message::addError('main.value-invalid', 'any', 'any'); $tgz = false; } else { - $tgz = $module->generate($this->edit === false); + $tgz = $module->generate($this->edit === null); } if ($tgz === false) { AddModule_Base::setStep('LdapAuth_Start'); // Continues with LdapAuth_Start for render() @@ -288,9 +289,8 @@ class LdapAuth_Finish extends AddModule_Base 'tm-config' => $tgz, ); - if ($this->edit === false) { + if ($this->edit === null) { AddModule_Base::setStep('AddModule_Assign', $module->id()); - return; } } diff --git a/modules-available/sysconfig/addmodule_screensaver.inc.php b/modules-available/sysconfig/addmodule_screensaver.inc.php index 8e5c5d28..7b6d0afb 100644 --- a/modules-available/sysconfig/addmodule_screensaver.inc.php +++ b/modules-available/sysconfig/addmodule_screensaver.inc.php @@ -14,7 +14,7 @@ class Screensaver_Start extends AddModule_Base if (Request::get('back', 'false', 'string') !== 'false') /* If coming via the back button, load the session data */ $this->session_data = Session::get('data'); - elseif ($this->edit !== false) { + elseif ($this->edit !== null) { $this->session_data = array( 'title' => $this->edit->title(), 'qss' => $this->edit->getData('qss'), @@ -24,22 +24,22 @@ class Screensaver_Start extends AddModule_Base } else { $this->session_data = array( 'title' => '', - 'qss' => Dictionary::translate('saver_QssDefault', true), + 'qss' => Dictionary::translate('saver_QssDefault'), 'messages' => array( 'General' => array( - 'shutdown' => Dictionary::translate('saver_MessageDefaultShutdown', true), - 'shutdown-locked' => Dictionary::translate('saver_MessageDefaultShutdownLocked', true), - 'idle-kill' => Dictionary::translate('saver_MessageDefaultIdleKill', true), - 'idle-kill-locked' => Dictionary::translate('saver_MessageDefaultIdleKillLocked', true), - 'no-timeout' => Dictionary::translate('saver_MessageDefaultNoTimeout', true), - 'no-timeout-locked' => Dictionary::translate('saver_MessageDefaultNoTimeoutLocked', true), + 'shutdown' => Dictionary::translate('saver_MessageDefaultShutdown'), + 'shutdown-locked' => Dictionary::translate('saver_MessageDefaultShutdownLocked'), + 'idle-kill' => Dictionary::translate('saver_MessageDefaultIdleKill'), + 'idle-kill-locked' => Dictionary::translate('saver_MessageDefaultIdleKillLocked'), + 'no-timeout' => Dictionary::translate('saver_MessageDefaultNoTimeout'), + 'no-timeout-locked' => Dictionary::translate('saver_MessageDefaultNoTimeoutLocked'), ) ), 'texts' => array( - 'text-shutdown' => Dictionary::translate('saver_TextDefaultShutdown', true), + 'text-shutdown' => Dictionary::translate('saver_TextDefaultShutdown'), 'text-shutdown-locked' => '', - 'text-idle-kill' => Dictionary::translate('saver_TextDefaultIdleKill', true), - 'text-idle-kill-locked' => Dictionary::translate('saver_TextDefaultIdleKillLocked', true), + 'text-idle-kill' => Dictionary::translate('saver_TextDefaultIdleKill'), + 'text-idle-kill-locked' => Dictionary::translate('saver_TextDefaultIdleKillLocked'), 'text-no-timeout' => '', 'text-no-timeout-locked' => '', ), @@ -47,7 +47,6 @@ class Screensaver_Start extends AddModule_Base } $this->session_data['next'] = 'idle-kill'; Session::set('data', $this->session_data); - Session::save(); } protected function renderInternal() @@ -57,7 +56,7 @@ class Screensaver_Start extends AddModule_Base Render::addDialog(Dictionary::translateFile('config-module', 'screensaver_title'), false, 'screensaver-start', array( 'step' => 'Screensaver_Text', 'next' => 'idle-kill', - 'edit' => $this->edit ? $this->edit->id() : 0, + 'edit' => $this->edit !== null ? $this->edit->id() : 0, 'id' => 'start', 'title' => $this->session_data['title'], 'qss' => $this->session_data['qss'], @@ -68,24 +67,22 @@ class Screensaver_Start extends AddModule_Base class Screensaver_Text extends AddModule_Base { private $session_data; - private $id; protected function preprocessInternal() { /* Load session data */ $this->session_data = Session::get('data'); - $this->id = Request::post('id', '', 'string'); + $id = Request::post('id', '', 'string'); - if ($this->id === 'start') { + if ($id === 'start') { Screensaver_Helper::processQssData($this->session_data); - } elseif ($this->id !== '') { - Screensaver_Helper::processScreensaverText($this->session_data, $this->id); + } elseif ($id !== '') { + Screensaver_Helper::processScreensaverText($this->session_data, $id); } $next = Request::post('next', $this->session_data['next'], 'string'); $this->session_data['next'] = $next; Session::set('data', $this->session_data); - Session::save(); if ($next === 'finish') @@ -101,7 +98,7 @@ class Screensaver_Text extends AddModule_Base $next = $this->session_data['next']; $data = array( - 'edit' => $this->edit ? $this->edit->id() : 0, + 'edit' => $this->edit !== null ? $this->edit->id() : 0, ); /* Prepare and translate labels for the frontend */ @@ -117,8 +114,8 @@ class Screensaver_Text extends AddModule_Base * Dictionary::translate('saver_TitleShutdown'); * Dictionary::translate('saver_DescriptionShutdown'); */ - $data['title'] = Dictionary::translate('saver_Title' . $tag, true); - $data['description'] = Dictionary::translate('saver_Description' . $tag, true);; + $data['title'] = Dictionary::translate('saver_Title' . $tag); + $data['description'] = Dictionary::translate('saver_Description' . $tag); $data['msg_value'] = $this->session_data['messages']['General'][$next]; $data['msg_locked_value'] = $this->session_data['messages']['General'][$next . '-locked']; $data['text_value'] = $this->session_data['texts']['text-' . $next]; @@ -153,14 +150,14 @@ class Screensaver_Finish extends AddModule_Base if (empty($session_data['title'])) { Message::addError('missing-title'); Util::redirect('?do=SysConfig'); - return; } /* Only create an instance, if it's a new one */ - if ($this->edit !== false) + if ($this->edit !== null) { $module = $this->edit; - else + } else { $module = ConfigModule::getInstance('Screensaver'); + } /* Set all the data to the module instance */ $module->setData('qss', $session_data['qss']); @@ -168,15 +165,16 @@ class Screensaver_Finish extends AddModule_Base $module->setData('texts', $session_data['texts']); /* Insert or update database entries */ - if ($this->edit !== false) + if ($this->edit !== null) { $module->update($session_data['title']); - else + } else { $module->insert($session_data['title']); + } - $task = $module->generate($this->edit === false); + $task = $module->generate($this->edit === null); // Yay - if ($task !== false && $this->edit !== false) + if ($task !== false && $this->edit !== null) Message::addSuccess('module-edited'); elseif ($task !== false) { Message::addSuccess('module-added'); @@ -195,7 +193,6 @@ class Screensaver_Helper if (empty($session_data['title'])) { Message::addError('missing-title'); Util::redirect('?do=SysConfig'); - return; } $session_data['qss'] = Request::post('qss', $session_data['qss'], 'string'); $helperMode = Request::post('helper_mode', 'false', 'string'); diff --git a/modules-available/sysconfig/addmodule_sshconfig.inc.php b/modules-available/sysconfig/addmodule_sshconfig.inc.php index 4a75d77e..2447f9be 100644 --- a/modules-available/sysconfig/addmodule_sshconfig.inc.php +++ b/modules-available/sysconfig/addmodule_sshconfig.inc.php @@ -9,8 +9,8 @@ class SshConfig_Start extends AddModule_Base protected function renderInternal() { - if ($this->edit !== false) { - $data = $this->edit->getData(false) + array( + if ($this->edit !== null) { + $data = $this->edit->getData(null) + array( 'title' => $this->edit->title(), 'edit' => $this->edit->id(), 'PWD_' . strtoupper($this->edit->getData('allowPasswordLogin')) . '_selected' => 'selected', @@ -40,10 +40,11 @@ class SshConfig_Finish extends AddModule_Base return; } // Seems ok, create entry - if ($this->edit === false) + if ($this->edit === null) { $module = ConfigModule::getInstance('SshConfig'); - else + } else { $module = $this->edit; + } if ($module === false) { Message::addError('main.error-read', 'sshconfig.inc.php'); Util::redirect('?do=SysConfig&action=addmodule&step=SshConfig_Start'); @@ -59,18 +60,20 @@ class SshConfig_Finish extends AddModule_Base Util::redirect('?do=SysConfig&action=addmodule&step=SshConfig_Start'); } $module->setData('publicKey', false); - if ($this->edit !== false) + if ($this->edit !== null) { $ret = $module->update($title); - else + } else { $ret = $module->insert($title); - if (!$ret) + } + if (!$ret) { Util::redirect('?do=SysConfig&action=addmodule&step=SshConfig_Start'); - elseif (!$module->generate($this->edit === false, NULL, 200)) + } elseif (!$module->generate($this->edit === null, NULL, 200)) { Util::redirect('?do=SysConfig&action=addmodule&step=SshConfig_Start'); + } // Yay - if ($this->edit !== false) + if ($this->edit !== null) { Message::addSuccess('module-edited'); - else { + } else { Message::addSuccess('module-added'); AddModule_Base::setStep('AddModule_Assign', $module->id()); return; diff --git a/modules-available/sysconfig/addmodule_sshkey.inc.php b/modules-available/sysconfig/addmodule_sshkey.inc.php index b5ab4ad6..9f5bd1d3 100644 --- a/modules-available/sysconfig/addmodule_sshkey.inc.php +++ b/modules-available/sysconfig/addmodule_sshkey.inc.php @@ -9,8 +9,8 @@ class SshKey_Start extends AddModule_Base protected function renderInternal() { - if ($this->edit !== false) { - $data = $this->edit->getData(false) + array( + if ($this->edit !== null) { + $data = $this->edit->getData(null) + array( 'title' => $this->edit->title(), 'edit' => $this->edit->id(), ); @@ -35,7 +35,7 @@ class SshKey_Finish extends AddModule_Base return; } // Seems ok, create entry - if ($this->edit === false) { + if ($this->edit === null) { $module = ConfigModule::getInstance('SshKey'); } else { $module = $this->edit; @@ -48,18 +48,18 @@ class SshKey_Finish extends AddModule_Base Message::addError('main.value-invalid', 'pubkey', Request::post('publicKey')); Util::redirect('?do=SysConfig&action=addmodule&step=SshKey_Start'); } - if ($this->edit !== false) { + if ($this->edit !== null) { $ret = $module->update($title); } else { $ret = $module->insert($title); } if (!$ret) { Util::redirect('?do=SysConfig&action=addmodule&step=SshKey_Start'); - } elseif (!$module->generate($this->edit === false, NULL, 200)) { + } elseif (!$module->generate($this->edit === null, NULL, 200)) { Util::redirect('?do=SysConfig&action=addmodule&step=SshKey_Start'); } // Yay - if ($this->edit !== false) { + if ($this->edit !== null) { Message::addSuccess('module-edited'); } else { Message::addSuccess('module-added'); diff --git a/modules-available/sysconfig/api.inc.php b/modules-available/sysconfig/api.inc.php index 983c6dcb..e7be3029 100644 --- a/modules-available/sysconfig/api.inc.php +++ b/modules-available/sysconfig/api.inc.php @@ -11,9 +11,9 @@ if (substr($ip, 0, 7) === '::ffff:') { $ip = substr($ip, 7); } -$uuid = Request::any('uuid', false, 'string'); -if ($uuid !== false && strlen($uuid) !== 36) { - $uuid = false; +$uuid = Request::any('uuid', null, 'string'); +if ($uuid !== null && strlen($uuid) !== 36) { + $uuid = null; } // What we do if we can't supply the requested config @@ -46,7 +46,7 @@ $res = Database::simpleQuery("SELECT c.title, c.filepath, c.status, cl.locationi $best = 1000; $row = false; -while ($r = $res->fetch(PDO::FETCH_ASSOC)) { +foreach ($res as $r) { settype($r['locationid'], 'int'); $index = array_search($r['locationid'], $locationChain); if ($index === false || $index > $best) diff --git a/modules-available/sysconfig/hooks/bootup.inc.php b/modules-available/sysconfig/hooks/bootup.inc.php new file mode 100644 index 00000000..8e445dc4 --- /dev/null +++ b/modules-available/sysconfig/hooks/bootup.inc.php @@ -0,0 +1,3 @@ +<?php + +ConfigModuleBaseLdap::ldadp();
\ No newline at end of file diff --git a/modules-available/sysconfig/hooks/locations-column.inc.php b/modules-available/sysconfig/hooks/locations-column.inc.php new file mode 100644 index 00000000..8042b51c --- /dev/null +++ b/modules-available/sysconfig/hooks/locations-column.inc.php @@ -0,0 +1,57 @@ +<?php + +if (!User::hasPermission('.sysconfig.config.*') || !Module::isAvailable('sysconfig')) + return null; + +class SysconfigLocationColumn extends AbstractLocationColumn +{ + + private $lookup = []; + + public function __construct() + { + $confs = SysConfig::getAll(); + foreach ($confs as $conf) { + if (!isset($conf['locs']) || strlen($conf['locs']) === 0) + continue; + $confLocs = explode(',', $conf['locs']); + foreach ($confLocs as $locId) { + $this->lookup[$locId] = $conf['title']; + } + } + } + + public function getColumnHtml(int $locationId): string + { + return htmlspecialchars($this->lookup[$locationId] ?? ''); + } + + public function getEditUrl(int $locationId): string + { + if (!User::hasPermission('.sysconfig.config.assign', $locationId)) + return ''; + return '?do=sysconfig&locationid=' . $locationId; + } + + public function header(): string + { + return Dictionary::translateFileModule('sysconfig', 'module', 'location-column-header'); + } + + public function priority(): int + { + return 2000; + } + + public function propagateColumn(): bool + { + return true; + } + + public function propagateDefaultHtml(): string + { + return htmlspecialchars($this->lookup[0] ?? ''); + } +} + +return new SysconfigLocationColumn();
\ No newline at end of file diff --git a/modules-available/sysconfig/inc/configmodule.inc.php b/modules-available/sysconfig/inc/configmodule.inc.php index 580c15a0..729cb959 100644 --- a/modules-available/sysconfig/inc/configmodule.inc.php +++ b/modules-available/sysconfig/inc/configmodule.inc.php @@ -7,18 +7,23 @@ abstract class ConfigModule { /** - * @var array list of known module types + * @var ?array{'title': string, + * 'description': string, + * 'group': string, + * 'unique': bool, + * 'sortOrder': int, + * 'moduleClass': string, + * 'wizardClass': string}[] list of known module types */ - private static $moduleTypes = false; + private static $moduleTypes = null; private $moduleId = 0; - private $moduleArchive = false; - private $moduleTitle = false; - private $moduleStatus = false; - /** - * @var int - */ + private $moduleArchive = ''; + private $moduleTitle = ''; + private $moduleStatus = 'MISSING'; + /** @var int */ private $dateline = 0; + /** @var int */ private $currentVersion = 0; /** * @var false|array Data of module, false if not initialized @@ -33,9 +38,9 @@ abstract class ConfigModule */ public static function loadDb() { - if (self::$moduleTypes !== false) + if (self::$moduleTypes !== null) return; - self::$moduleTypes = array(); + self::$moduleTypes = []; Module::isAvailable('sysconfig'); foreach (glob(dirname(__FILE__) . '/configmodule/*.inc.php', GLOB_NOSORT) as $file) { require_once $file; @@ -44,10 +49,16 @@ abstract class ConfigModule /** * Get all known config module types. - * - * @return array list of modules + * @return array{'title': string, + * 'description': string, + * 'group': string, + * 'unique': bool, + * 'sortOrder': int, + * 'moduleClass': string, + * 'wizardClass': string}[] list of known module types + * / */ - public static function getList() + public static function getList(): array { self::loadDb(); return self::$moduleTypes; @@ -63,20 +74,20 @@ abstract class ConfigModule * @param string $description Description for this module type * @param string $group Title for group this module type belongs to * @param bool $unique Can only one such module be added to a config? - * @param int $sortOrder Lower comes first, alphabetical ordering otherwiese + * @param int $sortOrder Lower comes first, alphabetical ordering otherwise */ - public static function registerModule($id, $title, $description, $group, $unique, $sortOrder = 0) + public static function registerModule(string $id, string $title, string $description, string $group, bool $unique, int $sortOrder = 0): void { if (isset(self::$moduleTypes[$id])) { - Util::traceError("Config Module $id already registered!"); + ErrorHandler::traceError("Config Module $id already registered!"); } $moduleClass = 'ConfigModule_' . $id; $wizardClass = $id . '_Start'; if (!class_exists($moduleClass)) { - Util::traceError("Class $moduleClass does not exist!"); + ErrorHandler::traceError("Class $moduleClass does not exist!"); } if (!is_subclass_of($moduleClass, 'ConfigModule')) { - Util::traceError("$moduleClass does not have ConfigModule as its parent!"); + ErrorHandler::traceError("$moduleClass does not have ConfigModule as its parent!"); } self::$moduleTypes[$id] = array( 'title' => $title, @@ -93,21 +104,33 @@ abstract class ConfigModule * Get fresh instance of ConfigModule subclass for given module type. * * @param string $moduleType name of module type - * @return false|\ConfigModule module instance + * @return ConfigModule module instance */ - public static function getInstance($moduleType) + public static function getInstance(string $moduleType): ConfigModule + { + $ret = self::getInstanceOrNull($moduleType); + if ($ret === null) { + Message::addError('main.error-read', $moduleType . '.inc.php'); + Util::redirect('?do=sysconfig'); + } + return $ret; + } + + public static function getInstanceOrNull(string $moduleType): ?ConfigModule { self::loadDb(); if (!isset(self::$moduleTypes[$moduleType])) { error_log('Unknown module type: ' . $moduleType); - return false; + return null; } return new self::$moduleTypes[$moduleType]['moduleClass']; } - public static function instanceFromDbRow($dbRow) + private static function instanceFromDbRow(array $dbRow): ?ConfigModule { - $instance = self::getInstance($dbRow['moduletype']); + $instance = self::getInstanceOrNull($dbRow['moduletype']); + if ($instance === null) + return null; $instance->currentVersion = $dbRow['version']; $instance->moduleArchive = $dbRow['filepath']; $instance->moduleData = json_decode($dbRow['contents'], true); @@ -125,37 +148,37 @@ abstract class ConfigModule * Get module instance from id. * * @param int $moduleId module id to get - * @return false|\ConfigModule The requested module from DB, or false on error + * @return ?ConfigModule The requested module from DB, or null on error */ - public static function get($moduleId) + public static function get(int $moduleId): ?ConfigModule { $ret = Database::queryFirst("SELECT moduleid, title, moduletype, filepath, contents, version, status, dateline FROM configtgz_module " . " WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleId)); if ($ret === false) - return false; + return null; return self::instanceFromDbRow($ret); } /** * Get module instances from module type. * - * @param int $moduleType module type to get - * @return \ConfigModule[]|false The requested modules from DB, or false on error + * @param string $moduleType module type to get + * @return ?ConfigModule[] The requested modules from DB, or null on error */ - public static function getAll($moduleType = false) + public static function getAll(string $moduleType = null): ?array { - if ($moduleType === false) { + if ($moduleType === null) { $ret = Database::simpleQuery("SELECT moduleid, title, moduletype, filepath, contents, version, status, dateline FROM configtgz_module"); } else { $ret = Database::simpleQuery("SELECT moduleid, title, moduletype, filepath, contents, version, status, dateline FROM configtgz_module " . " WHERE moduletype = :moduletype", array('moduletype' => $moduleType)); } if ($ret === false) - return false; + return null; $list = array(); - while ($row = $ret->fetch(PDO::FETCH_ASSOC)) { + foreach ($ret as $row) { $instance = self::instanceFromDbRow($row); - if ($instance === false) + if ($instance === null) continue; $list[] = $instance; } @@ -167,37 +190,37 @@ abstract class ConfigModule * * @return int module version */ - protected abstract function moduleVersion(); + protected abstract function moduleVersion(): int; /** * Validate the module's configuration. * - * @return boolean ok or not + * @return bool ok or not */ - protected abstract function validateConfig(); + protected abstract function validateConfig(): bool; /** * Set module specific data. * * @param string $key key, name or id of data being set * @param mixed $value Module specific data - * @return boolean true if data was successfully set, false otherwise (i.e. invalid data being set) + * @return bool true if data was successfully set, false otherwise (i.e. invalid data being set) */ - public abstract function setData($key, $value); + public abstract function setData(string $key, $value): bool; /** * Get module specific data. * Can be overridden by modules. * - * @param string $key key, name or id of data to get, or false to get the raw moduleData array + * @param ?string $key key, name or id of data to get, or null to get the raw moduleData array * @return mixed Module specific data */ - public function getData($key) + public function getData(?string $key) { - if ($key === false) + if ($key === null) return $this->moduleData; if (!is_array($this->moduleData) || !isset($this->moduleData[$key])) - return false; + return null; return $this->moduleData[$key]; } @@ -205,25 +228,25 @@ abstract class ConfigModule * Module specific version of generate. * * @param string $tgz File name of tgz module to write final output to - * @param string $parent Parent task of this task + * @param string|null $parent Parent task of this task * @return array|boolean true if generation is completed immediately, * a task struct if some task needs to be run for generation, * false on error */ - protected abstract function generateInternal($tgz, $parent); + protected abstract function generateInternal(string $tgz, ?string $parent); - private final function createFileName() + private function createFileName(): string { return CONFIG_TGZ_LIST_DIR . '/modules/' . $this->moduleType() . '_id-' . $this->moduleId . '__' . mt_rand() . '-' . time() . '.tgz'; } - public function allowDownload() + public function allowDownload(): bool { return false; } - public function needRebuild() + public function needRebuild(): bool { return $this->moduleStatus !== 'OK' || $this->currentVersion < $this->moduleVersion(); } @@ -233,17 +256,15 @@ abstract class ConfigModule * * @return int id */ - public final function id() + public final function id(): int { return $this->moduleId; } /** * Get module title. - * - * @return string */ - public final function title() + public final function title(): string { return $this->moduleTitle; } @@ -253,17 +274,17 @@ abstract class ConfigModule * * @return string tgz file absolute path */ - public final function archive() + public final function archive(): string { return $this->moduleArchive; } - public final function status() + public final function status(): string { return $this->moduleStatus; } - public final function currentVersion() + public final function currentVersion(): int { return $this->currentVersion; } @@ -273,14 +294,13 @@ abstract class ConfigModule * * @return string module type */ - public final function moduleType() + public final function moduleType(): string { + // Yes, need to pass $this, otherwise we get ConfigModule, the base class this function is part of $name = get_class($this); - if ($name === false) - Util::traceError('ConfigModule::moduleType: get_class($this) returned false!'); // ConfigModule_* if (!preg_match('/^ConfigModule_(\w+)$/', $name, $out)) - Util::traceError('ConfigModule::moduleType: get_class($this) returned "' . $name . '"'); + ErrorHandler::traceError('ConfigModule::moduleType: get_class($this) returned "' . $name . '"'); return $out[1]; } @@ -292,10 +312,10 @@ abstract class ConfigModule * @param string $title display name of the module * @return boolean true if inserted successfully, false if module config is invalid */ - public final function insert($title) + public final function insert(string $title): bool { if ($this->moduleId !== 0) - Util::traceError('ConfigModule::insert called when moduleId != 0'); + ErrorHandler::traceError('ConfigModule::insert called when moduleId != 0'); if (!$this->validateConfig()) return false; $this->moduleTitle = $title; @@ -311,7 +331,7 @@ abstract class ConfigModule )); $this->moduleId = Database::lastInsertId(); if (!is_numeric($this->moduleId)) - Util::traceError('Inserting new config module into DB did not yield a numeric insert id'); + ErrorHandler::traceError('Inserting new config module into DB did not yield a numeric insert id'); $this->moduleArchive = $this->createFileName(); Database::exec("UPDATE configtgz_module SET filepath = :path WHERE moduleid = :moduleid LIMIT 1", array( 'path' => $this->moduleArchive, @@ -326,10 +346,10 @@ abstract class ConfigModule * * @return boolean true on success, false otherwise */ - public final function update($title = '') + public final function update(string $title = ''): bool { if ($this->moduleId === 0) - Util::traceError('ConfigModule::update called when moduleId == 0'); + ErrorHandler::traceError('ConfigModule::update called when moduleId == 0'); if (!empty($title)) { $this->moduleTitle = $title; } @@ -353,16 +373,16 @@ abstract class ConfigModule * Updating the database etc. will happen later through a callback. * * @param boolean $deleteOnError if true, the db entry will be deleted if generation failed - * @param string $parent Parent task of this task + * @param string|null $parent Parent task of this task * @param int $timeoutMs maximum time in milliseconds we wait for completion * @return string|boolean task id if deferred generation was started, * true if generation succeeded (without using a task or within $timeoutMs) * false on error */ - public final function generate($deleteOnError, $parent = NULL, $timeoutMs = 0) + public final function generate(bool $deleteOnError, string $parent = NULL, int $timeoutMs = 0) { - if ($this->moduleId === 0 || $this->moduleTitle === false) - Util::traceError('ConfigModule::generateAsync called on uninitialized/uninserted module!'); + if ($this->moduleId === 0 || empty($this->moduleTitle)) + ErrorHandler::traceError('ConfigModule::generateAsync called on uninitialized/uninserted module!'); $tmpTgz = '/tmp/bwlp-id-' . $this->moduleId . '_' . mt_rand() . '_' . time() . '.tgz'; $ret = $this->generateInternal($tmpTgz, $parent); // Wait for generation if requested @@ -395,10 +415,10 @@ abstract class ConfigModule /** * Delete the module. */ - public final function delete() + public final function delete(): void { if ($this->moduleId === 0) - Util::traceError('ConfigModule::delete called with invalid module id!'); + ErrorHandler::traceError('ConfigModule::delete called with invalid module id!'); $ret = Database::exec("DELETE FROM configtgz_module WHERE moduleid = :moduleid LIMIT 1", array( 'moduleid' => $this->moduleId ), true) !== false; @@ -410,17 +430,19 @@ abstract class ConfigModule $this->moduleTitle = false; $this->moduleArchive = false; } - return $ret; } - private final function markUpdated($tmpTgz) + /** + * @param ?string $tmpTgz new tar archive to use for this module, or null if the old one is still valid + */ + private function markUpdated(?string $tmpTgz): bool { if ($this->moduleId === 0) - Util::traceError('ConfigModule::markUpdated called with invalid module id!'); - if ($this->moduleArchive === false) + ErrorHandler::traceError('ConfigModule::markUpdated called with invalid module id!'); + if ($this->moduleArchive === null) $this->moduleArchive = $this->createFileName(); // Move file - if ($tmpTgz === false) { + if ($tmpTgz === null) { if (!file_exists($this->moduleArchive)) { EventLog::failure('ConfigModule::markUpdated for "' . $this->moduleTitle . '" called with no tmpTgz and no existing tgz!'); $this->markFailed(); @@ -460,24 +482,26 @@ abstract class ConfigModule return $retval; } - private final function markFailed() + private function markFailed(): void { if ($this->moduleId === 0) - Util::traceError('ConfigModule::markFailed called with invalid module id!'); - if ($this->moduleArchive === false) + ErrorHandler::traceError('ConfigModule::markFailed called with invalid module id!'); + if ($this->moduleArchive === '') { $this->moduleArchive = $this->createFileName(); - if (!file_exists($this->moduleArchive)) + } + if (!file_exists($this->moduleArchive)) { $status = 'MISSING'; - else + } else { $status = 'OUTDATED'; - return Database::exec("UPDATE configtgz_module SET filepath = :filename, status = :status WHERE moduleid = :id LIMIT 1", array( + } + Database::exec("UPDATE configtgz_module SET filepath = :filename, status = :status WHERE moduleid = :id LIMIT 1", array( 'id' => $this->moduleId, 'filename' => $this->moduleArchive, 'status' => $status - )) !== false; + )); } - public function dateline_s() + public function dateline_s(): string { return Util::prettyTime($this->dateline); } @@ -489,7 +513,7 @@ abstract class ConfigModule * Override this if you need to handle this, otherwise * the base implementation does nothing. */ - public function event_serverIpChanged() + public function event_serverIpChanged(): void { // Do::Nothing() } @@ -500,11 +524,10 @@ abstract class ConfigModule * Will be called if the server's IP address changes. The event will be propagated * to all config module classes so action can be taken if appropriate. */ - public static function serverIpChanged() + public static function serverIpChanged(): void { self::loadDb(); - $list = self::getAll(); - foreach ($list as $mod) { + foreach (self::getAll() ?? [] as $mod) { $mod->event_serverIpChanged(); } } @@ -513,53 +536,51 @@ abstract class ConfigModule * Called when (re)generating a config module failed, so we can * update the status in the DB and add a server log entry. * - * @param array $task - * @param array $args contains 'moduleid' and optionally 'deleteOnError' and 'tmpTgz' + * @param array $args contains 'moduleid' and optionally 'deleteOnError' */ - public static function generateFailed($task, $args) + public static function generateFailed(array $task, array $args): void { if (!isset($args['moduleid']) || !is_numeric($args['moduleid'])) { EventLog::warning('Ignoring generateFailed event as it has no moduleid assigned.'); return; } $module = self::get($args['moduleid']); - if ($module === false) { + if ($module === null) { EventLog::warning('generateFailed callback for module id ' . $args['moduleid'] . ', but no instance could be generated.'); return; } - if (isset($task['data']['error'])) + if (isset($task['data']['error'])) { $error = $task['data']['error']; - elseif (isset($task['data']['messages'])) + } elseif (isset($task['data']['messages'])) { $error = $task['data']['messages']; - else + } else { $error = ''; + } EventLog::failure("Generating module '" . $module->moduleTitle . "' failed.", $error); - if ($args['deleteOnError']) + if ($args['deleteOnError'] ?? false) { $module->delete(); - else + } else { $module->markFailed(); + } } /** * (Re)generating a config module succeeded. Update db entry. * - * @param array $args contains 'moduleid' and optionally 'deleteOnError' and 'tmpTgz' + * @param array $args contains 'moduleid' and optionally 'tmpTgz' */ - public static function generateSucceeded($args) + public static function generateSucceeded(array $args): void { if (!isset($args['moduleid']) || !is_numeric($args['moduleid'])) { EventLog::warning('Ignoring generateSucceeded event as it has no moduleid assigned.'); return; } $module = self::get($args['moduleid']); - if ($module === false) { + if ($module === null) { EventLog::warning('generateSucceeded callback for module id ' . $args['moduleid'] . ', but no instance could be generated.'); return; } - if (isset($args['tmpTgz'])) - $module->markUpdated($args['tmpTgz']); - else - $module->markUpdated(false); + $module->markUpdated($args['tmpTgz'] ?? null); } } diff --git a/modules-available/sysconfig/inc/configmodule/branding.inc.php b/modules-available/sysconfig/inc/configmodule/branding.inc.php index 8990dbec..7013e3ae 100644 --- a/modules-available/sysconfig/inc/configmodule/branding.inc.php +++ b/modules-available/sysconfig/inc/configmodule/branding.inc.php @@ -14,34 +14,34 @@ class ConfigModule_Branding extends ConfigModule const MODID = 'Branding'; const VERSION = 1; - + + /** @var false|string */ private $tmpFile = false; - protected function generateInternal($tgz, $parent) + protected function generateInternal(string $tgz, ?string $parent) { if (!$this->validateConfig()) { - return $this->archive() !== false && file_exists($this->archive()); // No new temp file given, old archive still exists, pretend it worked... + return !empty($this->archive()) && file_exists($this->archive()); // No new temp file given, old archive still exists, pretend it worked... } - $task = Taskmanager::submit('MoveFile', array( + return Taskmanager::submit('MoveFile', array( 'source' => $this->tmpFile, 'destination' => $tgz, 'parentTask' => $parent, 'failOnParentFail' => false )); - return $task; } - protected function moduleVersion() + protected function moduleVersion(): int { return self::VERSION; } - protected function validateConfig() + protected function validateConfig(): bool { return $this->tmpFile !== false && file_exists($this->tmpFile); } - public function setData($key, $value) + public function setData(string $key, $value): bool { if ($key !== 'tmpFile' || !is_string($value) || !file_exists($value)) return false; @@ -49,12 +49,12 @@ class ConfigModule_Branding extends ConfigModule return true; } - public function getData($key) + public function getData(?string $key): bool { return false; } - public function allowDownload() + public function allowDownload(): bool { return true; } diff --git a/modules-available/sysconfig/inc/configmodule/customodule.inc.php b/modules-available/sysconfig/inc/configmodule/customodule.inc.php index 8b968336..0b8e38d2 100644 --- a/modules-available/sysconfig/inc/configmodule/customodule.inc.php +++ b/modules-available/sysconfig/inc/configmodule/customodule.inc.php @@ -13,15 +13,16 @@ class ConfigModule_CustomModule extends ConfigModule { const MODID = 'CustomModule'; const VERSION = 2; - + + /** @var false|string */ private $tmpFile = false; - protected function generateInternal($tgz, $parent) + protected function generateInternal(string $tgz, ?string $parent) { if (!$this->validateConfig()) { // No temp file given from wizard // Old archive still exists? pretend it worked... - if ($this->archive() === false || !file_exists($this->archive())) + if ($this->archive() === '' || !file_exists($this->archive())) return false; if ($this->currentVersion() == 1) { // Need an upgrade @@ -34,26 +35,25 @@ class ConfigModule_CustomModule extends ConfigModule // Nothing to do return true; } - $task = Taskmanager::submit('MoveFile', array( + return Taskmanager::submit('MoveFile', array( 'source' => $this->tmpFile, 'destination' => $tgz, 'parentTask' => $parent, 'failOnParentFail' => false )); - return $task; } - protected function moduleVersion() + protected function moduleVersion(): int { return self::VERSION; } - protected function validateConfig() + protected function validateConfig(): bool { return $this->tmpFile !== false && file_exists($this->tmpFile); } - public function setData($key, $value) + public function setData(string $key, $value): bool { // Sets the temp file from the wizard, where it stored the processed archive if ($key !== 'tmpFile' || !file_exists($value)) @@ -62,12 +62,12 @@ class ConfigModule_CustomModule extends ConfigModule return true; } - public function getData($key) + public function getData(?string $key): bool { return false; } - public function allowDownload() + public function allowDownload(): bool { return true; } diff --git a/modules-available/sysconfig/inc/configmodule/ldapauth.inc.php b/modules-available/sysconfig/inc/configmodule/ldapauth.inc.php index 7af4671e..64af4c0e 100644 --- a/modules-available/sysconfig/inc/configmodule/ldapauth.inc.php +++ b/modules-available/sysconfig/inc/configmodule/ldapauth.inc.php @@ -5,7 +5,7 @@ class ConfigModule_LdapAuth extends ConfigModuleBaseLdap const MODID = 'LdapAuth'; - protected function preTaskmanagerHook(&$config) + protected function preTaskmanagerHook(array &$config) { // Just set the flag so the taskmanager job knows we're dealing with a normal ldap server, // not AD scheme diff --git a/modules-available/sysconfig/inc/configmodule/screensaver.inc.php b/modules-available/sysconfig/inc/configmodule/screensaver.inc.php index ed97941e..1797331c 100644 --- a/modules-available/sysconfig/inc/configmodule/screensaver.inc.php +++ b/modules-available/sysconfig/inc/configmodule/screensaver.inc.php @@ -14,7 +14,7 @@ class ConfigModule_Screensaver extends ConfigModule const MODID = 'Screensaver'; const VERSION = 1; - protected function generateInternal($tgz, $parent) + protected function generateInternal(string $tgz, ?string $parent) { /* Validate if all data are available */ if (!$this->validateConfig()) @@ -23,30 +23,27 @@ class ConfigModule_Screensaver extends ConfigModule /* Give the Taskmanager the job and create the tgz */ $taskId = 'xscreensaver' . mt_rand() . '-' . microtime(true); - $task = Taskmanager::submit('MakeTarball', array( + return Taskmanager::submit('MakeTarball', array( 'id' => $taskId, 'files' => $this->getFileArray(), 'destination' => $tgz, ), false); - - return $task; } - protected function moduleVersion() + protected function moduleVersion(): int { return self::VERSION; } - protected function validateConfig() + protected function validateConfig(): bool { - return isset($this->moduleData['qss']) && - isset($this->moduleData['texts']) && - isset($this->moduleData['texts']['text-idle-kill']) && - isset($this->moduleData['texts']['text-no-timeout']) && - isset($this->moduleData['texts']['text-shutdown']); + return isset($this->moduleData['texts']['text-no-timeout']) + && isset($this->moduleData['texts']['text-idle-kill']) + && isset($this->moduleData['texts']['text-shutdown']) + && isset($this->moduleData['qss']); } - public function setData($key, $value) + public function setData(string $key, $value): bool { switch ($key) { case 'qss': @@ -60,17 +57,15 @@ class ConfigModule_Screensaver extends ConfigModule return true; } - public function allowDownload() + public function allowDownload(): bool { return false; } /** * Creates a map with filepath => file content - * - * @return array in the form of Map<String, byte[]> */ - private function getFileArray() + private function getFileArray(): array { $files = array( '/opt/openslx/xscreensaver/style.qss' => $this->moduleData['qss'], @@ -100,7 +95,7 @@ class ConfigModule_Screensaver extends ConfigModule return $files; } - private function wrapHtmlTags($text_name) + private function wrapHtmlTags(string $text_name): string { return '<html><body>' . $this->moduleData['texts'][$text_name] . '</body></html>'; } diff --git a/modules-available/sysconfig/inc/configmodule/sshconfig.inc.php b/modules-available/sysconfig/inc/configmodule/sshconfig.inc.php index b5ab20e4..a62d1035 100644 --- a/modules-available/sysconfig/inc/configmodule/sshconfig.inc.php +++ b/modules-available/sysconfig/inc/configmodule/sshconfig.inc.php @@ -14,7 +14,7 @@ class ConfigModule_SshConfig extends ConfigModule const MODID = 'SshConfig'; const VERSION = 1; - protected function generateInternal($tgz, $parent) + protected function generateInternal(string $tgz, ?string $parent) { if (!$this->validateConfig()) return false; @@ -26,12 +26,12 @@ class ConfigModule_SshConfig extends ConfigModule return Taskmanager::submit('SshdConfigGenerator', $config); } - protected function moduleVersion() + protected function moduleVersion(): int { return self::VERSION; } - protected function validateConfig() + protected function validateConfig(): bool { // UPGRADE if (isset($this->moduleData['allowPasswordLogin']) && !isset($this->moduleData['allowedUsersLogin'])) { @@ -45,7 +45,7 @@ class ConfigModule_SshConfig extends ConfigModule && isset($this->moduleData['listenPort']); } - public function setData($key, $value) + public function setData(string $key, $value): bool { switch ($key) { case 'publicKey': diff --git a/modules-available/sysconfig/inc/configmodule/sshkey.inc.php b/modules-available/sysconfig/inc/configmodule/sshkey.inc.php index 2d212d25..e4a55ad7 100644 --- a/modules-available/sysconfig/inc/configmodule/sshkey.inc.php +++ b/modules-available/sysconfig/inc/configmodule/sshkey.inc.php @@ -14,7 +14,7 @@ class ConfigModule_SshKey extends ConfigModule const MODID = 'SshKey'; const VERSION = 1; - protected function generateInternal($tgz, $parent) + protected function generateInternal(string $tgz, ?string $parent) { if (!$this->validateConfig()) return false; @@ -30,17 +30,17 @@ class ConfigModule_SshKey extends ConfigModule return Taskmanager::submit('MakeTarball', $config); } - protected function moduleVersion() + protected function moduleVersion(): int { return self::VERSION; } - protected function validateConfig() + protected function validateConfig(): bool { return isset($this->moduleData['publicKey']); } - public function setData($key, $value) + public function setData(string $key, $value): bool { switch ($key) { case 'publicKey': diff --git a/modules-available/sysconfig/inc/configmodulebaseldap.inc.php b/modules-available/sysconfig/inc/configmodulebaseldap.inc.php index b6498aed..770a40e6 100644 --- a/modules-available/sysconfig/inc/configmodulebaseldap.inc.php +++ b/modules-available/sysconfig/inc/configmodulebaseldap.inc.php @@ -11,7 +11,7 @@ abstract class ConfigModuleBaseLdap extends ConfigModule 'shareOther', 'shareHomeDrive', 'shareDomain', 'credentialPassthrough', 'mapping', 'genuid', 'ldapAttrMountOpts', 'shareHomeMountOpts', 'nohomewarn'); - public static function getMapping($config = false, &$empty = true) + public static function getMapping(array $config = null, ?bool &$empty = true): array { $list = array( ['name' => 'uid', 'field' => 'uid', 'ad' => 'sAMAccountName'], @@ -46,10 +46,10 @@ abstract class ConfigModuleBaseLdap extends ConfigModule * * @param string $command start, restart, check * @param bool|int|int[] $ids list of IDs to run command on, or false meaning "all" - * @param string $parent if not NULL, this will be the parent task of the launch-task + * @param string|null $parent if not NULL, this will be the parent task of the launch-task * @return boolean|string false on error, id of task otherwise */ - public static function ldadp($command = 'start', $ids = false, $parent = null) + public static function ldadp(string $command = 'start', $ids = false, string $parent = null) { if ($ids === false) { $ids = self::getActiveModuleIds(); @@ -67,7 +67,7 @@ abstract class ConfigModuleBaseLdap extends ConfigModule return $task['id']; } - protected function generateInternal($tgz, $parent) + protected function generateInternal(string $tgz, ?string $parent) { $config = $this->moduleData; if (isset($config['certificate']) && !is_string($config['certificate'])) { @@ -96,8 +96,8 @@ abstract class ConfigModuleBaseLdap extends ConfigModule $config['shareHomeDrive'] = 'H:'; } // This is now always on, as we mask it transparently in our lightdm greeter - $config['fixnumeric'] = 'yes'; - $config['genuid'] = isset($config['genuid']) && !empty($config['genuid']); + $config['fixnumeric'] = 'true'; + $config['genuid'] = !empty($config['genuid']); $config['nohomewarn'] = isset($config['nohomewarn']) ? (int)$config['nohomewarn'] : 0; $this->preTaskmanagerHook($config); $task = Taskmanager::submit('CreateLdapConfig', $config); @@ -111,25 +111,23 @@ abstract class ConfigModuleBaseLdap extends ConfigModule * Hook called before running CreateLdapConfig task with the * configuration to be passed to the task. Passed by reference * so it can be modified. - * - * @param array $config */ - protected function preTaskmanagerHook(&$config) + protected function preTaskmanagerHook(array &$config) { } - protected function moduleVersion() + protected function moduleVersion(): int { return self::VERSION; } - protected function validateConfig() + protected function validateConfig(): bool { // Check if required fields are filled - return Util::hasAllKeys($this->moduleData, self::$REQUIRED_FIELDS); + return ArrayUtil::hasAllKeys($this->moduleData, self::$REQUIRED_FIELDS); } - public function setData($key, $value) + public function setData(string $key, $value): bool { if (!in_array($key, self::$REQUIRED_FIELDS) && !in_array($key, self::$OPTIONAL_FIELDS)) return false; @@ -142,7 +140,7 @@ abstract class ConfigModuleBaseLdap extends ConfigModule /** * Server IP changed - rebuild all AD modules. */ - public function event_serverIpChanged() + public function event_serverIpChanged(): void { $this->generate(false); } diff --git a/modules-available/sysconfig/inc/configtgz.inc.php b/modules-available/sysconfig/inc/configtgz.inc.php index 98f29753..8ac87908 100644 --- a/modules-available/sysconfig/inc/configtgz.inc.php +++ b/modules-available/sysconfig/inc/configtgz.inc.php @@ -4,29 +4,28 @@ class ConfigTgz { private $configId = 0; - private $configTitle = false; - private $file = false; + private $configTitle = ''; + private $file = ''; private $modules = array(); private function __construct() { - ; } - public function id() + public function id(): int { return $this->configId; } - public function title() + public function title(): string { return $this->configTitle; } - public function areAllModulesUpToDate() + public function areAllModulesUpToDate(): bool { if (!$this->configId > 0) - Util::traceError('ConfigTgz::areAllModulesUpToDate called on un-inserted config.tgz!'); + ErrorHandler::traceError('ConfigTgz::areAllModulesUpToDate called on un-inserted config.tgz!'); foreach ($this->modules as $module) { if (!empty($module['filepath']) && file_exists($module['filepath'])) { if ($module['status'] !== 'OK') @@ -38,24 +37,29 @@ class ConfigTgz return true; } - public function isActive() + public function isActive(): bool { return readlink(CONFIG_HTTP_DIR . '/default/config.tgz') === $this->file; } - - public function getModuleIds() + + /** + * @return int[] + */ + public function getModuleIds(): array { - $ret = array(); + $ret = []; foreach ($this->modules as $module) { - $ret[] = $module['moduleid']; + $ret[] = (int)$module['moduleid']; } return $ret; } - - public function update($title, $moduleIds) + + /** + * @param string $title New title for module + * @param int[] $moduleIds List of modules to include in this config + */ + public function update(string $title, array $moduleIds): void { - if (!is_array($moduleIds)) - return false; if (!empty($title)) { $this->configTitle = $title; } @@ -69,7 +73,7 @@ class ConfigTgz // Delete old connections Database::exec("DELETE FROM configtgz_x_module WHERE configid = :configid", array('configid' => $this->configId)); // Make connection - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { Database::exec("INSERT INTO configtgz_x_module (configid, moduleid) VALUES (:configid, :moduleid)", array( 'configid' => $this->configId, 'moduleid' => $row['moduleid'] @@ -83,20 +87,19 @@ class ConfigTgz 'status' => 'OUTDATED', 'now' => time(), )); - return true; } /** * - * @param bool $deleteOnError - * @param int $timeoutMs - * @param string|null $parentTask parent task to order this rebuild after + * @param bool $deleteOnError Delete this config in case of error? + * @param int $timeoutMs max time to wait for completion + * @param string|null $parentTask parent task to order this (re)build after * @return string|bool true=success, false=error, string=taskid, still running */ - public function generate($deleteOnError = false, $timeoutMs = 0, $parentTask = null) + public function generate(bool $deleteOnError = false, int $timeoutMs = 0, ?string $parentTask = null) { - if (!($this->configId > 0) || !is_array($this->modules) || $this->file === false) - Util::traceError ('configId <= 0 or modules not array in ConfigTgz::rebuild()'); + if (!($this->configId > 0) || empty($this->file)) + ErrorHandler::traceError('configId <= 0 or no file in ConfigTgz::rebuild()'); $files = array(); // Get all config modules for system config foreach ($this->modules as $module) { @@ -134,33 +137,34 @@ class ConfigTgz return $task['id']; } - public function delete() + public function delete(): bool { if ($this->configId === 0) - Util::traceError('ConfigTgz::delete called with invalid config id!'); + ErrorHandler::traceError('ConfigTgz::delete called with invalid config id!'); $ret = Database::exec("DELETE FROM configtgz WHERE configid = :configid LIMIT 1", ['configid' => $this->configId], true); if ($ret !== false) { - if ($this->file !== false) + if (!empty($this->file)) { Taskmanager::submit('DeleteFile', array('file' => $this->file), true); + } $this->configId = 0; - $this->modules = false; - $this->file = false; + $this->modules = []; + $this->file = ''; } return $ret !== false; } - public function markOutdated() + public function markOutdated(): void { if ($this->configId === 0) - Util::traceError('ConfigTgz::markOutdated called with invalid config id!'); - return $this->mark('OUTDATED'); + ErrorHandler::traceError('ConfigTgz::markOutdated called with invalid config id!'); + $this->mark('OUTDATED'); } - private function markUpdated($task) + private function markUpdated(array $task): void { if ($this->configId === 0) - Util::traceError('ConfigTgz::markUpdated called with invalid config id!'); + ErrorHandler::traceError('ConfigTgz::markUpdated called with invalid config id!'); if ($this->areAllModulesUpToDate()) { if (empty($task['data']['warnings'])) { $warnings = ''; @@ -170,7 +174,7 @@ class ConfigTgz // Get mapping of moduleid to module name for prettier log display $res = Database::simpleQuery('SELECT moduleid, title FROM configtgz_module'); $mods = []; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { $mods[$row['moduleid']] = $row['title']; } // Now extract module id from filename and if applicable, replace filename by module name @@ -186,27 +190,28 @@ class ConfigTgz 'status' => 'OK', 'warnings' => $warnings, ]); - return 'OK'; + return; } - return $this->mark('OUTDATED'); + $this->mark('OUTDATED'); } - private function markFailed() + private function markFailed(): void { if ($this->configId === 0) - Util::traceError('ConfigTgz::markFailed called with invalid config id!'); - if ($this->file === false || !file_exists($this->file)) - return $this->mark('MISSING'); - return $this->mark('OUTDATED'); + ErrorHandler::traceError('ConfigTgz::markFailed called with invalid config id!'); + if (empty($this->file) || !file_exists($this->file)) { + $this->mark('MISSING'); + } else { + $this->mark('OUTDATED'); + } } - private function mark($status) + private function mark($status): void { Database::exec("UPDATE configtgz SET status = :status WHERE configid = :configid LIMIT 1", [ 'configid' => $this->configId, 'status' => $status, ]); - return $status; } /* @@ -218,12 +223,12 @@ class ConfigTgz * @param string $destFile where to store final result * @return false|array taskmanager task */ - private static function recompress($files, $destFile, $parentTask = null) + private static function recompress(array $files, string $destFile, $parentTask = null) { // Get stuff other modules want to inject $handler = function($hook) { include $hook->file; - return isset($file) ? $file : false; + return $file ?? false; }; foreach (Hook::load('config-tgz') as $hook) { $file = $handler($hook); @@ -246,15 +251,15 @@ class ConfigTgz * on each one. This mostly makes sense to call if a global module * that is injected via a hook has changed. */ - public static function rebuildAllConfigs() + public static function rebuildAllConfigs(): void { Database::exec("UPDATE configtgz SET status = :status", array( 'status' => 'OUTDATED' )); $res = Database::simpleQuery("SELECT configid FROM configtgz"); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { $configTgz = self::get($row['configid']); - if ($configTgz !== false) { + if ($configTgz !== null) { $configTgz->generate(); } } @@ -263,12 +268,10 @@ class ConfigTgz /** * @param string $title Title of config * @param int[] $moduleIds Modules to include in config - * @return false|ConfigTgz The module instance, false on error + * @return ConfigTgz The module instance */ - public static function insert($title, $moduleIds) + public static function insert(string $title, array $moduleIds): ConfigTgz { - if (!is_array($moduleIds)) - return false; $instance = new ConfigTgz; $instance->configTitle = $title; // Create output file name (config.tgz) @@ -290,7 +293,7 @@ class ConfigTgz } $res = Database::simpleQuery("SELECT moduleid, moduletype, filepath, status FROM configtgz_module WHERE moduleid IN ($idstr)"); // Make connection - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { Database::exec("INSERT INTO configtgz_x_module (configid, moduleid) VALUES (:configid, :moduleid)", array( 'configid' => $instance->configId, 'moduleid' => $row['moduleid'] @@ -300,53 +303,53 @@ class ConfigTgz return $instance; } - public static function get($configId) + /** + * @param array{configid: int, title: string, filepath: string} $row Input data, fields mandatory + */ + private static function instanceFromRow(array $row): ConfigTgz { - $ret = Database::queryFirst("SELECT configid, title, filepath FROM configtgz WHERE configid = :configid", array( - 'configid' => $configId - )); - if ($ret === false) - return false; $instance = new ConfigTgz; - $instance->configId = $ret['configid']; - $instance->configTitle = $ret['title']; - $instance->file = $ret['filepath']; - $ret = Database::simpleQuery("SELECT moduleid, moduletype, filepath, status FROM configtgz_x_module " + $instance->configId = $row['configid']; + $instance->configTitle = $row['title']; + $instance->file = $row['filepath']; + $innerRes = Database::simpleQuery("SELECT moduleid, moduletype, filepath, status FROM configtgz_x_module " . " INNER JOIN configtgz_module USING (moduleid) " . " WHERE configid = :configid", array('configid' => $instance->configId)); $instance->modules = array(); - while ($row = $ret->fetch(PDO::FETCH_ASSOC)) { - $instance->modules[] = $row; + foreach ($innerRes as $innerRow) { + $instance->modules[] = $innerRow; } return $instance; } + public static function get(int $configId): ?ConfigTgz + { + $ret = Database::queryFirst("SELECT configid, title, filepath FROM configtgz WHERE configid = :configid", array( + 'configid' => $configId + )); + if ($ret === false) + return null; + return self::instanceFromRow($ret); + } + /** * @param int $moduleId ID of config module - * @return ConfigTgz[]|false + * @return ConfigTgz[] */ - public static function getAllForModule($moduleId) + public static function getAllForModule(int $moduleId): array { $res = Database::simpleQuery("SELECT configid, title, filepath FROM configtgz_x_module " . " INNER JOIN configtgz USING (configid) " . " WHERE moduleid = :moduleid", array( 'moduleid' => $moduleId )); - if ($res === false) - return false; + if ($res === false) { + EventLog::warning('ConfigTgz::getAllForModule failed: ' . Database::lastError()); + return []; + } $list = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { - $instance = new ConfigTgz; - $instance->configId = $row['configid']; - $instance->configTitle = $row['title']; - $instance->file = $row['filepath']; - $innerRes = Database::simpleQuery("SELECT moduleid, moduletype, filepath, status FROM configtgz_x_module " - . " INNER JOIN configtgz_module USING (moduleid) " - . " WHERE configid = :configid", array('configid' => $instance->configId)); - $instance->modules = array(); - while ($innerRow = $innerRes->fetch(PDO::FETCH_ASSOC)) { - $instance->modules[] = $innerRow; - } + foreach ($res as $row) { + $instance = self::instanceFromRow($row); $list[] = $instance; } return $list; @@ -356,31 +359,32 @@ class ConfigTgz * Called when (re)generating a config tgz failed, so we can * update the status in the DB and add a server log entry. * - * @param array $task * @param array $args contains 'configid' and optionally 'deleteOnError' */ - public static function generateFailed($task, $args) + public static function generateFailed(array $task, array $args): void { if (!isset($args['configid']) || !is_numeric($args['configid'])) { EventLog::warning('Ignoring generateFailed event as it has no configid assigned.'); return; } $config = self::get($args['configid']); - if ($config === false) { + if ($config === null) { EventLog::warning('generateFailed callback for config id ' . $args['configid'] . ', but no instance could be generated.'); return; } - if (isset($task['data']['error'])) + if (isset($task['data']['error'])) { $error = $task['data']['error']; - elseif (isset($task['data']['messages'])) + } elseif (isset($task['data']['messages'])) { $error = $task['data']['messages']; - else + } else { $error = ''; + } EventLog::failure("Generating config.tgz '" . $config->configTitle . "' failed.", $error); - if ($args['deleteOnError']) + if ($args['deleteOnError']) { $config->delete(); - else + } else { $config->markFailed(); + } } /** @@ -389,14 +393,14 @@ class ConfigTgz * @param array $task the task object * @param array $args contains 'configid' and optionally 'deleteOnError' */ - public static function generateSucceeded($task, $args) + public static function generateSucceeded(array $task, array $args): void { if (!isset($args['configid']) || !is_numeric($args['configid'])) { EventLog::warning('Ignoring generateSucceeded event as it has no configid assigned.'); return; } $config = self::get($args['configid']); - if ($config === false) { + if ($config === null) { EventLog::warning('generateSucceeded callback for config id ' . $args['configid'] . ', but no instance could be generated.'); return; } diff --git a/modules-available/sysconfig/inc/ldap.inc.php b/modules-available/sysconfig/inc/ldap.inc.php index 349a662e..e974a8a3 100644 --- a/modules-available/sysconfig/inc/ldap.inc.php +++ b/modules-available/sysconfig/inc/ldap.inc.php @@ -3,7 +3,7 @@ class Ldap { - public static function normalizeDn($dn) + public static function normalizeDn(string $dn): string { return trim(preg_replace('/[,;]\s*/', ',', $dn)); } diff --git a/modules-available/sysconfig/inc/ppd.inc.php b/modules-available/sysconfig/inc/ppd.inc.php index 9bd5d171..c28e0355 100644 --- a/modules-available/sysconfig/inc/ppd.inc.php +++ b/modules-available/sysconfig/inc/ppd.inc.php @@ -247,8 +247,8 @@ class Ppd private $data; private $dataLen; - private $error; - private $warnings; + private $error = null; + private $warnings = []; private $knownKeywordMalformed; @@ -301,16 +301,16 @@ class Ppd $this->dataLen = strlen($this->data); $this->encoder = false; $this->sourceEncoding = false; - $this->error = false; + $this->error = null; $this->warnings = array(); $this->knownKeywordMalformed = false; $this->settings = array(); $this->requiredKeywords = array(); // Parse - /* @var $rawOption \PpdOption */ - /* @var $currentBlock \PpdBlockInternal */ - $currentBlock = false; + /* @var PpdOption $rawOption */ + /* @var ?PpdBlockInternal $currentBlock */ + $currentBlock = null; $inRawBlock = false; // True if in a multi-line InvocationValue or QuotedValue (3.6: Parsing Summary for Values) $wantsEnd = false; // For now we ignore values mostly while parsing. The spec says that InvocationValues must only contain printable @@ -318,9 +318,9 @@ class Ppd $lStart = -1; $lEnd = -1; $no = 0; - while ($lStart < $this->dataLen && $lEnd !== false) { + while ($lStart < $this->dataLen) { unset($mainKeyword, $optionKeyword, $optionTranslation, $option, $value, $valueTranslation); - if ($no !== 0 && $this->data{$lEnd} === "\r" && $this->data{$lEnd + 1} === "\n") { + if ($no !== 0 && $this->data[$lEnd] === "\r" && $this->data[$lEnd + 1] === "\n") { $lEnd++; } if ($no === 1) { @@ -332,6 +332,8 @@ class Ppd } $lStart = $lEnd + 1; $lEnd = $this->nextLineEnd($lStart); + if ($lEnd === null) + break; $no++; // Validate $len = $lEnd - $lStart; @@ -343,7 +345,7 @@ class Ppd $this->warn($no, 'Exceeds length of 255'); } if (!$inRawBlock && preg_match_all('/[^\x09\x0A\x0D\x20-\xFF]/', $line, $out)) { - $chars = $this->escapeBinaryArray($out[0]); + $chars = self::escapeBinaryArray($out[0]); $this->warn($no, 'Contains invalid character(s) ' . $chars); } // Handle @@ -373,13 +375,13 @@ class Ppd } } // 3) Handle "key [option]: value" - if ($line{0} === '*') { - if ($line{1} === '%') { + if ($line[0] === '*') { + if ($line[1] === '%') { // Skip comment continue; } $parts = preg_split('/\s*:\s*/', $line, 2); // TODO: UIConstrains - if (count($parts) !== 2) { + if (!is_array($parts) || count($parts) !== 2) { $this->warn($no, 'No colon found; not in "key [option]: value" format, ignoring line'); continue; } @@ -390,11 +392,12 @@ class Ppd continue; } $mainKeyword = $out[1]; - $optionKeyword = isset($out[3]) ? $out[3] : false; + $optionKeyword = $out[3] ?? null; $optionTranslation = isset($out[4]) ? $this->unhexTranslation($no, substr($out[4], 1)) : $optionKeyword; // If no translation given, fallback to option // 3b) Handle value + /** @var string $value */ $value = $parts[1]; - if ($value{0} === '"') { + if ($value[0] === '"') { // Start of InvocationValue or QuotedValue if (preg_match(',^"([^"]*)"(/.*)?$,', $value, $vMatch)) { // Single line @@ -419,28 +422,23 @@ class Ppd // Key-value-pair parsed, now the fun part // Special cases for opening closing certain groups if ($mainKeyword === 'OpenGroup') { - if ($currentBlock !== false) { + if ($currentBlock !== null) { $this->error = 'Line ' . $no . ': OpenGroup while other block (type=' . $currentBlock->type . ', id=' . $currentBlock->id . ') was not closed yet'; return; } // TODO: Check unique - $nb = new PpdBlockInternal($value, $valueTranslation, 'Group', $currentBlock, $lStart); - if ($currentBlock !== false) { - $currentBlock->childBlocks[] = $nb; - } + $nb = new PpdBlockInternal($value, $valueTranslation, 'Group', null, $lStart); $currentBlock = $nb; continue; } elseif ($mainKeyword === 'OpenSubGroup') { - if ($currentBlock === false || $currentBlock->type !== 'Group') { + if ($currentBlock === null || $currentBlock->type !== 'Group') { $this->error = 'Line ' . $no . ': OpenSubGroup with no preceding OpenGroup'; return; } // TODO: Check unique $nb = new PpdBlockInternal($value, $valueTranslation, 'SubGroup', $currentBlock, $lStart); - if ($currentBlock !== false) { - $currentBlock->childBlocks[] = $nb; - } + $currentBlock->childBlocks[] = $nb; $currentBlock = $nb; continue; } elseif ($mainKeyword === 'OpenUI' || $mainKeyword === 'JCLOpenUI') { @@ -450,23 +448,24 @@ class Ppd } else { $type = substr($type, 4); } - if ($currentBlock !== false && $currentBlock->isUi()) { + if ($currentBlock !== null && $currentBlock->isUi()) { $this->error = 'Line ' . $no . ': ' . $mainKeyword . ' while previous ' . $type . ' "' . $currentBlock->id . '" was not closed yet'; return; } - if ($optionKeyword === false) { + if ($optionKeyword === null) { $this->error = 'Line ' . $no . ': ' . $mainKeyword . ' with no option keyword'; return; } - if ($optionKeyword{0} !== '*') { + if ($optionKeyword[0] !== '*') { $this->error = 'Line ' . $no . ': ' . $mainKeyword . " with option keyword that doesn't start with asterisk (*)."; return; } // TODO: Check unique - $nb = new PpdBlockInternal($optionKeyword, $optionTranslation, $type, $currentBlock, $lStart); + $nb = new PpdBlockInternal($optionKeyword, $optionTranslation ?? $optionKeyword, + $type, $currentBlock, $lStart); $nb->value = $value; - if ($currentBlock !== false) { + if ($currentBlock !== null) { $currentBlock->childBlocks[] = $nb; } $currentBlock = $nb; @@ -481,7 +480,7 @@ class Ppd } else { $type = substr($type, 5); } - if ($currentBlock === false) { + if ($currentBlock === null) { $this->error = 'Line ' . $no . ': ' . $mainKeyword . ' with no Open' . $type; return; } @@ -498,7 +497,7 @@ class Ppd $currentBlock = $currentBlock->parent; continue; } elseif ($mainKeyword === 'OrderDependency') { - if ($currentBlock === false || $currentBlock->isUi()) { + if ($currentBlock === null || $currentBlock->isUi()) { $this->warn($no, 'OrderDependency outside OpenUI/CloseUI block'); } continue; @@ -521,9 +520,10 @@ class Ppd $this->warn($no, 'Required keyword ' . $mainKeyword . ' declared twice, ignoring'); continue; } + } else { + $this->requiredKeywords[$mainKeyword] = array($value); } - $this->requiredKeywords[$mainKeyword] = array($value); - if (($err = $this->validateLine($this->REQUIRED_KEYWORDS[$mainKeyword], $optionKeyword, $value)) !== true) { + if (($err = Ppd::validateLine($this->REQUIRED_KEYWORDS[$mainKeyword], $optionKeyword, $value)) !== true) { $this->warn($no, 'Required main keyword ' . $mainKeyword . ': ' . $err); $this->knownKeywordMalformed = true; } @@ -531,7 +531,7 @@ class Ppd } // Other well known keywords if (isset($this->KNOWN_KEYWORDS[$mainKeyword])) { - if (($err = $this->validateLine($this->KNOWN_KEYWORDS[$mainKeyword], $optionKeyword, $value)) !== true) { + if (($err = Ppd::validateLine($this->KNOWN_KEYWORDS[$mainKeyword], $optionKeyword, $value)) !== true) { $this->warn($no, 'Known main keyword ' . $mainKeyword . ': ' . $err); $this->knownKeywordMalformed = true; } @@ -541,17 +541,18 @@ class Ppd $option = $this->getOption(substr($mainKeyword, 7), $currentBlock); $option->default = new PpdOption($lStart, $len, $value, $valueTranslation); continue; - } elseif (substr($mainKeyword, 0, 17) === 'FoomaticRIPOption') { - if ($optionKeyword === false) { + } + if (substr($mainKeyword, 0, 17) === 'FoomaticRIPOption') { + if ($optionKeyword === null) { $this->warn($no, "$mainKeyword with no option keyword"); - } elseif ($currentBlock !== false && isset($this->settings[$optionKeyword])) { + } elseif ($currentBlock !== null && isset($this->settings[$optionKeyword])) { $option = $this->getOption($optionKeyword, $currentBlock); $option->foomatic[substr($mainKeyword, 11)] = new PpdOption($lStart, $len, $value, $valueTranslation); } else { $this->warn($no, 'TODO: ' . $line); } } elseif (substr($mainKeyword, 0, 6) === 'Custom') { - if ($optionKeyword === false) { + if ($optionKeyword === null) { $this->warn($no, "$mainKeyword with no option keyword"); } elseif ($optionKeyword !== 'True') { $this->warn($no, "$mainKeyword with option keyword other than 'True'; ignored"); @@ -560,7 +561,7 @@ class Ppd $option->custom = new PpdOption($lStart, $len, $value, $valueTranslation); } } elseif (substr($mainKeyword, 0, 11) === 'ParamCustom') { - if ($optionKeyword === false) { + if ($optionKeyword === null) { $this->warn($no, "$mainKeyword with no option keyword"); } elseif (substr($mainKeyword, 11) !== $optionKeyword) { $this->warn($no, "Don't know how to handle $mainKeyword with option keyword $optionKeyword " @@ -569,20 +570,20 @@ class Ppd $option = $this->getOption($optionKeyword, $currentBlock); $option->customParam = new PpdOption($lStart, $len, $value, $valueTranslation); } - } elseif ($mainKeyword{0} === '?') { + } elseif ($mainKeyword[0] === '?') { // Ignoring option query for now - } elseif ($optionKeyword === false && !isset($this->KNOWN_KEYWORDS[$mainKeyword])) { + } elseif ($optionKeyword === null && !isset($this->KNOWN_KEYWORDS[$mainKeyword])) { // Must be a definition for an option $this->warn($no, "Don't know how to handle line with main keyword '$mainKeyword', no option keyword found."); } else { // Some option for some option ;) - if ($optionKeyword === false) { + if ($optionKeyword === null) { // We know that this is a known main keyword otherwise we would have hit the previous elseif block $optionKeyword = $value; $optionTranslation = $valueTranslation; } $option = $this->getOption($mainKeyword, $currentBlock); - $optionInstance = new PpdOption($lStart, $len, $optionKeyword, $optionTranslation); + $optionInstance = new PpdOption($lStart, $len, $optionKeyword, $optionTranslation ?? $optionKeyword); if ($this->binary_in_array($mainKeyword, $this->REPEATED_KEYWORDS)) { // This can occur multiple times, just pile them up $option->values[] = $optionInstance; @@ -603,9 +604,9 @@ class Ppd } elseif (strlen(trim($line)) !== 0) { $this->warn($no, 'Invalid format; not empty and not starting with asterisk (*)'); } - } + } // end while loop over ppd contents // - if ($currentBlock !== false) { + if ($currentBlock !== null) { $this->error = 'Block ' . $currentBlock->id . ' (' . $currentBlock->type . ') was never closed.'; return; } @@ -615,11 +616,11 @@ class Ppd $this->error = 'One or more required keywords missing'; } } - if ($this->error !== false) { + if ($this->error !== null) { return; } // All required keywords exist - if (preg_match('/utf\-?8/i', $this->requiredKeywords['LanguageEncoding'][0])) { + if (preg_match('/utf-?8/i', $this->requiredKeywords['LanguageEncoding'][0])) { $this->sourceEncoding = false; // Would be a NOOP } elseif (isset($this->ENCODINGS[$this->requiredKeywords['LanguageEncoding'][0]])) { $this->sourceEncoding = $this->ENCODINGS[$this->requiredKeywords['LanguageEncoding'][0]]; @@ -669,12 +670,12 @@ class Ppd } } - private function nextLineEnd($start) + private function nextLineEnd(int $start): ?int { if ($start >= $this->dataLen) - return false; + return null; while ($start < $this->dataLen) { - $char = $this->data{$start}; + $char = $this->data[$start]; if ($char === "\r" || $char === "\n") return $start; ++$start; @@ -682,27 +683,26 @@ class Ppd return $this->dataLen; } - private function warn($lineNo, $message) + private function warn(int $lineNo, string $message): void { $line = 'Line ' . $lineNo . ': ' . $message; $this->warnings[] = $line; } - private function escapeBinaryArray($array) + private static function escapeBinaryArray(array $array): string { - $chars = array_reduce(array_unique($array), function ($carry, $item) { + return array_reduce(array_unique($array), function ($carry, $item) { return $carry . '\x' . dechex(ord($item)); }, ''); - return $chars; } - private function unhexTranslation($lineNo, $translation) + private function unhexTranslation(int $lineNo, string $translation): string { if (strpos($translation, '<') === false) return $translation; return preg_replace_callback('/<[^>]*>/', function ($match) use ($lineNo) { if (preg_match_all('/[^a-fA-F0-9\<\>\s]/', $match[0], $out)) { - $this->warn($lineNo, 'Invalid character(s) in hex substring: ' . $this->escapeBinaryArray($out[0])); + $this->warn($lineNo, 'Invalid character(s) in hex substring: ' . self::escapeBinaryArray($out[0])); } $string = preg_replace('/[^a-fA-F0-9]/', '', $match[0]); if (strlen($string) % 2 !== 0) { @@ -713,7 +713,7 @@ class Ppd }, $translation); } - private function hexTranslation($translation) + private function hexTranslation(string $translation): string { return preg_replace_callback('/[\x00-\x1f\x7b-\xff\:\<\>]+/', function ($match) { return '<' . unpack('H*', $match[0])[1] . '>'; @@ -724,23 +724,23 @@ class Ppd * Get option object * * @param string $name option name - * @param \PpdBlockInternal $block which block this option is defined in - * @return \PpdSettingInternal the option object + * @param ?PpdBlockInternal $block which block this option is defined in + * @return PpdSettingInternal the option object */ - private function getOption($name, $block = false) + private function getOption(string $name, ?PpdBlockInternal $block = null): PpdSettingInternal { if (!isset($this->settings[$name])) { $this->settings[$name] = new PpdSettingInternal(); $this->settings[$name]->block = $block; - } elseif ($block !== false) { - if ($this->settings[$name]->block === false || $block->isChildOf($this->settings[$name]->block)) { + } elseif ($block !== null) { + if ($this->settings[$name]->block === null || $block->isChildOf($this->settings[$name]->block)) { $this->settings[$name]->block = $block; } } return $this->settings[$name]; } - private function binary_in_array($elem, $array) + private function binary_in_array($elem, $array): bool { $top = sizeof($array) - 1; $bot = 0; @@ -755,7 +755,7 @@ class Ppd return false; } - private function validateLine($validator, $option, $value) + private static function validateLine($validator, ?string $option, string $value) { if (is_array($validator)) { $oExp = $validator[0]; @@ -780,7 +780,7 @@ class Ppd return true; } - private function getEolChar() + private function getEolChar(): string { $rn = substr_count("\r\n", $this->data); $r = substr_count("\r", $this->data) - $rn; @@ -799,21 +799,21 @@ class Ppd * */ - public function getError() + public function getError(): ?string { return $this->error; } - public function getWarnings() + public function getWarnings(): array { return $this->warnings; } - public function getUISettings() + public function getUISettings(): array { $result = array(); foreach ($this->settings as $mk => $option) { - $isUi = ($option->block !== false && $option->block->isUi()) || isset($this->UI_KEYWORDS[$mk]); + $isUi = ($option->block !== null && $option->block->isUi()) || isset($this->UI_KEYWORDS[$mk]); if ($isUi) { $result[] = $mk; } @@ -821,30 +821,30 @@ class Ppd return $result; } - public function getSetting($name) + public function getSetting(string $name): ?PpdSetting { if (!isset($this->settings[$name])) - return false; + return null; return new PpdSetting($this->settings[$name], isset($this->UI_KEYWORDS[$name]), $this->encoder); } - public function removeSetting($name) + public function removeSetting(string $name): bool { if (!isset($this->settings[$name])) return false; $setting = $this->settings[$name]; $ranges = array(); - $this->mergeRanges($ranges, $setting->default); - $this->mergeRanges($ranges, $setting->custom); - $this->mergeRanges($ranges, $setting->customParam); + Ppd::mergeRangesFromOption($ranges, $setting->default); + Ppd::mergeRangesFromOption($ranges, $setting->custom); + Ppd::mergeRangesFromOption($ranges, $setting->customParam); foreach ($setting->foomatic as $obj) { - $this->mergeRanges($ranges, $obj); + Ppd::mergeRangesFromOption($ranges, $obj); } foreach ($setting->values as $obj) { - $this->mergeRanges($ranges, $obj); + Ppd::mergeRangesFromOption($ranges, $obj); } - if ($setting->block !== false && $setting->block->isUi()) { - $this->mergeRanges($ranges, $setting->block->start, $setting->block->end); + if ($setting->block !== null && $setting->block->isUi()) { + Ppd::mergeRanges($ranges, $setting->block->start, $setting->block->end); } $tmp = array_map(function ($e) { return $e[0]; }, $ranges); array_multisort($tmp, SORT_NUMERIC, $ranges); @@ -853,20 +853,20 @@ class Ppd foreach ($ranges as $range) { $new .= substr($this->data, $last, $range[0] - $last); $last = $range[1]; - if ($this->data{$last} === "\r") { + if ($this->data[$last] === "\r") { $last++; } - if ($this->data{$last} === "\n") { + if ($this->data[$last] === "\n") { $last++; } } $new .= substr($this->data, $last); $this->data = $new; $this->parse(); - return $this->error === false; + return $this->error === null; } - public function addEmptyOption($settingName, $option, $translation = false, $prepend = true) + public function addEmptyOption(string $settingName, string $option, string $translation = null, bool $prepend = true): bool { if (!isset($this->settings[$settingName])) return false; @@ -874,15 +874,15 @@ class Ppd $pos = false; if (!empty($setting->values)) { if ($prepend) { - $pos = array_reduce($setting->values, function ($carry, $option) { return min($carry, $option->lineOffset); }, PHP_INT_MAX); + $pos = array_reduce($setting->values, function (int $carry, PpdOption $option) { return min($carry, $option->lineOffset); }, PHP_INT_MAX); } else { - $pos = array_reduce($setting->values, function ($carry, $option) { return max($carry, $option->lineOffset); }, 0); + $pos = array_reduce($setting->values, function (int $carry, PpdOption $option) { return max($carry, $option->lineOffset); }, 0); } - } elseif ($setting->default !== false) { + } elseif ($setting->default !== null) { $pos = $setting->default->lineOffset; - } elseif ($setting->block !== false && $setting->block->isUi()) { + } elseif ($setting->block !== null && $setting->block->isUi()) { $pos = $this->nextLineEnd($setting->block->start); - while ($pos !== false && $pos < $this->dataLen && ($this->data{$pos} === "\r" || $this->data{$pos} === "\n")) { + while ($pos !== null && $pos < $this->dataLen && ($this->data[$pos] === "\r" || $this->data[$pos] === "\n")) { $pos++; } } @@ -890,23 +890,23 @@ class Ppd return false; } $line = '*' . $settingName . ' ' . $option; - if ($translation !== false) { + if ($translation !== null) { $line .= '/' . $this->hexTranslation(($this->encoder)($translation, true)); } $eol = $this->getEolChar(); $line .= ': ""' . $eol; $this->data = substr($this->data, 0, $pos) . $line . substr($this->data, $pos); $this->parse(); - return $this->error === false; + return $this->error === null; } - public function setDefaultOption($settingName, $optionName) + public function setDefaultOption($settingName, $optionName): bool { if (!isset($this->settings[$settingName])) return false; $setting = $this->settings[$settingName]; $line = '*Default' . $settingName . ': ' . $optionName; - if ($setting->default !== false) { + if ($setting->default !== null) { $start = $setting->default->lineOffset; $end = $start + $setting->default->lineLen; } elseif (empty($setting->values)) { @@ -918,22 +918,21 @@ class Ppd } $this->data = substr($this->data, 0, $start) . $line . substr($this->data, $end); $this->parse(); - return $this->error === false; + return $this->error === null; } - public function write($file) + public function write(string $file) { return file_put_contents($file, $this->data); } - private function mergeRanges(&$ranges, $start, $end = false) + private static function mergeRangesFromOption(array &$ranges, PpdOption $option): void + { + self::mergeRanges($ranges, $option->lineOffset, $option->lineOffset + $option->lineLen); + } + + private static function mergeRanges(array &$ranges, int $start, int $end): void { - if (is_object($start) && get_class($start) === 'PpdOption') { - $end = $start->lineOffset + $start->lineLen; - $start = $start->lineOffset; - } - if ($start === false || $end === false) - return; if ($start >= $end) return; // Don't even bother foreach (array_keys($ranges) as $key) { @@ -956,7 +955,7 @@ class Ppd // $start must lie before range start, otherwise we'd have hit the case above $end = $ranges[$key][1]; unset($ranges[$key]); - continue; + //continue; } } $ranges[] = array($start, $end); @@ -965,7 +964,7 @@ class Ppd /** * @return bool whether there was at least one known option with format restriction violated. */ - public function hasInvalidOption() + public function hasInvalidOption(): bool { return $this->knownKeywordMalformed; } @@ -1013,15 +1012,13 @@ class PpdSetting /** * PpdSetting constructor. - * - * @param \PpdSettingInternal $setting */ - public function __construct($setting, $isUi, $enc) + public function __construct(PpdSettingInternal $setting, bool $isUi, callable $enc) { - if ($setting->default !== false) { + if ($setting->default !== null) { $this->default = $setting->default->option; } - if ($setting->block !== false && $setting->block->isUi()) { + if ($setting->block !== null && $setting->block->isUi()) { $this->uiOptionType = $setting->block->value; $this->uiOptionTranslation = $enc($setting->block->translation); $this->isUi = true; @@ -1055,9 +1052,9 @@ class PpdSetting class PpdSettingInternal { /** - * @var \PpdOption + * @var ?PpdOption */ - public $default = false; + public $default = null; /** * @var \PpdOption[] */ @@ -1067,17 +1064,17 @@ class PpdSettingInternal */ public $foomatic = array(); /** - * @var \PpdOption + * @var ?PpdOption */ - public $custom = false; + public $custom = null; /** - * @var \PpdOption + * @var ?PpdOption */ - public $customParam = false; + public $customParam = null; /** - * @var \PpdBlockInternal the innermost block this option resides in + * @var ?PpdBlockInternal the innermost block this option resides in */ - public $block = false; + public $block = null; } class PpdOption @@ -1088,7 +1085,7 @@ class PpdOption public $lineLen; public $multiLine = false; - public function __construct($lineOffset, $lineLen, $option, $optionTranslation) + public function __construct(int $lineOffset, int $lineLen, string $option, string $optionTranslation) { $this->option = $option; $this->optionTranslation = $optionTranslation; @@ -1106,13 +1103,13 @@ class PpdBlockInternal public $translation; public $type; /** - * @var \PpdBlockInternal[] + * @var PpdBlockInternal[] */ public $childBlocks = array(); /** - * @var \PpdBlockInternal + * @var ?PpdBlockInternal */ - public $parent; + public $parent = null; /** * @var int start byte in ppd @@ -1120,16 +1117,16 @@ class PpdBlockInternal public $start; /** - * @var int|bool end byte in ppd, false if block is not closed + * @var ?int end byte in ppd, null if block is not closed */ - public $end = false; + public $end = null; /** * @var string value of opening line for block, e.g. 'PickOne' for OpenUI */ - public $value = false; + public $value = ''; - public function __construct($id, $translation, $type, $parent, $start) + public function __construct(string $id, string $translation, string $type, ?PpdBlockInternal $parent, int $start) { $this->id = $id; $this->translation = $translation; @@ -1141,16 +1138,16 @@ class PpdBlockInternal /** * @return bool true if this is a UI block */ - public function isUi() + public function isUi(): bool { return $this->type == 'UI' || $this->type === 'JCLUI'; } /** - * @param \PpdBlockInternal $block some other PpdBlock instance + * @param PpdBlockInternal $block some other PpdBlock instance * @return bool true if this is a child of $block */ - public function isChildOf($block) + public function isChildOf(PpdBlockInternal $block): bool { $parent = $this->parent; while ($parent !== false) { diff --git a/modules-available/sysconfig/inc/sysconfig.inc.php b/modules-available/sysconfig/inc/sysconfig.inc.php index 9ad3a36f..09860c7d 100644 --- a/modules-available/sysconfig/inc/sysconfig.inc.php +++ b/modules-available/sysconfig/inc/sysconfig.inc.php @@ -3,12 +3,12 @@ class SysConfig { - public static function getAll() + public static function getAll(): array { $res = Database::simpleQuery("SELECT c.configid, c.title, c.filepath, c.status, Group_Concat(cl.locationid) AS locs FROM configtgz c" . " LEFT JOIN configtgz_location cl USING (configid) GROUP BY c.configid"); $ret = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { $ret[] = $row; } return $ret; diff --git a/modules-available/sysconfig/install.inc.php b/modules-available/sysconfig/install.inc.php index 3f80ffe6..53882882 100644 --- a/modules-available/sysconfig/install.inc.php +++ b/modules-available/sysconfig/install.inc.php @@ -87,7 +87,7 @@ if (!tableHasColumn('configtgz_module', 'dateline')) { $update[] = UPDATE_DONE; // Infer from module's filemtime $res = Database::simpleQuery('SELECT moduleid, filepath FROM configtgz_module'); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { Database::exec('UPDATE configtgz_module SET dateline = :mtime WHERE moduleid = :moduleid', ['moduleid' => $row['moduleid'], 'mtime' => filemtime($row['filepath'])]); } @@ -102,7 +102,7 @@ if (!tableHasColumn('configtgz', 'dateline')) { INNER JOIN configtgz_x_module cxm USING (configid) INNER JOIN configtgz_module m USING (moduleid) GROUP BY configid'); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { Database::exec('UPDATE configtgz SET dateline = :mtime WHERE configid = :configid', ['configid' => $row['configid'], 'mtime' => $row['dateline']]); } @@ -125,28 +125,28 @@ Module::isAvailable('sysconfig'); $list = ConfigModule::getAll(); $parentTask = null; $configList = []; -if ($list === false) { +if ($list === null) { EventLog::warning('Could not regenerate configs - please do so manually'); } else { - foreach ($list as $ad) { - if ($ad->moduleType() === 'SshConfig') { + foreach ($list as $confMod) { + if ($confMod->moduleType() === 'SshConfig') { // 2020-11-12: Split SshConfig into SshConfig and SshKey - $pubkey = $ad->getData('publicKey'); - if ($pubkey !== false && !empty($pubkey)) { - error_log('Legacy module with pubkey ' . $ad->id()); - $key = ConfigModule::getInstance('SshKey'); - if ($key !== false) { + $pubkey = $confMod->getData('publicKey'); + if (!empty($pubkey)) { + error_log('Legacy module with pubkey ' . $confMod->id()); + $key = ConfigModule::getInstanceOrNull('SshKey'); + if ($key !== null) { $key->setData('publicKey', $pubkey); - if ($key->insert($ad->title())) { + if ($key->insert($confMod->title())) { // Insert worked, remove key from old module, add this module to the same configs $task = $key->generate(false, $parentTask); if ($task !== false) { $parentTask = $task; } error_log('Inserted new module with id ' . $key->id()); - $ad->setData('publicKey', false); - $ad->update(); - $configs = ConfigTgz::getAllForModule($ad->id()); + $confMod->setData('publicKey', false); + $confMod->update(); + $configs = ConfigTgz::getAllForModule($confMod->id()); foreach ($configs as $config) { // Add newly created key-only module to all configs $new = array_merge($config->getModuleIds(), [$key->id()]); @@ -158,9 +158,9 @@ if ($list === false) { } } } - if ($ad->needRebuild()) { + if ($confMod->needRebuild()) { $update[] = UPDATE_DONE; - $task = $ad->generate(false, $parentTask); + $task = $confMod->generate(false, $parentTask); if ($task !== false) { $parentTask = $task; } @@ -171,5 +171,8 @@ if ($list === false) { } } +// Start any changed services +ConfigModuleBaseLdap::ldadp(); + // Create response for browser responseFromArray($update); diff --git a/modules-available/sysconfig/lang/de/module.json b/modules-available/sysconfig/lang/de/module.json index 1dbb268b..4bc1642f 100644 --- a/modules-available/sysconfig/lang/de/module.json +++ b/modules-available/sysconfig/lang/de/module.json @@ -6,8 +6,12 @@ "lang_moduleAssign": "Modul zu Systemkonfigurationen zuweisen", "lang_noModuleFromThisGroup": "(Kein Modul dieser Gruppe)", "lang_unknwonTaskManager": "Unbekannter Taskmanager-Fehler", + "location-column-header": "Lokalisierung", "module_name": "Lokalisierung + Integration", "page_title": "Lokalisierung + Integration", + "saver_DescriptionIdleKill": "Ein Bildschirmschoner mit Timeout, nach dessen Ablauf alle Anwendungen ohne weitere Nachfragen geschlossen werden und der Nutzer ausgeloggt wird.", + "saver_DescriptionNoTimeout": "Ein Bildschirmschoner ohne Timeout.", + "saver_DescriptionShutdown": "Ein Bildschirmschoner mit Timeout, nach dessen Ablauf alle Anwendungen ohne weitere Nachfragen geschlossen werden und der PC heruntergefahren oder neugestartet wird.", "saver_MessageDefaultIdleKill": "Diese Sitzung wird bei Inaktivit\u00e4t in %1 beendet.", "saver_MessageDefaultIdleKillLocked": "Diese Sitzung wird in %1 beendet, wenn sie nicht entsperrt wird.", "saver_MessageDefaultNoTimeout": "Dieser Bildschirm wird gerade geschont.", @@ -15,13 +19,10 @@ "saver_MessageDefaultShutdown": "Achtung: Rechner wird in %1 heruntergefahren!", "saver_MessageDefaultShutdownLocked": "Achtung: Rechner wird in %1 heruntergefahren!", "saver_QssDefault": "#Saver {\r\n background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #443, stop:1 #000)\r\n}\r\n\r\nQLabel {\r\n color: #f64;\r\n}\r\n\r\n#lblClock {\r\n color: #999;\r\n font-size: 20pt;\r\n}\r\n\r\n#lblHeader {\r\n font-size: 20pt;\r\n}\r\n", - "saver_DescriptionIdleKill": "Ein Bildschirmschoner mit Timeout, nach dessen Ablauf alle Anwendungen ohne weitere Nachfragen geschlossen werden und der Nutzer ausgeloggt wird.", - "saver_DescriptionNoTimeout": "Ein Bildschirmschoner ohne Timeout.", - "saver_DescriptionShutdown": "Ein Bildschirmschoner mit Timeout, nach dessen Ablauf alle Anwendungen ohne weitere Nachfragen geschlossen werden und der PC heruntergefahren oder neugestartet wird.", - "saver_TitleIdleKill": "Idle Kill", - "saver_TitleNoTimeout": "Ohne Timeout", - "saver_TitleShutdown": "Herunterfahren", "saver_TextDefaultIdleKill": "<html><body>Keine Nutzeraktivit\u00e4t festgestellt. <br>Zum oben angegebenen Zeitpunkt wird die aktuell laufende Sitzung beendet, wenn der Rechner nicht mehr verwendet wird. <br>Alle noch laufenden Programme <br>werden ohne Nachfrage geschlossen. Stellen Sie daher sicher, bis zum angegebenen Zeitpunkt <br>s\u00e4mtliche sich in Bearbeitung befindlichen Daten abzuspeichern. <br><br>Dies dient dazu zu vermeiden, dass ein Rechner stundenlang gesperrt wird und somit <br>anderen Nutzern nicht zur Verf\u00fcgung steht.<\/body><\/html>", "saver_TextDefaultIdleKillLocked": "<html><body><br>Zum oben angegebenen Zeitpunkt wird die aktuell laufende Sitzung beendet, wenn sie zuvor nicht wieder entsperrt wird. <br>Alle noch laufenden Programme werden ohne Nachfrage geschlossen. <br>Stellen Sie daher sicher, bis zum angegebenen Zeitpunkt <br>s\u00e4mtliche sich in Bearbeitung befindlichen Daten abzuspeichern, bzw. die Sitzung wieder zu entsperren. <br><br>Dies dient dazu zu vermeiden, dass ein Rechner stundenlang gesperrt wird und somit<br>anderen Nutzern nicht zur Verf\u00fcgung steht.<\/body><\/html>", - "saver_TextDefaultShutdown": "<html><body>Achtung: Zum oben angegebenen Zeitpunkt wird der Computer heruntergefahren bzw. neugestartet. <br>Alle noch laufenden Programme werden ohne Nachfrage beendet. Stellen Sie daher sicher, bis <br>zum angegebenen Zeitpunkt s\u00e4mtliche Daten abzuspeichern und die Sitzung zu verlassen.<\/body><\/html>" -} + "saver_TextDefaultShutdown": "<html><body>Achtung: Zum oben angegebenen Zeitpunkt wird der Computer heruntergefahren bzw. neugestartet. <br>Alle noch laufenden Programme werden ohne Nachfrage beendet. Stellen Sie daher sicher, bis <br>zum angegebenen Zeitpunkt s\u00e4mtliche Daten abzuspeichern und die Sitzung zu verlassen.<\/body><\/html>", + "saver_TitleIdleKill": "Idle Kill", + "saver_TitleNoTimeout": "Ohne Timeout", + "saver_TitleShutdown": "Herunterfahren" +}
\ No newline at end of file diff --git a/modules-available/sysconfig/lang/en/module.json b/modules-available/sysconfig/lang/en/module.json index b49cc1cf..dbfacdb8 100644 --- a/modules-available/sysconfig/lang/en/module.json +++ b/modules-available/sysconfig/lang/en/module.json @@ -6,8 +6,12 @@ "lang_moduleAssign": "Assign Module to System Configurations", "lang_noModuleFromThisGroup": "(No module from this group)", "lang_unknwonTaskManager": "Unknown Task Manager error", + "location-column-header": "SysConfig", "module_name": "Localization", "page_title": "Localize and integrate", + "saver_DescriptionIdleKill": "A screensaver with a timeout which on it's expiration will close all running applications without further requests and logout the user.", + "saver_DescriptionNoTimeout": "A screensaver without a timeout.", + "saver_DescriptionShutdown": "A screensaver with a timeout which on it's expiration the PC will shutdown or restart. All applications will be closed without further requests.", "saver_MessageDefaultIdleKill": "This session will end in %1 when inactive.", "saver_MessageDefaultIdleKillLocked": "This session will end in %1 if the session is not unlocked.", "saver_MessageDefaultNoTimeout": "This screen is in saving mode.", @@ -15,13 +19,10 @@ "saver_MessageDefaultShutdown": "Caution: Computer will shutdown in %1!", "saver_MessageDefaultShutdownLocked": "Caution: Computer will shutdown in %1!", "saver_QssDefault": "#Saver {\r\n background: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #443, stop:1 #000)\r\n}\r\n\r\nQLabel {\r\n color: #f64;\r\n}\r\n\r\n#lblClock {\r\n color: #999;\r\n font-size: 20pt;\r\n}\r\n\r\n#lblHeader {\r\n font-size: 20pt;\r\n}\r\n", - "saver_DescriptionIdleKill": "A screensaver with a timeout which on it's expiration will close all running applications without further requests and logout the user.", - "saver_DescriptionNoTimeout": "A screensaver without a timeout.", - "saver_DescriptionShutdown": "A screensaver with a timeout which on it's expiration the PC will shutdown or restart. All applications will be closed without further requests.", - "saver_TitleIdleKill": "Idle Kill", - "saver_TitleNoTimeout": "No Timeout", - "saver_TitleShutdown": "Shutdown", "saver_TextDefaultIdleKill": "<html><body>No user activity detected. <br>If the computer is not used until the time specified above, the session will end. <br> All running applications <br>will be closed without further requests. Make sure that all files and changes are saved <br> before the time runs out. <br><br>It prevents computers from beeing locked for hours and <br>not beeing available for other users.<\/body><\/html>", "saver_TextDefaultIdleKillLocked": "<html><body><br>The current session will end by the time specified above if the computer isn't unlocked before. <br>All running applications will be closed without further requests. <br>Make sure that all files and changes are saved <br>or the session is unlocked before the time runs out. <br><br>It prevents computers from beeing locked for hours and <br>not beeing available for other users.<\/body><\/html>", - "saver_TextDefaultShutdown": "<html><body>Caution: The computer will shutdown or restart respectively at the specified time above. <br>All running applications will be closed without further requests. Make sure to save all files and changes and leave the session<br>before the time runs out.<\/body><\/html>" -} + "saver_TextDefaultShutdown": "<html><body>Caution: The computer will shutdown or restart respectively at the specified time above. <br>All running applications will be closed without further requests. Make sure to save all files and changes and leave the session<br>before the time runs out.<\/body><\/html>", + "saver_TitleIdleKill": "Idle Kill", + "saver_TitleNoTimeout": "No Timeout", + "saver_TitleShutdown": "Shutdown" +}
\ No newline at end of file diff --git a/modules-available/sysconfig/page.inc.php b/modules-available/sysconfig/page.inc.php index ff3983c1..b11f399e 100644 --- a/modules-available/sysconfig/page.inc.php +++ b/modules-available/sysconfig/page.inc.php @@ -152,11 +152,12 @@ class Page_SysConfig extends Page $listid = Request::post('list', Request::REQUIRED, 'int'); $this->listConfigContents($listid); return; + default: } Message::addError('invalid-action', $action, 'main'); } - private function getLocationNames($locations, $ids) + private function getLocationNames(array $locations, array $ids): string { $ret = array(); foreach ($ids as $id) { @@ -188,7 +189,7 @@ class Page_SysConfig extends Page $locationName = false; } $hasDefault = false; - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { if (is_null($row['loclist'])) { $locList = array(); } else { @@ -236,7 +237,7 @@ class Page_SysConfig extends Page private function listModules() { // Config modules - $modules = ConfigModule::getAll(); + $modules = ConfigModule::getAll() ?? []; $types = array_map(function ($mod) { return $mod->moduleType(); }, $modules); $titles = array_map(function ($mod) { return $mod->title(); }, $modules); array_multisort($types, SORT_ASC, $titles, SORT_ASC, $modules); @@ -291,7 +292,7 @@ class Page_SysConfig extends Page . " ORDER BY module.title ASC", array('configid' => $configid)); $modules = array(); - while ($row = $res->fetch(PDO::FETCH_ASSOC)) { + foreach ($res as $row) { $modules[] = array( 'module' => $row['moduletitle'], 'moduleid' => $row['moduleid'] @@ -336,7 +337,7 @@ class Page_SysConfig extends Page { $configid = Request::post('rebuild', Request::REQUIRED, 'int'); $config = ConfigTgz::get($configid); - if ($config === false) { + if ($config === null) { Message::addError('config-invalid', $configid); Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc); } @@ -375,9 +376,9 @@ class Page_SysConfig extends Page Message::addSuccess('module-deleted', $module['title']); } // Rebuild depending config.tgz - while ($crow = $existing->fetch(PDO::FETCH_ASSOC)) { + foreach ($existing as $crow) { $config = ConfigTgz::get($crow['configid']); - if ($config !== false) { + if ($config !== null) { $config->generate(); } } @@ -401,11 +402,11 @@ class Page_SysConfig extends Page { $moduleid = Request::post('rebuild', Request::REQUIRED); $module = ConfigModule::get($moduleid); - if ($module === false) { + if ($module === null) { Message::addError('config-invalid', $moduleid); Util::redirect('?do=sysconfig'); } - $ret = $module->generate(false, 250); + $ret = $module->generate(false, null, 500); if ($ret === true) Message::addSuccess('module-rebuilt', $module->title()); elseif ($ret === false) @@ -419,7 +420,7 @@ class Page_SysConfig extends Page { $configid = Request::post('del', Request::REQUIRED); $config = ConfigTgz::get($configid); - if ($config === false) { + if ($config === null) { Message::addError('config-invalid', $configid); Util::redirect('?do=sysconfig&locationid=' . $this->currentLoc); } diff --git a/modules-available/sysconfig/templates/ad-start.html b/modules-available/sysconfig/templates/ad-start.html index 3cca080f..6dd6208a 100644 --- a/modules-available/sysconfig/templates/ad-start.html +++ b/modules-available/sysconfig/templates/ad-start.html @@ -21,7 +21,7 @@ <input type="hidden" name="edit" value="{{edit}}"> <div class="input-group"> <span class="input-group-addon slx-ga2">{{lang_moduleTitle}}</span> - <input tabindex="1" name="title" value="{{title}}" type="text" class="form-control" autofocus> + <input tabindex="1" name="title" value="{{title}}" type="text" class="form-control" autofocus required> </div> <div class="input-group"> <span class="input-group-addon slx-ga2">Server *</span> diff --git a/modules-available/sysconfig/templates/branding-check.html b/modules-available/sysconfig/templates/branding-check.html index d48f9631..80eb4d48 100644 --- a/modules-available/sysconfig/templates/branding-check.html +++ b/modules-available/sysconfig/templates/branding-check.html @@ -20,7 +20,7 @@ <input type="hidden" name="edit" value="{{edit}}"> <div class="form-group"> <label for="title-id">{{lang_title}}</label> - <input type="text" name="title" value="{{title}}" id ="title-id" class="form-control" placeholder="Name des Moduls"> + <input type="text" name="title" value="{{title}}" id ="title-id" class="form-control" placeholder="Name des Moduls" required> </div> <div class="btn-group"> <a class="btn btn-default" href="?do=SysConfig&action=addmodule&step=Branding_Start">{{lang_cancel}}</a> diff --git a/modules-available/sysconfig/templates/branding-start.html b/modules-available/sysconfig/templates/branding-start.html index 0db085d9..a6346552 100644 --- a/modules-available/sysconfig/templates/branding-start.html +++ b/modules-available/sysconfig/templates/branding-start.html @@ -14,7 +14,7 @@ <input type="text" class="form-control" readonly placeholder="{{lang_selectFile}}"> <span class="input-group-btn"> <span class="btn btn-default btn-file"> - {{lang_browseForFile}}… <input type="file" name="file" id="input-file"> + {{lang_browseForFile}}… <input type="file" accept="image/svg+xml" name="file" id="input-file"> </span> </span> </div> diff --git a/modules-available/sysconfig/templates/cfg-start.html b/modules-available/sysconfig/templates/cfg-start.html index b4628cba..018cf89f 100644 --- a/modules-available/sysconfig/templates/cfg-start.html +++ b/modules-available/sysconfig/templates/cfg-start.html @@ -3,7 +3,7 @@ <input type="hidden" name="edit" value="{{edit}}"> <div class="input-group"> <span class="input-group-addon">{{lang_name}} *</span> - <input type="text" name="title" value="{{title}}" class="form-control" placeholder="{{lang_configuration}}" autofocus="autofocus"> + <input type="text" name="title" value="{{title}}" class="form-control" placeholder="{{lang_configuration}}" autofocus="autofocus" required> </div> <hr> <p>{{lang_configurationChoose}}</p> diff --git a/modules-available/sysconfig/templates/custom-fileselect.html b/modules-available/sysconfig/templates/custom-fileselect.html index 3e7dd3d6..5f190f08 100644 --- a/modules-available/sysconfig/templates/custom-fileselect.html +++ b/modules-available/sysconfig/templates/custom-fileselect.html @@ -5,7 +5,7 @@ <div class="input-group"> <span class="input-group-addon">{{lang_moduleName}}</span> <input type="text" name="title" value="{{title}}" class="form-control" placeholder="Mein Konfigurationsmodul" - autofocus="autofocus"> + autofocus="autofocus" required> </div> <div class="pull-right"> <button type="submit" class="btn btn-primary">{{lang_next}} »</button> @@ -51,4 +51,5 @@ <div class="pull-right"> <button type="submit" class="btn btn-primary">{{lang_next}} »</button> </div> + <div class="clearfix"></div> </form> diff --git a/modules-available/sysconfig/templates/ldap-start.html b/modules-available/sysconfig/templates/ldap-start.html index 059d54f5..e6c98680 100644 --- a/modules-available/sysconfig/templates/ldap-start.html +++ b/modules-available/sysconfig/templates/ldap-start.html @@ -11,7 +11,7 @@ <input type="hidden" name="edit" value="{{edit}}"> <div class="input-group"> <span class="input-group-addon slx-ga2">{{lang_moduleTitle}}</span> - <input tabindex="1" name="title" value="{{title}}" type="text" class="form-control"> + <input tabindex="1" name="title" value="{{title}}" type="text" class="form-control" required> </div> <div class="input-group"> <span class="input-group-addon slx-ga2">Server *</span> diff --git a/modules-available/sysconfig/templates/sshconfig-start.html b/modules-available/sysconfig/templates/sshconfig-start.html index 9920683d..b56be415 100644 --- a/modules-available/sysconfig/templates/sshconfig-start.html +++ b/modules-available/sysconfig/templates/sshconfig-start.html @@ -3,7 +3,7 @@ <input type="hidden" name="edit" value="{{edit}}"> <div class="input-group"> <span class="input-group-addon">{{lang_moduleName}}</span> - <input type="text" name="title" value="{{title}}" class="form-control" autofocus="autofocus"> + <input type="text" name="title" value="{{title}}" class="form-control" autofocus="autofocus" required> </div> <br> <div class="form-group"> diff --git a/modules-available/sysconfig/templates/sshkey-start.html b/modules-available/sysconfig/templates/sshkey-start.html index 52709984..8033740c 100644 --- a/modules-available/sysconfig/templates/sshkey-start.html +++ b/modules-available/sysconfig/templates/sshkey-start.html @@ -3,13 +3,16 @@ <input type="hidden" name="edit" value="{{edit}}"> <div class="input-group"> <span class="input-group-addon">{{lang_moduleName}}</span> - <input type="text" name="title" value="{{title}}" class="form-control" autofocus="autofocus"> + <input type="text" name="title" value="{{title}}" class="form-control" autofocus="autofocus" required> </div> <div class="form-group"> <label for="root-key">{{lang_rootKey}}</label> <input class="form-control" type="text" name="publicKey" value="{{publicKey}}" id="root-key" required pattern="[a-z0-9\-]+ +[a-zA-Z0-9=/\+]+ +.*"> <i>{{lang_rootKeyInfo}}</i> </div> + <div class="btn-group"> + <a class="btn btn-default" href="?do=SysConfig&action=addmodule">{{lang_back}}</a> + </div> <div class="btn-group pull-right"> <button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> {{lang_save}}</button> </div> |