From 06bff0b9b84d47c43f9bc8aff06a29d85ebb7ed0 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Tue, 14 Nov 2023 14:47:55 +0100 Subject: Add function param/return types, fix a lot more phpstorm complaints --- .idea/inspectionProfiles/Project_Default.xml | 2 +- Mustache/Compiler.php | 14 +- Mustache/Engine.php | 1 + Mustache/Parser.php | 11 +- api.php | 2 +- apis/cron.inc.php | 7 +- inc/arrayutil.inc.php | 11 +- inc/crypto.inc.php | 5 +- inc/dashboard.inc.php | 33 ++-- inc/database.inc.php | 13 +- inc/dictionary.inc.php | 72 ++++---- inc/download.inc.php | 13 +- inc/errorhandler.inc.php | 11 +- inc/event.inc.php | 4 +- inc/fileutil.inc.php | 16 +- inc/hook.inc.php | 12 +- inc/iputil.inc.php | 34 ++-- inc/mailer.inc.php | 14 +- inc/message.inc.php | 35 ++-- inc/module.inc.php | 63 +++---- inc/paginate.inc.php | 25 +-- inc/permission.inc.php | 16 +- inc/property.inc.php | 30 +-- inc/render.inc.php | 52 +++--- inc/request.inc.php | 4 +- inc/session.inc.php | 20 +- inc/taskmanager.inc.php | 30 +-- inc/taskmanagercallback.inc.php | 30 +-- inc/trigger.inc.php | 22 +-- inc/user.inc.php | 22 ++- inc/util.inc.php | 41 +++-- index.php | 7 +- install.php | 81 ++++---- modules-available/adduser/page.inc.php | 4 +- .../baseconfig/inc/baseconfig.inc.php | 25 +-- .../baseconfig/inc/baseconfigutil.inc.php | 14 +- .../baseconfig/inc/configholder.inc.php | 19 +- modules-available/baseconfig/inc/validator.inc.php | 5 +- modules-available/baseconfig/page.inc.php | 14 +- .../baseconfig_bwidm/hooks/translation.inc.php | 8 +- .../baseconfig_bwlp/hooks/translation.inc.php | 8 +- .../dnbd3/baseconfig/getconfig.inc.php | 7 +- modules-available/dnbd3/hooks/translation.inc.php | 4 +- modules-available/dnbd3/inc/dnbd3rpc.inc.php | 17 +- modules-available/dnbd3/inc/dnbd3util.inc.php | 19 +- modules-available/dnbd3/page.inc.php | 1 + modules-available/dozmod/api.inc.php | 58 +++--- modules-available/dozmod/page.inc.php | 2 +- modules-available/dozmod/pages/actionlog.inc.php | 4 +- .../dozmod/pages/expiredimages.inc.php | 2 +- modules-available/dozmod/pages/mailconfig.inc.php | 2 +- modules-available/dozmod/pages/templates.inc.php | 2 +- modules-available/dozmod/pages/users.inc.php | 4 +- .../eventlog/inc/filterruleprocessor.inc.php | 4 +- modules-available/eventlog/pages/log.inc.php | 4 +- .../exams/baseconfig/getconfig.inc.php | 13 +- modules-available/exams/inc/exams.inc.php | 9 +- modules-available/exams/page.inc.php | 20 +- modules-available/locationinfo/api.inc.php | 14 +- .../PhpEws/ArrayType/ArrayOfStringsType.php | 2 +- .../jamesiarmes/PhpNtlm/SoapClient.php | 5 +- .../locationinfo/inc/coursebackend.inc.php | 11 +- .../coursebackend/coursebackend_davinci.inc.php | 2 +- .../coursebackend/coursebackend_exchange.inc.php | 9 +- .../locationinfo/inc/icalcoursebackend.inc.php | 21 +-- .../locationinfo/inc/icalevent.inc.php | 9 +- .../locationinfo/inc/icalparser.inc.php | 6 +- .../locationinfo/inc/infopanel.inc.php | 23 +-- .../locationinfo/inc/locationinfo.inc.php | 11 +- .../locationinfo/inc/locationinfohooks.inc.php | 15 +- modules-available/locationinfo/page.inc.php | 42 +++-- .../locations/baseconfig/getconfig.inc.php | 5 +- modules-available/locations/inc/location.inc.php | 67 ++++--- .../locations/inc/locationhooks.inc.php | 4 +- .../locations/inc/locationutil.inc.php | 16 +- .../locations/inc/openingtimes.inc.php | 3 +- modules-available/locations/pages/cleanup.inc.php | 6 +- modules-available/locations/pages/details.inc.php | 17 +- .../locations/pages/locations.inc.php | 6 +- modules-available/locations/pages/subnets.inc.php | 8 +- modules-available/main/hooks/cron.inc.php | 2 + modules-available/main/hooks/translation.inc.php | 5 +- modules-available/main/page.inc.php | 2 +- .../minilinux/inc/linuxbootentryhook.inc.php | 17 +- modules-available/minilinux/inc/minilinux.inc.php | 47 +++-- modules-available/minilinux/page.inc.php | 26 +-- modules-available/news/page.inc.php | 47 ++--- .../hooks/translation-global.inc.php | 5 +- .../inc/getpermissiondata.inc.php | 12 +- .../inc/permissiondbupdate.inc.php | 21 ++- .../permissionmanager/inc/permissionutil.inc.php | 29 +-- modules-available/permissionmanager/page.inc.php | 28 +-- .../rebootcontrol/hooks/client-update.inc.php | 2 +- .../rebootcontrol/hooks/config-tgz.inc.php | 6 +- modules-available/rebootcontrol/hooks/cron.inc.php | 2 +- .../rebootcontrol/inc/rebootcontrol.inc.php | 28 +-- .../rebootcontrol/inc/rebootutils.inc.php | 11 +- .../rebootcontrol/inc/scheduler.inc.php | 4 +- modules-available/rebootcontrol/inc/sshkey.inc.php | 27 ++- modules-available/rebootcontrol/page.inc.php | 4 +- .../rebootcontrol/pages/subnet.inc.php | 2 +- modules-available/rebootcontrol/pages/task.inc.php | 11 -- modules-available/remoteaccess/api.inc.php | 2 +- .../remoteaccess/baseconfig/getconfig.inc.php | 11 +- .../remoteaccess/inc/remoteaccess.inc.php | 2 +- modules-available/remoteaccess/page.inc.php | 2 +- .../roomplanner/inc/composedroom.inc.php | 21 +-- .../roomplanner/inc/pvsgenerator.inc.php | 14 +- modules-available/roomplanner/inc/room.inc.php | 49 ++--- .../roomplanner/inc/simpleroom.inc.php | 18 +- modules-available/roomplanner/page.inc.php | 61 +++--- .../runmode/baseconfig/getconfig.inc.php | 13 +- modules-available/runmode/inc/runmode.inc.php | 57 +++--- modules-available/runmode/page.inc.php | 28 ++- .../serversetup-bwlp-ipxe/inc/bootentry.inc.php | 95 +++++----- .../inc/bootentryhook.inc.php | 53 +++--- .../serversetup-bwlp-ipxe/inc/execdata.inc.php | 7 +- .../serversetup-bwlp-ipxe/inc/ipxe.inc.php | 146 +++++++-------- .../serversetup-bwlp-ipxe/inc/ipxebuilder.inc.php | 16 +- .../serversetup-bwlp-ipxe/inc/ipxemenu.inc.php | 19 +- .../serversetup-bwlp-ipxe/inc/localboot.inc.php | 3 + .../serversetup-bwlp-ipxe/inc/menuentry.inc.php | 49 +++-- .../serversetup-bwlp-ipxe/inc/pxelinux.inc.php | 36 +++- .../inc/scriptbuilderbase.inc.php | 49 +++-- .../inc/scriptbuilderbash.inc.php | 20 +- .../inc/scriptbuilderipxe.inc.php | 45 ++--- .../serversetup-bwlp-ipxe/page.inc.php | 73 ++++---- modules-available/session/page.inc.php | 3 +- modules-available/statistics/api.inc.php | 2 +- .../statistics/baseconfig/getconfig.inc.php | 37 ++-- .../statistics/hooks/translation.inc.php | 4 +- .../statistics/inc/hardwareinfo.inc.php | 3 +- .../statistics/inc/hardwareparser.inc.php | 26 +-- .../statistics/inc/hardwareparserlegacy.inc.php | 5 +- .../statistics/inc/hardwarequery.inc.php | 40 ++-- .../statistics/inc/statistics.inc.php | 15 +- .../statistics/inc/statisticsfilter.inc.php | 23 +-- .../statistics/inc/statisticsfilterset.inc.php | 17 +- .../statistics/inc/statisticshooks.inc.php | 13 +- .../statistics/inc/statisticsstyling.inc.php | 6 +- modules-available/statistics/page.inc.php | 2 +- modules-available/statistics/pages/list.inc.php | 17 +- modules-available/statistics/pages/machine.inc.php | 4 +- modules-available/statistics/pages/summary.inc.php | 43 ++--- .../statistics_reporting/inc/getdata.inc.php | 21 ++- .../statistics_reporting/inc/queries.inc.php | 35 ++-- .../statistics_reporting/inc/remotereport.inc.php | 2 +- .../statistics_reporting/page.inc.php | 19 +- modules-available/sysconfig/addconfig.inc.php | 44 ++--- modules-available/sysconfig/addmodule.inc.php | 48 ++--- .../sysconfig/addmodule_adauth.inc.php | 29 +-- .../sysconfig/addmodule_branding.inc.php | 31 ++-- .../sysconfig/addmodule_custommodule.inc.php | 26 ++- .../sysconfig/addmodule_ldapauth.inc.php | 28 +-- .../sysconfig/addmodule_screensaver.inc.php | 46 ++--- .../sysconfig/addmodule_sshconfig.inc.php | 23 ++- .../sysconfig/addmodule_sshkey.inc.php | 12 +- modules-available/sysconfig/api.inc.php | 6 +- .../sysconfig/inc/configmodule.inc.php | 197 +++++++++++--------- .../sysconfig/inc/configmodule/branding.inc.php | 14 +- .../sysconfig/inc/configmodule/customodule.inc.php | 14 +- .../sysconfig/inc/configmodule/ldapauth.inc.php | 2 +- .../sysconfig/inc/configmodule/screensaver.inc.php | 25 ++- .../sysconfig/inc/configmodule/sshconfig.inc.php | 8 +- .../sysconfig/inc/configmodule/sshkey.inc.php | 8 +- .../sysconfig/inc/configmodulebaseldap.inc.php | 22 +-- modules-available/sysconfig/inc/configtgz.inc.php | 146 ++++++++------- modules-available/sysconfig/inc/ldap.inc.php | 2 +- modules-available/sysconfig/inc/ppd.inc.php | 205 +++++++++++---------- modules-available/sysconfig/inc/sysconfig.inc.php | 2 +- modules-available/sysconfig/install.inc.php | 26 +-- modules-available/sysconfig/page.inc.php | 13 +- modules-available/syslog/page.inc.php | 2 +- .../systemstatus/inc/systemstatus.inc.php | 2 +- modules-available/systemstatus/page.inc.php | 27 ++- modules-available/translation/page.inc.php | 135 +++++++------- .../vmstore/baseconfig/getconfig.inc.php | 4 + .../vmstore/inc/vmstorebenchmark.inc.php | 6 +- modules-available/vmstore/page.inc.php | 16 +- .../webinterface/baseconfig/getconfig.inc.php | 3 + tools/convert-modules.php | 2 +- tools/jedec.php | 4 +- 182 files changed, 1958 insertions(+), 2108 deletions(-) diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index cb285b8f..953381a3 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -243,7 +243,7 @@ - + diff --git a/Mustache/Compiler.php b/Mustache/Compiler.php index 2b0d1f93..fd93741a 100644 --- a/Mustache/Compiler.php +++ b/Mustache/Compiler.php @@ -96,7 +96,7 @@ class Mustache_Compiler $code .= $this->section( $node[Mustache_Tokenizer::NODES], $node[Mustache_Tokenizer::NAME], - isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(), + $node[Mustache_Tokenizer::FILTERS] ?? array(), $node[Mustache_Tokenizer::INDEX], $node[Mustache_Tokenizer::END], $node[Mustache_Tokenizer::OTAG], @@ -109,7 +109,7 @@ class Mustache_Compiler $code .= $this->invertedSection( $node[Mustache_Tokenizer::NODES], $node[Mustache_Tokenizer::NAME], - isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(), + $node[Mustache_Tokenizer::FILTERS] ?? array(), $level ); break; @@ -117,8 +117,8 @@ class Mustache_Compiler case Mustache_Tokenizer::T_PARTIAL: $code .= $this->partial( $node[Mustache_Tokenizer::NAME], - isset($node[Mustache_Tokenizer::DYNAMIC]) ? $node[Mustache_Tokenizer::DYNAMIC] : false, - isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '', + $node[Mustache_Tokenizer::DYNAMIC] ?? false, + $node[Mustache_Tokenizer::INDENT] ?? '', $level ); break; @@ -126,8 +126,8 @@ class Mustache_Compiler case Mustache_Tokenizer::T_PARENT: $code .= $this->parent( $node[Mustache_Tokenizer::NAME], - isset($node[Mustache_Tokenizer::DYNAMIC]) ? $node[Mustache_Tokenizer::DYNAMIC] : false, - isset($node[Mustache_Tokenizer::INDENT]) ? $node[Mustache_Tokenizer::INDENT] : '', + $node[Mustache_Tokenizer::DYNAMIC] ?? false, + $node[Mustache_Tokenizer::INDENT] ?? '', $node[Mustache_Tokenizer::NODES], $level ); @@ -165,7 +165,7 @@ class Mustache_Compiler case Mustache_Tokenizer::T_UNESCAPED_2: $code .= $this->variable( $node[Mustache_Tokenizer::NAME], - isset($node[Mustache_Tokenizer::FILTERS]) ? $node[Mustache_Tokenizer::FILTERS] : array(), + $node[Mustache_Tokenizer::FILTERS] ?? array(), $node[Mustache_Tokenizer::TYPE] === Mustache_Tokenizer::T_ESCAPED, $level ); diff --git a/Mustache/Engine.php b/Mustache/Engine.php index 7a31ac03..0ac2a738 100644 --- a/Mustache/Engine.php +++ b/Mustache/Engine.php @@ -689,6 +689,7 @@ class Mustache_Engine array('name' => $e->getTemplateName()) ); } + return null; } /** diff --git a/Mustache/Parser.php b/Mustache/Parser.php index 5db58244..e5523b24 100644 --- a/Mustache/Parser.php +++ b/Mustache/Parser.php @@ -222,7 +222,7 @@ class Mustache_Parser { if ($this->lineTokens > 1) { // this is the third or later node on this line, so it can't be standalone - return; + return null; } $prev = null; @@ -231,7 +231,7 @@ class Mustache_Parser // unless the previous node is whitespace. if ($prev = end($nodes)) { if (!$this->tokenIsWhitespace($prev)) { - return; + return null; } } } @@ -239,19 +239,19 @@ class Mustache_Parser if ($next = reset($tokens)) { // If we're on a new line, bail. if ($next[Mustache_Tokenizer::LINE] !== $this->lineNum) { - return; + return null; } // If the next token isn't whitespace, bail. if (!$this->tokenIsWhitespace($next)) { - return; + return null; } if (count($tokens) !== 1) { // Unless it's the last token in the template, the next token // must end in newline for this to be standalone. if (substr($next[Mustache_Tokenizer::VALUE], -1) !== "\n") { - return; + return null; } } @@ -263,6 +263,7 @@ class Mustache_Parser // Return the whitespace prefix, if any return array_pop($nodes); } + return null; } /** diff --git a/api.php b/api.php index 4c58687b..5a451f3a 100644 --- a/api.php +++ b/api.php @@ -23,7 +23,7 @@ spl_autoload_register(function ($class) { require_once $file; }); -function isLocalExecution() +function isLocalExecution(): bool { return !isset($_SERVER['REMOTE_ADDR']) || $_SERVER['REMOTE_ADDR'] === '127.0.0.1'; } diff --git a/apis/cron.inc.php b/apis/cron.inc.php index 0b1e92a9..03b6201f 100644 --- a/apis/cron.inc.php +++ b/apis/cron.inc.php @@ -14,7 +14,7 @@ define('CRON_KEY_STATUS', 'cron.key.status'); define('CRON_KEY_BLOCKED', 'cron.key.blocked'); // Crash report mode - used by system crontab entry -if (($report = Request::get('crashreport', false, 'string'))) { +if (($report = Request::get('crashreport', false, 'string')) !== false) { $list = Property::getList(CRON_KEY_STATUS); if (empty($list)) { error_log('Cron crash report triggered but no cronjob marked active.'); @@ -62,10 +62,7 @@ function getJobStatus($id) } // Hooks by other modules -/** - * @param Hook $hook - */ -function handleModule($hook) +function handleModule(Hook $hook): void { global $cron_log_text; $cron_log_text = ''; diff --git a/inc/arrayutil.inc.php b/inc/arrayutil.inc.php index 9ce5730f..7aded4db 100644 --- a/inc/arrayutil.inc.php +++ b/inc/arrayutil.inc.php @@ -6,9 +6,6 @@ class ArrayUtil /** * Take an array of arrays, take given key from each sub-array and return * new array with just those corresponding values. - * @param array $list - * @param string $key - * @return array */ public static function flattenByKey(array $list, string $key): array { @@ -18,8 +15,6 @@ class ArrayUtil /** * Pass an array of arrays you want to merge. The keys of the outer array will become * the inner keys of the resulting array, and vice versa. - * @param array $arrays - * @return array */ public static function mergeByKey(array $arrays): array { @@ -38,11 +33,8 @@ class ArrayUtil /** * Sort array by given column. - * @param array $array - * @param string $column - * @return void */ - public static function sortByColumn(array &$array, string $column, int $sortOrder = SORT_ASC, int $sortFlags = SORT_REGULAR) + public static function sortByColumn(array &$array, string $column, int $sortOrder = SORT_ASC, int $sortFlags = SORT_REGULAR): void { $sorter = array_column($array, $column); array_multisort($sorter, $sortOrder, $sortFlags, $array); @@ -53,7 +45,6 @@ class ArrayUtil * * @param array $array An array * @param array $keyList A list of strings which must all be valid keys in $array - * @return boolean */ public static function hasAllKeys(array $array, array $keyList): bool { diff --git a/inc/crypto.inc.php b/inc/crypto.inc.php index d26a94ab..c82a5d82 100644 --- a/inc/crypto.inc.php +++ b/inc/crypto.inc.php @@ -10,8 +10,11 @@ class Crypto */ public static function hash6(string $password): string { + $bytes = Util::randomBytes(16); + if ($bytes === null) + ErrorHandler::traceError('Could not get random bytes'); $salt = substr(str_replace('+', '.', - base64_encode(Util::randomBytes(16))), 0, 16); + base64_encode($bytes)), 0, 16); $hash = crypt($password, '$6$' . $salt); if ($hash === null || strlen($hash) < 60) { ErrorHandler::traceError('Error hashing password using SHA-512'); diff --git a/inc/dashboard.inc.php b/inc/dashboard.inc.php index 0b0f69e3..716776d3 100644 --- a/inc/dashboard.inc.php +++ b/inc/dashboard.inc.php @@ -7,12 +7,12 @@ class Dashboard private static $subMenu = array(); private static $disabled = false; - public static function disable() + public static function disable(): void { self::$disabled = true; } - public static function createMenu() + public static function createMenu(): void { if (self::$disabled) return; @@ -22,7 +22,7 @@ class Dashboard if (isset($MENU_CAT_OVERRIDE)) { foreach ($MENU_CAT_OVERRIDE as $cat => $list) { foreach ($list as $mod) { - $modByCategory[$cat][$mod] = false; + $modByCategory[$cat][$mod] = null; $modById[$mod] =& $modByCategory[$cat][$mod]; } } @@ -30,10 +30,10 @@ class Dashboard $all = Module::getEnabled(true); foreach ($all as $module) { $cat = $module->getCategory(); - if ($cat === false) + if (empty($cat)) continue; $modId = $module->getIdentifier(); - if (isset($modById[$modId])) { + if (array_key_exists($modId, $modById)) { $modById[$modId] = $module; } else { $modByCategory[$cat][$modId] = $module; @@ -43,10 +43,10 @@ class Dashboard $categories = array(); foreach ($modByCategory as $catId => $modList) { $collapse = true; - /* @var Module[] $modList */ + /* @var (?Module)[] $modList */ $modules = array(); - foreach ($modList as $modId => $module) { - if ($module === false) + foreach ($modList as $module) { + if ($module === null) continue; // Was set in $MENU_CAT_OVERRIDE, but is not enabled $newEntry = array( 'displayName' => $module->getDisplayName(), @@ -62,28 +62,25 @@ class Dashboard } $modules[] = $newEntry; } - $categories[] = array( + $categories[] = [ 'icon' => self::getCategoryIcon($catId), 'displayName' => Dictionary::getCategoryName($catId), 'modules' => $modules, 'collapse' => $collapse, - ); + ]; } - Render::setDashboard(array( + Render::setDashboard([ 'categories' => $categories, 'url' => urlencode($_SERVER['REQUEST_URI']), 'langs' => Dictionary::getLanguages(true), 'user' => User::getName(), 'warning' => User::getName() !== false && User::hasPermission('.eventlog.*') && User::getLastSeenEvent() < Property::getLastWarningId(), 'needsSetup' => User::getName() !== false && Property::getNeedsSetup() - )); + ]); } - public static function getCategoryIcon($category) + public static function getCategoryIcon(string $category): string { - if ($category === false) { - return ''; - } if (!preg_match('/^(\w+)\.(.*)$/', $category, $out)) { error_log('Requested category icon for invalid category "' . $category . '"'); return ''; @@ -105,12 +102,12 @@ class Dashboard return 'glyphicon glyphicon-' . self::$iconCache[$module][$icon]; } - public static function addSubmenu($url, $name) + public static function addSubmenu(string $url, string $name): void { self::$subMenu[] = array('url' => $url, 'name' => $name); } - public static function getSubmenus() + public static function getSubmenus(): array { return self::$subMenu; } diff --git a/inc/database.inc.php b/inc/database.inc.php index 0c8f40ae..7805b508 100644 --- a/inc/database.inc.php +++ b/inc/database.inc.php @@ -12,8 +12,10 @@ class Database */ private static $dbh = false; - private static $returnErrors; - private static $lastError = false; + /** @var bool */ + private static $returnErrors = false; + /** @var ?string */ + private static $lastError = null; private static $explainList = array(); private static $queryCount = 0; /** @var float */ @@ -165,9 +167,9 @@ class Database } /** - * @return string|false return last error returned by query + * @return ?string return last error returned by query */ - public static function lastError() + public static function lastError(): ?string { return self::$lastError; } @@ -183,7 +185,7 @@ class Database public static function simpleQuery(string $query, array $args = [], bool $ignoreError = null) { self::init(); - if (CONFIG_DEBUG && !isset(self::$explainList[$query]) && preg_match('/^\s*SELECT/is', $query)) { + if (CONFIG_DEBUG && !isset(self::$explainList[$query]) && preg_match('/^\s*SELECT/i', $query)) { self::$explainList[$query] = [$args]; } // Support passing nested arrays for IN statements, automagically refactor @@ -225,7 +227,6 @@ class Database return false; ErrorHandler::traceError("Database Error: \n" . self::$lastError); } - return false; } public static function examineLoggedQueries() diff --git a/inc/dictionary.inc.php b/inc/dictionary.inc.php index 4c98c63b..ee613d0b 100644 --- a/inc/dictionary.inc.php +++ b/inc/dictionary.inc.php @@ -6,16 +6,15 @@ class Dictionary /** * @var string[] Array of languages, numeric index, two letter CC as values */ - private static $languages = false; + private static $languages = []; /** - * @var array Array of languages, numeric index, values are ['name' => 'Language Name', 'cc' => 'xx'] + * @var array{'name': string, 'cc': string}|null Long name of language, and CC */ - private static $languagesLong = false; - private static $stringCache = array(); + private static $languagesLong = null; + private static $stringCache = []; - public static function init() + public static function init(): void { - self::$languages = array(); foreach (glob('lang/??', GLOB_ONLYDIR) as $lang) { if (!file_exists($lang . '/name.txt') && !file_exists($lang . '/flag.png')) continue; @@ -93,25 +92,25 @@ class Dictionary * * @param string $module Module name * @param string $file Dictionary name - * @param string|false $lang Language CC, false === current language + * @param ?string $lang Language CC, false === current language * @return array assoc array mapping language tags to the translated strings */ - public static function getArray($module, $file, $lang = false) + public static function getArray(string $module, string $file, ?string $lang = null): array { - if ($lang === false) + if ($lang === null) $lang = LANG; $path = Util::safePath("modules/{$module}/lang/{$lang}/{$file}.json"); if (isset(self::$stringCache[$path])) return self::$stringCache[$path]; if (!file_exists($path)) - return array(); + return []; $content = file_get_contents($path); if ($content === false) { // File does not exist for language $content = '[]'; } $json = json_decode($content, true); if (!is_array($json)) { - $json = array(); + $json = []; } return self::$stringCache[$path] = $json; } @@ -126,7 +125,7 @@ class Dictionary * @param bool $returnTagOnMissing If true, the tag name enclosed in {{}} will be returned if the tag does not exist * @return string|false The requested tag's translation, or false if not found and $returnTagOnMissing === false */ - public static function translateFileModule($moduleId, $file, $tag, $returnTagOnMissing = false) + public static function translateFileModule(string $moduleId, string $file, string $tag, bool $returnTagOnMissing = true) { $strings = self::getArray($moduleId, $file); if (!isset($strings[$tag])) { @@ -146,7 +145,7 @@ class Dictionary * @param bool $returnTagOnMissing If true, the tag name enclosed in {{}} will be returned if the tag does not exist * @return string|false The requested tag's translation, or false if not found and $returnTagOnMissing === false */ - public static function translateFile($file, $tag, $returnTagOnMissing = false) + public static function translateFile(string $file, string $tag, bool $returnTagOnMissing = true) { if (!class_exists('Page') || Page::getModule() === false) return false; // We have no page - return false for now, as we're most likely running in api or install mode @@ -160,9 +159,9 @@ class Dictionary * @param bool $returnTagOnMissing If true, the tag name enclosed in {{}} will be returned if the tag does not exist * @return string|false The requested tag's translation, or false if not found and $returnTagOnMissing === false */ - public static function translate($tag, $returnTagOnMissing = false) + public static function translate(string $tag, bool $returnTagOnMissing = true) { - $string = self::translateFile('module', $tag); + $string = self::translateFile('module', $tag, false); if ($string !== false) return $string; $string = self::translateFileModule('main', 'global-tags', $tag); @@ -176,9 +175,8 @@ class Dictionary * * @param string $module Module the message belongs to * @param string $id Message id - * @return string|false */ - public static function getMessage($module, $id) + public static function getMessage(string $module, string $id): string { $string = self::translateFileModule($module, 'messages', $id); if ($string === false) { @@ -190,19 +188,18 @@ class Dictionary /** * Get translation of the given category. * - * @param string $category + * @param string $category Menu category to get localized name for * @return string Category name, or some generic fallback to the given category id */ - public static function getCategoryName($category) + public static function getCategoryName(string $category): string { - if ($category === false) { - return 'No Category'; - } - if (!preg_match('/^(\w+)\.(.*)$/', $category, $out)) { - return 'Invalid Category ID format: ' . $category; + if (!empty($category)) { + if (!preg_match('/^(\w+)\.(.*)$/', $category, $out)) { + return 'Invalid Category ID format: ' . $category; + } + $string = self::translateFileModule($out[1], 'categories', $out[2]); } - $string = self::translateFileModule($out[1], 'categories', $out[2]); - if ($string === false) { + if (empty($category) || $string === false) { return "!!{$category}!!"; } return $string; @@ -215,12 +212,12 @@ class Dictionary * false = regular array containing only the ccs * @return array List of languages */ - public static function getLanguages($withName = false) + public static function getLanguages(bool $withName = false): ?array { if (!$withName) return self::$languages; - if (self::$languagesLong === false) { - self::$languagesLong = array(); + if (self::$languagesLong === null) { + self::$languagesLong = []; foreach (self::$languages as $lang) { if (file_exists("lang/$lang/name.txt")) { $name = file_get_contents("lang/$lang/name.txt"); @@ -230,10 +227,10 @@ class Dictionary if (!isset($name) || $name === false) { $name = $lang; } - self::$languagesLong[] = array( + self::$languagesLong[] = [ 'cc' => $lang, - 'name' => $name - ); + 'name' => $name, + ]; } } return self::$languagesLong; @@ -242,11 +239,8 @@ class Dictionary /** * Get name of language matching given language CC. * Default to the CC if the language isn't known. - * - * @param string $langCC - * @return string */ - public static function getLanguageName($langCC) + public static function getLanguageName(string $langCC): string { if (file_exists("lang/$langCC/name.txt")) { $name = file_get_contents("lang/$langCC/name.txt"); @@ -264,12 +258,12 @@ class Dictionary * to the image, otherwise, it is just added as the title attribute. * * @param $caption bool with caption next to - * @param $langCC string Language cc to get flag code for - defaults to current language + * @param $langCC ?string Language cc to get flag code for - defaults to current language * @return string html code of img tag for language */ - public static function getFlagHtml($caption = false, $langCC = false) + public static function getFlagHtml(bool $caption = false, string $langCC = null): string { - if ($langCC === false) { + if ($langCC === null) { $langCC = LANG; } $flag = "lang/$langCC/flag.png"; diff --git a/inc/download.inc.php b/inc/download.inc.php index 10eac188..49ebbfbc 100644 --- a/inc/download.inc.php +++ b/inc/download.inc.php @@ -24,7 +24,6 @@ class Download curl_setopt(self::$curlHandle, CURLOPT_TIMEOUT, $timeout); curl_setopt(self::$curlHandle, CURLOPT_FOLLOWLOCATION, true); curl_setopt(self::$curlHandle, CURLOPT_AUTOREFERER, true); - curl_setopt(self::$curlHandle, CURLOPT_BINARYTRANSFER, true); curl_setopt(self::$curlHandle, CURLOPT_MAXREDIRS, 6); } @@ -37,7 +36,7 @@ class Download * Download file, obey given timeout in seconds * Return data on success, false on failure */ - public static function asString(string $url, int $timeout, &$code) + public static function asString(string $url, int $timeout, ?int &$code) { $ch = self::initCurl($url, $timeout); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); @@ -52,9 +51,10 @@ class Download * @param string $url URL to fetch * @param array|false $params POST params to set in body, list of key-value-pairs * @param int $timeout timeout in seconds - * @param int $code HTTP response code, or 999 on error + * @param ?int $code HTTP response code, or 999 on error + * @return string|false */ - public static function asStringPost(string $url, $params, int $timeout, &$code) + public static function asStringPost(string $url, $params, int $timeout, ?int &$code) { $string = ''; if (is_array($params)) { @@ -80,10 +80,9 @@ class Download * @param string $target destination path to download file to * @param string $url URL of file to download * @param int $timeout timeout in seconds - * @param int $code HTTP status code passed out by reference - * @return boolean + * @param ?int $code HTTP status code passed out by reference */ - public static function toFile(string $target, string $url, int $timeout, &$code): bool + public static function toFile(string $target, string $url, int $timeout, ?int &$code): bool { $fh = fopen($target, 'wb'); if ($fh === false) diff --git a/inc/errorhandler.inc.php b/inc/errorhandler.inc.php index c7a32b02..8e49353c 100644 --- a/inc/errorhandler.inc.php +++ b/inc/errorhandler.inc.php @@ -1,5 +1,7 @@ $line) { @@ -104,7 +107,7 @@ SADFACE; return $output; } - public static function formatBacktracePlain($trace): string + public static function formatBacktracePlain(array $trace): string { $output = ''; foreach ($trace as $idx => $line) { @@ -121,7 +124,7 @@ SADFACE; return $output; } - private static function formatArgument($arg, $expandArray = true) + private static function formatArgument($arg, bool $expandArray = true): string { if (is_string($arg)) { $arg = "'$arg'"; diff --git a/inc/event.inc.php b/inc/event.inc.php index e622f74f..db5bf1f1 100644 --- a/inc/event.inc.php +++ b/inc/event.inc.php @@ -15,7 +15,7 @@ class Event * Called when the system (re)booted. Could be implemented * by a @reboot entry in crontab (running as the same user php does) */ - public static function systemBooted() + public static function systemBooted(): void { EventLog::info('System boot...'); $everythingFine = true; @@ -96,7 +96,7 @@ class Event /** * Server's primary IP address changed. */ - public static function serverIpChanged() + public static function serverIpChanged(): void { Trigger::ipxe(); if (Module::isAvailable('sysconfig')) { // TODO: Modularize events diff --git a/inc/fileutil.inc.php b/inc/fileutil.inc.php index f35f987e..86a5ebc5 100644 --- a/inc/fileutil.inc.php +++ b/inc/fileutil.inc.php @@ -8,9 +8,9 @@ class FileUtil * * @param string $file file to read * @param int $maxBytes maximum length to read - * @return boolean|string data, false on error + * @return false|string data, false on error */ - public static function readFile($file, $maxBytes = 1000) + public static function readFile(string $file, int $maxBytes = 1000) { $fh = @fopen($file, 'rb'); if ($fh === false) @@ -19,18 +19,18 @@ class FileUtil fclose($fh); return $data; } - + /** * Read a file of key=value lines to assoc array. * * @param string $file Filename - * @return boolean|array assoc array, false on error + * @return ?array assoc array, null on error */ - public static function fileToArray($file) + public static function fileToArray(string $file): ?array { $data = self::readFile($file, 2000); if ($data === false) - return false; + return null; $data = explode("\n", str_replace("\r", "\n", $data)); $ret = array(); foreach ($data as $line) { @@ -40,7 +40,7 @@ class FileUtil } return $ret; } - + /** * Write given associative array to file as key=value pairs. * @@ -48,7 +48,7 @@ class FileUtil * @param array $array Associative array to write * @return boolean success of operation */ - public static function arrayToFile($file, $array) + public static function arrayToFile(string $file, array $array): bool { $fh = fopen($file, 'wb'); if ($fh === false) diff --git a/inc/hook.inc.php b/inc/hook.inc.php index f74281f1..abeac68e 100644 --- a/inc/hook.inc.php +++ b/inc/hook.inc.php @@ -14,7 +14,7 @@ class Hook * * @param string $hookName Name of hook to search for. * @param bool $filterBroken if true, modules that have a hook but have missing deps will not be returned - * @return \Hook[] list of modules with requested hooks + * @return Hook[] list of modules with requested hooks */ public static function load(string $hookName, bool $filterBroken = true): array { @@ -34,17 +34,17 @@ class Hook * @param string $moduleName Module * @param string $hookName Hook * @param bool $filterBroken return false if the module has missing deps - * @return Hook|false hook instance, false on error or if module doesn't have given hook + * @return ?Hook hook instance, false on error or if module doesn't have given hook */ - public static function loadSingle(string $moduleName, string $hookName, bool $filterBroken = true) + public static function loadSingle(string $moduleName, string $hookName, bool $filterBroken = true): ?Hook { if (Module::get($moduleName) === false) // No such module - return false; + return null; if ($filterBroken && !Module::isAvailable($moduleName)) // Broken - return false; + return null; $file = 'modules/' . $moduleName . '/hooks/' . $hookName . '.inc.php'; if (!file_exists($file)) // No hook - return false; + return null; return new Hook($moduleName, $file); } diff --git a/inc/iputil.inc.php b/inc/iputil.inc.php index 69311d7f..ecd8c198 100644 --- a/inc/iputil.inc.php +++ b/inc/iputil.inc.php @@ -3,38 +3,39 @@ class IpUtil { - public static function rangeToCidr($start, $end) + public static function rangeToCidr(int $start, int $end): string { - $value = (int)$start ^ (int)$end; + $value = $start ^ $end; if (!self::isAllOnes($value)) return 'NOT SUBNET: ' . long2ip($start) . '-' . long2ip($end); - $ones = self::countOnes($value); + $ones = self::bitLength($value); return long2ip($start) . '/' . (32 - $ones); } - public static function isValidSubnetRange($start, $end) + public static function isValidSubnetRange(int $start, int $end): bool { - return self::isAllOnes((int)$start ^ (int)$end); + return self::isAllOnes($start ^ $end); } /** - * Return number of one bits required to represent - * this number. Assumes given number is 2^n - 1. + * Return number of bits required to represent + * this number. + * !! Assumes given number is 2^n - 1 !! */ - private static function countOnes($value) + private static function bitLength(int $value): int { // This is log(value) / log(2) // It should actually be $value + 1, but floating point errors // start to happen either way at higher values, so with // the round() thrown in, it doesn't matter... - return round(log($value) / 0.69314718055995); + return (int)round(log($value) / 0.69314718055995); } /** * Is the given number just ones if converted to * binary (ignoring leading zeros)? */ - private static function isAllOnes($value) + private static function isAllOnes(int $value): bool { return ($value & ($value + 1)) === 0; } @@ -44,16 +45,17 @@ class IpUtil * ['start' => (int), 'end' => (int)] representing * the according start and end addresses as integer * values. Returns false on malformed input. + * * @param string $cidr 192.168.101/24, 1.2.3.4/16, ... - * @return array|false start and end address, false on error + * @return array{start: int, end: int}|null start and end address, false on error */ - public static function parseCidr($cidr) + public static function parseCidr(string $cidr): ?array { $parts = explode('/', $cidr); if (count($parts) !== 2) { $ip = ip2long($cidr); if ($ip === false) - return false; + return null; if (PHP_INT_SIZE === 4) { $ip = sprintf('%u', $ip); } @@ -62,15 +64,15 @@ class IpUtil $ip = $parts[0]; $bits = $parts[1]; if (!is_numeric($bits) || $bits < 0 || $bits > 32) - return false; + return null; $dots = substr_count($ip, '.'); if ($dots < 3) { $ip .= str_repeat('.0', 3 - $dots); } $ip = ip2long($ip); if ($ip === false) - return false; - $bits = pow(2, 32 - $bits) - 1; + return null; + $bits = (int)((2 ** (32 - $bits)) - 1); if (PHP_INT_SIZE === 4) return ['start' => sprintf('%u', $ip & ~$bits), 'end' => sprintf('%u', $ip | $bits)]; return ['start' => $ip & ~$bits, 'end' => $ip | $bits]; diff --git a/inc/mailer.inc.php b/inc/mailer.inc.php index 1545e930..b2fb7741 100644 --- a/inc/mailer.inc.php +++ b/inc/mailer.inc.php @@ -93,7 +93,7 @@ class Mailer return preg_replace('/^\* Expire in \d+ ms for.*[\\r\\n]+(?=\* Expire)/m','$1', $this->errlog); } - public static function queue(int $configid, array $rcpts, string $subject, string $text) + public static function queue(int $configid, array $rcpts, string $subject, string $text): void { foreach ($rcpts as $rcpt) { Database::exec("INSERT INTO mail_queue (rcpt, subject, body, dateline, configid) @@ -102,7 +102,7 @@ class Mailer } } - public static function flushQueue() + public static function flushQueue(): void { $list = Database::queryGroupList("SELECT Concat(configid, rcpt, subject) AS keyval, mailid, configid, rcpt, subject, body, dateline FROM mail_queue @@ -167,19 +167,15 @@ class Mailer return self::$configs[$configId] ?? []; } - /** - * @param int $configId - * @return Mailer|null - */ - public static function instanceFromConfig(int $configId) + public static function instanceFromConfig(int $configId): ?Mailer { $config = self::getConfig($configId); if (empty($config)) return null; if ($config['ssl'] === 'IMPLICIT') { - $uri = "smtps://{$config['host']}:${config['port']}"; + $uri = "smtps://{$config['host']}:{$config['port']}"; } else { - $uri = "smtp://{$config['host']}:${config['port']}"; + $uri = "smtp://{$config['host']}:{$config['port']}"; } return new Mailer($uri, $config['ssl'] === 'EXPLICIT', $config['senderaddress'], $config['username'], $config['password'], $config['replyto']); diff --git a/inc/message.inc.php b/inc/message.inc.php index 9197e4c2..482e4ba4 100644 --- a/inc/message.inc.php +++ b/inc/message.inc.php @@ -11,40 +11,39 @@ class Message * yet, it will be added to the queue, otherwise it will be added * in place during rendering. */ - public static function addError($id) + public static function addError(string $id, ...$params): void { - self::add('danger', $id, func_get_args()); + self::add('danger', $id, $params); } - public static function addWarning($id) + public static function addWarning(string $id, ...$params): void { - self::add('warning', $id, func_get_args()); + self::add('warning', $id, $params); } - public static function addInfo($id) + public static function addInfo(string $id, ...$params): void { - self::add('info', $id, func_get_args()); + self::add('info', $id, $params); } - public static function addSuccess($id) + public static function addSuccess(string $id, ...$params): void { - self::add('success', $id, func_get_args()); + self::add('success', $id, $params); } /** * Internal function that adds a message. Used by * addError/Success/Info/... above. */ - private static function add($type, $id, $params) + private static function add(string $type, string $id, array $params): void { if (strstr($id, '.') === false) { $id = Page::getModule()->getIdentifier() . '.' . $id; } - if (count($params) > 1 && $params[1] === true) { - $params = array_slice($params, 2); + if (!empty($params) && $params[0] === true) { + $params = array_slice($params, 1); $linkModule = true; } else { - $params = array_slice($params, 1); $linkModule = false; } switch ($type) { @@ -70,7 +69,9 @@ class Message 'params' => $params, 'link' => $linkModule ); - if (self::$flushed) self::renderList(); + if (self::$flushed) { + self::renderList(); + } } /** @@ -78,7 +79,7 @@ class Message * After calling this, any further calls to add* will be rendered in * place in the current page output. */ - public static function renderList() + public static function renderList(): void { self::$flushed = true; if (empty(self::$list)) @@ -122,7 +123,7 @@ class Message * Get all queued messages, flushing the queue. * Useful in api/ajax mode. */ - public static function asString() + public static function asString(): string { $return = ''; foreach (self::$list as $item) { @@ -145,7 +146,7 @@ class Message * Deserialize any messages from the current HTTP request and * place them in the message queue. */ - public static function fromRequest() + public static function fromRequest(): void { $messages = is_array($_REQUEST['message']) ? $_REQUEST['message'] : array($_REQUEST['message']); foreach ($messages as $message) { @@ -163,7 +164,7 @@ class Message * Turn the current message queue into a serialized version, * suitable for appending to a GET or POST request */ - public static function toRequest() + public static function toRequest(): string { $parts = array(); foreach (array_merge(self::$list, self::$alreadyDisplayed) as $item) { diff --git a/inc/module.inc.php b/inc/module.inc.php index 042ea0c0..115c9e9a 100644 --- a/inc/module.inc.php +++ b/inc/module.inc.php @@ -7,16 +7,16 @@ class Module */ /** - * @var \Module[] + * @var ?Module[] */ - private static $modules = false; + private static $modules = null; /** * @param string $name ID/Internal name of module - * @param false $ignoreDepFail whether to return the module even if some of its dependencies failed + * @param bool $ignoreDepFail whether to return the module even if some of its dependencies failed * @return false|Module */ - public static function get($name, $ignoreDepFail = false) + public static function get(string $name, bool $ignoreDepFail = false) { if (!isset(self::$modules[$name])) return false; @@ -28,13 +28,13 @@ class Module /** * Check whether given module is available, that is, all dependencies are * met. If the module is available, it will be activated, so all its classes - * are available through the auto-loader, and any js or css is added to the + * are available through the autoloader, and any js or css is added to the * final page output. * * @param string $moduleId module to check * @return bool true if module is available and activated */ - public static function isAvailable($moduleId, $activate = true) + public static function isAvailable(string $moduleId, bool $activate = true): bool { $module = self::get($moduleId); if ($module === false) @@ -45,7 +45,7 @@ class Module return !$module->hasMissingDependencies(); } - private static function resolveDepsByName($name) + private static function resolveDepsByName(string $name): bool { if (!isset(self::$modules[$name])) return false; @@ -57,7 +57,7 @@ class Module * @param \Module $mod the module to check * @return boolean true iff module deps are all found and enabled */ - private static function resolveDeps($mod) + private static function resolveDeps(Module $mod): bool { if (!$mod->depsChecked) { $mod->depsChecked = true; @@ -75,7 +75,7 @@ class Module /** * @return \Module[] List of valid, enabled modules */ - public static function getEnabled($sortById = false) + public static function getEnabled(bool $sortById = false): array { $ret = array(); $sort = array(); @@ -96,7 +96,7 @@ class Module /** * @return \Module[] List of all modules, including with missing deps */ - public static function getAll() + public static function getAll(): array { foreach (self::$modules as $module) { self::resolveDeps($module); @@ -107,7 +107,7 @@ class Module /** * @return \Module[] List of modules that have been activated */ - public static function getActivated() + public static function getActivated(): array { $ret = array(); $i = 0; @@ -120,9 +120,9 @@ class Module return $ret; } - public static function init() + public static function init(): void { - if (self::$modules !== false) + if (self::$modules !== null) return; $dh = opendir('modules'); if ($dh === false) @@ -143,7 +143,8 @@ class Module * Non-static */ - private $category = false; + /** @var ?string category id */ + private $category = null; private $clientPlugin = false; private $depsMissing = false; private $depsChecked = false; @@ -161,7 +162,7 @@ class Module */ private $scripts = array(); - private function __construct($name) + private function __construct(string $name) { $file = 'modules/' . $name . '/config.json'; $json = @json_decode(@file_get_contents($file), true); @@ -180,12 +181,12 @@ class Module $this->name = $name; } - public function hasMissingDependencies() + public function hasMissingDependencies(): bool { return $this->depsMissing; } - public function newPage() + public function newPage(): Page { $modulePath = 'modules/' . $this->name . '/page.inc.php'; if (!file_exists($modulePath)) { @@ -196,7 +197,7 @@ class Module return new $class(); } - public function activate($depth, $direct) + public function activate(?int $depth, ?bool $direct): bool { if ($this->depsMissing) return false; @@ -228,14 +229,14 @@ class Module return true; } - public function getDependencies() + public function getDependencies(): array { $deps = array(); $this->getDepsInternal($deps); return array_keys($deps); } - private function getDepsInternal(&$deps) + private function getDepsInternal(array &$deps): void { if (!is_array($this->dependencies)) return; @@ -250,49 +251,49 @@ class Module } } - public function getIdentifier() + public function getIdentifier(): string { return $this->name; } - public function getDisplayName() + public function getDisplayName(): string { - $string = Dictionary::translateFileModule($this->name, 'module', 'module_name'); + $string = Dictionary::translateFileModule($this->name, 'module', 'module_name', false); if ($string === false) { return '!!' . $this->name . '!!'; } return $string; } - public function getPageTitle() + public function getPageTitle(): string { - $val = Dictionary::translateFileModule($this->name, 'module', 'page_title'); + $val = Dictionary::translateFileModule($this->name, 'module', 'page_title', false); if ($val !== false) return $val; return $this->getDisplayName(); } - public function getCategory() + public function getCategory(): ?string { return $this->category; } - public function getCategoryName() + public function getCategoryName(): string { return Dictionary::getCategoryName($this->category); } - public function doCollapse() + public function doCollapse(): bool { return $this->collapse; } - public function getDir() + public function getDir(): string { return 'modules/' . $this->name; } - public function getScripts() + public function getScripts(): array { if ($this->directActivation && $this->clientPlugin) { if (!in_array('clientscript.js', $this->scripts) && file_exists($this->getDir() . '/clientscript.js')) { @@ -303,7 +304,7 @@ class Module return []; } - public function getCss() + public function getCss(): array { if ($this->directActivation && $this->clientPlugin) { if (!in_array('style.css', $this->css) && file_exists($this->getDir() . '/style.css')) { diff --git a/inc/paginate.inc.php b/inc/paginate.inc.php index 3187261c..b9a1ed78 100644 --- a/inc/paginate.inc.php +++ b/inc/paginate.inc.php @@ -9,15 +9,14 @@ class Paginate private $totalRows = false; /** - * @query - The query that will return lines to show - * @currentPage - 0based index of currently viewed page - * @perPage - Number of items to show per page - * @url - URL of current wegpage + * @param string $query - The query that will return lines to show + * @param int $perPage - Number of items to show per page + * @param ?string $url - URL of current wegpage */ - public function __construct($query, $perPage, $url = false) + public function __construct(string $query, int $perPage, string $url = null) { $this->currentPage = (isset($_GET['page']) ? (int)$_GET['page'] : 0); - $this->perPage = (int)$perPage; + $this->perPage = $perPage; if ($this->currentPage < 0) { ErrorHandler::traceError('Current page < 0'); } @@ -25,17 +24,17 @@ class Paginate ErrorHandler::traceError('Per page < 1'); } // Query - if (!preg_match('/\s*SELECT\s/is', $query)) { + if (!preg_match('/\s*SELECT\s/i', $query)) { ErrorHandler::traceError('Query has to start with SELECT!'); } // XXX: MySQL only - if (preg_match('/^mysql/i', CONFIG_SQL_DSN)) { + if (preg_match('/^(mysql|mariadb)/i', CONFIG_SQL_DSN)) { // Sanity: Check for LIMIT specification at the end if (preg_match('/LIMIT\s+(\d+|\:\w+|\?)\s*,\s*(\d+|\:\w+|\?)(\s|;)*(\-\-.*)?$/is', $query)) { ErrorHandler::traceError("You cannot pass a query containing a LIMIT to the Paginator class!"); } // Sanity: no comment or semi-colon at end (sloppy, might lead to false negatives) - if (preg_match('/(\-\-|;)(\s|[^\'"`])*$/is', $query)) { + if (preg_match('/(\-\-|;)(\s|[^\'"`])*$/i', $query)) { ErrorHandler::traceError("Your query must not end in a comment or semi-colon!"); } // Don't use SQL_CALC_FOUND_ROWS as it leads to filesort frequently thus being slower than two queries @@ -45,7 +44,9 @@ class Paginate ErrorHandler::traceError('Unsupported database engine'); } // Mangle URL - if ($url === false) $url = $_SERVER['REQUEST_URI']; + if ($url === null) { + $url = $_SERVER['REQUEST_URI']; + } if (strpos($url, '?') === false) { $url .= '?'; } else { @@ -60,7 +61,7 @@ class Paginate /** * Execute the query, returning the PDO query object */ - public function exec($args = array()) + public function exec(array $args = []) { $countQuery = preg_replace('/ORDER\s+BY\s.*?(\sASC|\sDESC|$)/is', '', $this->query); $countQuery = preg_replace('/SELECT\s.*?\sFROM\s/is', 'SELECT Count(*) AS rowcount FROM ', $countQuery); @@ -71,7 +72,7 @@ class Paginate return $retval; } - public function render($template, $data) + public function render(string $template, array $data): void { if ($this->totalRows == 0) { // Shortcut for no content diff --git a/inc/permission.inc.php b/inc/permission.inc.php index abeabb1d..798f9350 100644 --- a/inc/permission.inc.php +++ b/inc/permission.inc.php @@ -9,7 +9,7 @@ class Permission 'translation' => 8, // Can edit translations ); - public static function get($permission) + public static function get(string $permission): int { if (!isset(self::$permissions[$permission])) ErrorHandler::traceError('Invalid permission: ' . $permission); return self::$permissions[$permission]; @@ -17,10 +17,13 @@ class Permission // TODO: Doc/Refactor - public static function addGlobalTags(&$array, $locationid, $disabled, $noneAvailDisabled = null) + public static function addGlobalTags(?array &$array, ?int $locationid, array $disabled, ?string $noneAvailDisabled = null): void { if (Module::get('permissionmanager') === false) return; + if ($array === null) { + $array = []; + } $one = false; foreach ($disabled as $perm) { if (User::hasPermission($perm, $locationid)) { @@ -47,7 +50,7 @@ class Permission } } - public static function moduleHasPermissions($moduleId) + public static function moduleHasPermissions(string $moduleId): bool { if (Module::get('permissionmanager') === false) return true; @@ -58,13 +61,8 @@ class Permission * Takes a list of locations, removes any locations from it where the user doesn't have permission, * and then re-adds locations resulting from the given query. The given query should return only * one column per row, which is a location id. - * @param $passedLocations - * @param $permission - * @param $query - * @param $params - * @return array */ - public static function mergeWithDisallowed($passedLocations, $permission, $query, $params) + public static function mergeWithDisallowed(array $passedLocations, string $permission, string $query, array $params): array { $allowed = User::getAllowedLocations($permission); if (in_array(0, $allowed)) diff --git a/inc/property.inc.php b/inc/property.inc.php index dd72c187..5efcfe3a 100644 --- a/inc/property.inc.php +++ b/inc/property.inc.php @@ -41,7 +41,7 @@ class Property * @param string|null|false $value the value to store for $key * @param int $maxAgeMinutes how long to keep this entry around at least, in minutes. 0 for infinite */ - public static function set(string $key, $value, int $maxAgeMinutes = 0) + public static function set(string $key, $value, int $maxAgeMinutes = 0): void { if ($value === false || $value === null) { Database::exec("DELETE FROM property WHERE name = :key", ['key' => $key]); @@ -82,11 +82,9 @@ class Property } /** - * @param string $key - * @param int $subkey * @return ?string entry from property list */ - public static function getListEntry(string $key, int $subkey) + public static function getListEntry(string $key, int $subkey): ?string { $row = Database::queryFirst("SELECT dateline, `value` FROM property_list WHERE `name` = :key AND subkey = :subkey", ['key' => $key, 'subkey' => $subkey]); @@ -188,12 +186,12 @@ class Property * Legacy getters/setters */ - public static function getServerIp() + public static function getServerIp(): string { - return self::get('server-ip', 'none'); + return self::get('server-ip', 'invalid'); } - public static function setServerIp(string $value, $automatic = false): bool + public static function setServerIp(string $value, bool $automatic = false): bool { if ($value === self::getServerIp()) return false; @@ -203,16 +201,6 @@ class Property return true; } - public static function getBootMenu() - { - return json_decode(self::get('ipxe-menu'), true); - } - - public static function setBootMenu($value) - { - self::set('ipxe-menu', json_encode($value)); - } - public static function getVmStoreConfig() { return json_decode(self::get('vmstore-config'), true); @@ -247,14 +235,14 @@ class Property return self::get('last-warn-event-id', 0); } - public static function setNeedsSetup($value) + public static function setNeedsSetup(bool $value) { - self::set('needs-setup', $value); + self::set('needs-setup', (int)$value); } - public static function getNeedsSetup() + public static function getNeedsSetup(): bool { - return self::get('needs-setup'); + return self::get('needs-setup') != 0; } public static function setPasswordFieldType(string $value) diff --git a/inc/render.inc.php b/inc/render.inc.php index 697646c5..68a0cd19 100644 --- a/inc/render.inc.php +++ b/inc/render.inc.php @@ -14,20 +14,21 @@ class Render { /** - * @var Mustache_Engine + * @var ?Mustache_Engine */ - private static $mustache = false; + private static $mustache = null; private static $body = ''; private static $header = ''; - private static $dashboard = false; + /** @var ?array */ + private static $dashboard = null; private static $footer = ''; private static $title = ''; private static $templateCache = array(); private static $tags = array(); - public static function init() + public static function init(): void { - if (self::$mustache !== false) + if (self::$mustache !== null) ErrorHandler::traceError('Called Render::init() twice!'); $options = array(); $tmp = '/tmp/bwlp-cache'; @@ -41,7 +42,7 @@ class Render self::$mustache = new Mustache_Engine($options); } - private static function cssEsc($str) + private static function cssEsc(string $str): string { return str_replace(array('"', '&', '<', '>'), array('\\000022', '\\000026', '\\00003c', '\\00003e'), $str); } @@ -49,12 +50,10 @@ class Render /** * Output the buffered, generated page */ - public static function output() + public static function output(): void { Header('Content-Type: text/html; charset=utf-8'); - /* @var $modules Module[] */ $modules = array_reverse(Module::getActivated()); - $pageModule = Page::getModule(); $title = Property::get('page-title-prefix', ''); $bgcolor = Property::get('logo-background', ''); if (!empty($bgcolor) || !empty($title)) { @@ -99,7 +98,7 @@ class Render ' ', - (self::$dashboard !== false ? self::parse('main-menu', self::$dashboard, 'main') : ''), + (self::$dashboard !== null ? self::parse('main-menu', self::$dashboard, 'main') : ''), '
', self::$body @@ -128,7 +127,7 @@ class Render /** * Set the page title (title-tag) */ - public static function setTitle($title, $override = true) + public static function setTitle(string $title, bool $override = true): void { if (!$override && !empty(self::$title)) return; @@ -138,7 +137,7 @@ class Render /** * Add raw html data to the header-section of the generated page */ - public static function addHeader($html) + public static function addHeader(string $html): void { self::$header .= $html . "\n"; } @@ -146,7 +145,7 @@ class Render /** * Add raw html data to the footer-section of the generated page (right before the closing body tag) */ - public static function addFooter($html) + public static function addFooter(string $html): void { self::$footer .= $html . "\n"; } @@ -154,7 +153,7 @@ class Render /** * Add the given template to the output, using the given params for placeholders in the template */ - public static function addTemplate($template, $params = false, $module = false) + public static function addTemplate(string $template, array $params = [], ?string $module = null) { self::$body .= self::parse($template, $params, $module); } @@ -167,7 +166,7 @@ class Render * @param string $template template used to fill the dialog body * @param array $params parameters for rendering the body template */ - public static function addDialog($title, $next, $template, $params = false) + public static function addDialog(string $title, bool $next, string $template, array $params = []): void { self::addTemplate('dialog-generic', array( 'title' => $title, @@ -179,7 +178,7 @@ class Render /** * Add error message to page */ - public static function addError($message) + public static function addError($message): void { self::addTemplate('messagebox-error', array('message' => $message)); } @@ -191,9 +190,9 @@ class Render * @param string $module name of module to load template from; defaults to currently active module * @return string Rendered template */ - public static function parse($template, $params = false, $module = false, $lang = false) + public static function parse(string $template, array $params = [], ?string $module = null, ?string $lang = null): string { - if ($module === false && class_exists('Page')) { + if ($module === null && class_exists('Page', false)) { $module = Page::getModule()->getIdentifier(); } // Load html snippet @@ -201,9 +200,6 @@ class Render if ($html === false) { return '

Template ' . htmlspecialchars($template) . '

' . nl2br(htmlspecialchars(print_r($params, true))) . '
'; } - if (!is_array($params)) { - $params = array(); - } // Now find all language tags in this array if (preg_match_all('/{{\s*(lang_.+?)\s*}}/', $html, $out) > 0) { $dictionary = Dictionary::getArray($module, 'template-tags', $lang); @@ -211,14 +207,14 @@ class Render foreach ($out[1] as $tag) { if ($fallback === false && empty($dictionary[$tag])) { $fallback = true; // Fallback to general dictionary of main module - $dictionary = $dictionary + Dictionary::getArray('main', 'global-tags'); + $dictionary += Dictionary::getArray('main', 'global-tags'); } // Add untranslated strings to the dictionary, so their tag is seen in the rendered page if (empty($dictionary[$tag])) { $dictionary[$tag] = '{{' . $tag . '}}'; } } - $params = $params + $dictionary; + $params += $dictionary; } // Always add token to parameter list $params['token'] = Session::get('token'); @@ -244,7 +240,7 @@ class Render */ public static function openTag($tag, $params = false) { - array_push(self::$tags, $tag); + self::$tags[] = $tag; if (!is_array($params)) { self::$body .= '<' . $tag . '>'; } else { @@ -271,8 +267,9 @@ class Render /** * Private helper: Load the given template and return it + * @return false|string */ - private static function getTemplate($template, $module) + private static function getTemplate(string $template, string $module) { $id = "$template/$module"; if (isset(self::$templateCache[$id])) { @@ -287,12 +284,13 @@ class Render /** * Create the dashboard menu */ - public static function setDashboard($params) + public static function setDashboard(array $params): void { self::$dashboard = $params; } - public static function readableColor($hex) { + public static function readableColor(string $hex): string + { if (strlen($hex) <= 4) { $cnt = 1; } else { diff --git a/inc/request.inc.php b/inc/request.inc.php index 7cf4a73f..c499a9d9 100644 --- a/inc/request.inc.php +++ b/inc/request.inc.php @@ -53,7 +53,7 @@ class Request /** * @return true iff the request is a POST request */ - public static function isPost() + public static function isPost(): bool { return $_SERVER['REQUEST_METHOD'] === 'POST'; } @@ -61,7 +61,7 @@ class Request /** * @return true iff the request is a GET request */ - public static function isGet() + public static function isGet(): bool { return $_SERVER['REQUEST_METHOD'] === 'GET'; } diff --git a/inc/session.inc.php b/inc/session.inc.php index 1c20c8a6..622eb320 100644 --- a/inc/session.inc.php +++ b/inc/session.inc.php @@ -10,7 +10,7 @@ class Session private static $userId = 0; private static $updateSessionDateline = false; - private static function generateSessionId(string $salt) + private static function generateSessionId(string $salt): void { if (self::$sid !== false) ErrorHandler::traceError('Error: Asked to generate session id when already set.'); @@ -27,7 +27,7 @@ class Session ); } - public static function create(string $salt, int $userId, bool $fixedAddress) + public static function create(string $salt, int $userId, bool $fixedAddress): void { self::generateSessionId($salt); self::$data = []; @@ -71,7 +71,7 @@ class Session * @param mixed $value data to store for key, false = delete * @param int|false $validMinutes validity in minutes, or false = forever */ - public static function set(string $key, $value, $validMinutes = 60) + public static function set(string $key, $value, $validMinutes = 60): void { if (self::$data === false) ErrorHandler::traceError('Tried to set session data with no active session'); @@ -96,7 +96,7 @@ class Session return true; } - public static function delete() + public static function delete(): void { if (self::$sid === false) return; @@ -112,7 +112,7 @@ class Session * a security measure if the user suspects that a session left open on * another device could be/is being abused. */ - public static function deleteAllButCurrent() + public static function deleteAllButCurrent(): void { if (self::$sid === false) return; @@ -120,7 +120,7 @@ class Session ['sid' => self::$sid, 'uid' => self::$userId]); } - public static function deleteCookie() + public static function deleteCookie(): void { Util::clearCookie('sid'); } @@ -155,7 +155,7 @@ class Session return true; } - private static function setupSessionAccounting(bool $cookie) + private static function setupSessionAccounting(bool $cookie): void { if ($cookie) { self::$updateSessionDateline = true; @@ -169,7 +169,7 @@ class Session }); } - private static function saveOnShutdown() + private static function saveOnShutdown(): void { $now = time(); $args = ['lastip' => $_SERVER['REMOTE_ADDR']]; @@ -182,7 +182,7 @@ class Session self::saveData($args); } - public static function saveExtraData() + public static function saveExtraData(): void { if (!self::$dataChanged) return; @@ -190,7 +190,7 @@ class Session self::$dataChanged = false; } - private static function saveData(array $args) + private static function saveData(array $args): void { $query = "UPDATE session SET " . implode(', ', array_map(function ($key) { return "$key = :$key"; diff --git a/inc/taskmanager.inc.php b/inc/taskmanager.inc.php index 700ea4ad..6c9d63c2 100644 --- a/inc/taskmanager.inc.php +++ b/inc/taskmanager.inc.php @@ -19,7 +19,7 @@ class Taskmanager */ private static $sock = false; - private static function init() + private static function init(): void { if (self::$sock !== false) return; @@ -32,7 +32,7 @@ class Taskmanager self::send(CONFIG_TM_PASSWORD); } - private static function send($message) + private static function send(string $message): bool { $len = strlen($message); $sent = socket_send(self::$sock, pack('N', $len) . $message, $len + 4, 0); @@ -51,7 +51,7 @@ class Taskmanager * the return value is just true (and you won't know if the task could actually be started) * @return array{id: string, statusCode: string, data: array}|bool struct representing the task status (as a result of submit); false on communication error */ - public static function submit($task, $data = false, $async = false) + public static function submit(string $task, array $data = null, bool $async = false) { self::init(); $seq = (string) mt_rand(); @@ -109,7 +109,7 @@ class Taskmanager * @param string|array $taskid a task id or a task array returned by ::status or ::submit * @return boolean true if taskid exists in taskmanager */ - public static function isTask($task) + public static function isTask($task): bool { if ($task === false) return false; @@ -127,7 +127,7 @@ class Taskmanager * @param int $timeout maximum time in ms to wait for completion of task * @return array|false result/status of task, or false if it couldn't be queried */ - public static function waitComplete($task, $timeout = 2500) + public static function waitComplete($task, int $timeout = 2500) { if (is_array($task) && isset($task['id'])) { if ($task['statusCode'] !== Taskmanager::TASK_PROCESSING && $task['statusCode'] !== Taskmanager::TASK_WAITING) { @@ -140,6 +140,7 @@ class Taskmanager return false; $done = false; $deadline = microtime(true) + $timeout / 1000; + $status = false; while (($remaining = $deadline - microtime(true)) > 0) { usleep((int)min(100000, $remaining * 100000)); $status = self::status($task); @@ -163,7 +164,7 @@ class Taskmanager * @param array|false $task struct representing task, obtained by ::status * @return boolean true if task failed, false if finished successfully or still waiting/running */ - public static function isFailed($task) + public static function isFailed($task): bool { if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id'])) return true; @@ -176,10 +177,10 @@ class Taskmanager * Check whether the given task is finished, i.e. either failed or succeeded, * but is not running, still waiting for execution or simply unknown. * - * @param array $task struct representing task, obtained by ::status + * @param mixed $task struct representing task, obtained by ::status * @return boolean true if task failed or finished, false if waiting for execution or currently executing, no valid task, etc. */ - public static function isFinished($task) + public static function isFinished($task): bool { if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id'])) return false; @@ -192,10 +193,10 @@ class Taskmanager * Check whether the given task is running, that is either waiting for execution * or currently executing. * - * @param array $task struct representing task, obtained by ::status + * @param mixed $task struct representing task, obtained by ::status * @return boolean true if task is waiting or executing, false if waiting for execution or currently executing, no valid task, etc. */ - public static function isRunning($task) + public static function isRunning($task): bool { if (!is_array($task) || !isset($task['statusCode']) || !isset($task['id'])) return false; @@ -204,7 +205,7 @@ class Taskmanager return false; } - public static function addErrorMessage($task) + public static function addErrorMessage($task): void { static $failure = false; if ($task === false) { @@ -231,7 +232,7 @@ class Taskmanager * @param string|array $task task to release. can either be its id, or a struct representing the task, as returned * by ::submit() or ::status() */ - public static function release($task) + public static function release($task): void { if (is_array($task) && isset($task['id'])) { $task = $task['id']; @@ -247,7 +248,6 @@ class Taskmanager /** * Read reply from socket for given sequence number. * - * @param string $seq * @return mixed the decoded json data for that message as an array, or false on error */ private static function readReply(string $seq) @@ -324,7 +324,7 @@ class Taskmanager * sending or receiving and the send or receive * buffer might be in an undefined state. */ - private static function reset() + private static function reset(): void { if (self::$sock === false) return; @@ -335,7 +335,7 @@ class Taskmanager /** * @param float $deadline end time */ - private static function updateRecvTimeout($deadline) + private static function updateRecvTimeout(float $deadline): void { $to = $deadline - microtime(true); if ($to <= 0) { diff --git a/inc/taskmanagercallback.inc.php b/inc/taskmanagercallback.inc.php index 7c1e965e..321475ac 100644 --- a/inc/taskmanagercallback.inc.php +++ b/inc/taskmanagercallback.inc.php @@ -13,7 +13,7 @@ class TaskmanagerCallback * @param string|array $task Task or Task ID to define callback for * @param string $callback name of callback function, must be a static method in this class */ - public static function addCallback($task, $callback, $args = NULL) + public static function addCallback($task, string $callback, $args = NULL): void { if (!call_user_func_array('method_exists', array('TaskmanagerCallback', $callback))) { EventLog::warning("addCallback: Invalid callback function: $callback"); @@ -50,7 +50,7 @@ class TaskmanagerCallback * * @return array list of array(taskid => list of callbacks) */ - public static function getPendingCallbacks() + public static function getPendingCallbacks(): array { $res = Database::simpleQuery("SELECT taskid, cbfunction, args FROM callback", array(), true); if ($res === false) @@ -67,9 +67,9 @@ class TaskmanagerCallback * table if appropriate. * * @param array $callback entry from the callback table (cbfunction + taskid + args) - * @param array $status status of the task as returned by the taskmanager. If NULL it will be queried. + * @param ?array $status status of the task as returned by the taskmanager. If NULL it will be queried. */ - public static function handleCallback($callback, $status = NULL) + public static function handleCallback(array $callback, array $status = NULL): void { if (is_null($status)) $status = Taskmanager::status($callback['taskid']); @@ -99,7 +99,7 @@ class TaskmanagerCallback /** * Result of trying to (re)launch ldadp. */ - public static function ldadpStartup($task) + public static function ldadpStartup(array $task) { if (Taskmanager::isFailed($task)) { if (!isset($task['data']['messages'])) { @@ -112,14 +112,14 @@ class TaskmanagerCallback /** * Result of restoring the server configuration */ - public static function dbRestored($task) + public static function dbRestored(array $task) { if (!Taskmanager::isFailed($task)) { EventLog::info('Configuration backup restored.'); } } - public static function adConfigCreate($task) + public static function adConfigCreate(array $task) { if (Taskmanager::isFailed($task)) EventLog::warning("Could not generate Active Directory configuration", $task['data']['error']); @@ -131,7 +131,7 @@ class TaskmanagerCallback * @param array $task task obj * @param array $args has keys 'moduleid' and optionally 'deleteOnError' and 'tmpTgz' */ - public static function cbConfModCreated($task, $args) + public static function cbConfModCreated(array $task, array $args) { $mod = Module::get('sysconfig'); if ($mod === false) @@ -150,7 +150,7 @@ class TaskmanagerCallback * @param array $task task obj * @param array $args has keys 'configid' and optionally 'deleteOnError' */ - public static function cbConfTgzCreated($task, $args) + public static function cbConfTgzCreated(array $task, array $args) { $mod = Module::get('sysconfig'); if ($mod === false) @@ -163,7 +163,7 @@ class TaskmanagerCallback } } - public static function manualMount($task, $args) + public static function manualMount(array $task, $args) { if (!isset($task['data']['exitCode'])) return; @@ -183,7 +183,7 @@ class TaskmanagerCallback } } - public static function mlGotList($task, $args) + public static function mlGotList(array $task, $args) { $mod = Module::get('minilinux'); if ($mod === false) @@ -192,7 +192,7 @@ class TaskmanagerCallback MiniLinux::listDownloadCallback($task, $args); } - public static function mlGotLinux($task, $args) + public static function mlGotLinux(array $task, $args) { $mod = Module::get('minilinux'); if ($mod === false) @@ -201,7 +201,7 @@ class TaskmanagerCallback MiniLinux::linuxDownloadCallback($task, $args); } - public static function rbcConnCheck($task, $args) + public static function rbcConnCheck(array $task, $args) { $mod = Module::get('rebootcontrol'); if ($mod === false) @@ -210,7 +210,7 @@ class TaskmanagerCallback RebootControl::connectionCheckCallback($task, $args); } - public static function ipxeVersionSet($task) + public static function ipxeVersionSet(array $task) { $mod = Module::get('serversetup'); if ($mod === false) @@ -219,7 +219,7 @@ class TaskmanagerCallback IPxeBuilder::setIPxeVersionCallback($task); } - public static function ipxeCompileDone($task) + public static function ipxeCompileDone(array $task) { $mod = Module::get('serversetup'); if ($mod === false) diff --git a/inc/trigger.inc.php b/inc/trigger.inc.php index df06229b..4776855c 100644 --- a/inc/trigger.inc.php +++ b/inc/trigger.inc.php @@ -15,9 +15,9 @@ class Trigger * Compile iPXE pxelinux menu. Needs to be done whenever the server's IP * address changes. * - * @return ?string false if launching task failed, task-id otherwise + * @return ?string null if launching task failed, task-id otherwise */ - public static function ipxe(string $taskId = null) + public static function ipxe(string $taskId = null): ?string { static $lastResult = null; if ($lastResult !== null) @@ -101,18 +101,14 @@ class Trigger * @param bool $ifLocalOnly Only execute task if the storage type is local (used for DNBD3) * @return ?string task id of mount procedure, or false on error */ - public static function mount($vmstore = false, bool $ifLocalOnly = false) + public static function mount($vmstore = false, bool $ifLocalOnly = false): ?string { if ($vmstore === false) { $vmstore = Property::getVmStoreConfig(); } if (!is_array($vmstore)) return null; - if (isset($vmstore['storetype'])) { - $storetype = $vmstore['storetype']; - } else { - $storetype = 'unknown'; - } + $storetype = $vmstore['storetype'] ?? 'unknown'; if ($storetype === 'nfs') { $addr = $vmstore['nfsaddr']; $opts = 'nfsopts'; @@ -126,11 +122,7 @@ class Trigger // Bail out if storage is not local, and we only want to run it in that case if ($ifLocalOnly && $addr !== 'null') return null; - if (isset($vmstore[$opts])) { - $opts = $vmstore[$opts]; - }else { - $opts = null; - } + $opts = $vmstore[$opts] ?? null; $status = Taskmanager::submit('MountVmStore', array( 'address' => $addr, 'type' => 'images', @@ -172,7 +164,7 @@ class Trigger return $tasksLeft; } - private static function triggerDaemons(string $action, $parent, &$taskids) + private static function triggerDaemons(string $action, ?string $parent, array &$taskids): ?string { $task = Taskmanager::submit('Systemctl', array( 'operation' => $action, @@ -200,7 +192,7 @@ class Trigger /** * Stop any daemons that might be sitting on the VMstore, or database. */ - public static function stopDaemons($parent, &$taskids) + public static function stopDaemons(?string $parent, array &$taskids): ?string { $parent = self::triggerDaemons('stop', $parent, $taskids); $task = Taskmanager::submit('LdadpLauncher', array( diff --git a/inc/user.inc.php b/inc/user.inc.php index cf9c38c0..4d278e1b 100644 --- a/inc/user.inc.php +++ b/inc/user.inc.php @@ -1,5 +1,7 @@ 0; } - public static function login(string $user, string $pass, bool $fixedIp) + public static function login(string $user, string $pass, bool $fixedIp): bool { $ret = Database::queryFirst('SELECT userid, passwd FROM user WHERE login = :user LIMIT 1', array(':user' => $user)); if ($ret === false) @@ -157,14 +160,15 @@ class User return true; } - public static function logout() + #[NoReturn] + public static function logout(): void { Session::delete(); Header('Location: ?do=Main&fromlogout'); exit(0); } - public static function setLastSeenEvent($eventid) + public static function setLastSeenEvent(int $eventid): void { if (!self::isLoggedIn()) return; @@ -182,7 +186,7 @@ class User return self::$user['lasteventid']; } - private static function generateToken($salt = '') + private static function generateToken($salt = ''): void { Session::set('token', md5($salt . ',' . rand() . ',' diff --git a/inc/util.inc.php b/inc/util.inc.php index 8bd48dd3..0c402a6a 100644 --- a/inc/util.inc.php +++ b/inc/util.inc.php @@ -1,5 +1,7 @@ PiB#'); } - public static function sanitizeFilename(string $name) + public static function sanitizeFilename(string $name): string { return preg_replace('/[^a-zA-Z0-9_\-]+/', '_', $name); } @@ -130,7 +133,7 @@ class Util * @param string $prefix required prefix of $path * @return false|string */ - public static function safePath(string $path, string $prefix = '') + public static function safePath(string $path, string $prefix = ''): string { if (empty($path)) return false; @@ -253,9 +256,9 @@ class Util * * @param int $length number of bytes to return * @param bool $secure true = only use strong random sources - * @return string|bool string of requested length, false on error + * @return ?string string of requested length, false on error */ - public static function randomBytes(int $length, bool $secure = true) + public static function randomBytes(int $length, bool $secure = true): ?string { if (function_exists('random_bytes')) { try { @@ -292,7 +295,7 @@ class Util } } if ($secure) { - return false; + return null; } $bytes = ''; while ($length > 0) { @@ -306,7 +309,7 @@ class Util */ public static function randomUuid(): string { - $b = unpack('h8a/h4b/h12c', self::randomBytes(12)); + $b = unpack('h8a/h4b/h12c', self::randomBytes(12, false)); return sprintf('%08s-%04s-%04x-%04x-%012s', // 32 bits for "time_low" @@ -334,7 +337,7 @@ class Util * The format depends on how far the timestamp lies in the past. * * @param int $ts unix timestamp - * @return string human readable representation + * @return string human-readable representation */ public static function prettyTime(int $ts): string { @@ -366,8 +369,8 @@ class Util public static function boolToString(bool $bool): string { if ($bool) - return Dictionary::translate('lang_yes', true); - return Dictionary::translate('lang_no', true); + return Dictionary::translate('lang_yes'); + return Dictionary::translate('lang_no'); } /** @@ -375,7 +378,6 @@ class Util * * @param int $seconds The number to format * @param bool $showSecs whether to show seconds, or rather cut after minutes - * @return string */ public static function formatDuration(int $seconds, bool $showSecs = true): string { @@ -408,7 +410,7 @@ class Util * * @param string $name cookie name */ - public static function clearCookie(string $name) + public static function clearCookie(string $name): void { $parts = explode('/', $_SERVER['SCRIPT_NAME']); $path = ''; @@ -455,14 +457,21 @@ class Util /** * Clamp given value into [min, max] range. + * @param mixed $value value to clamp. This should be a number. + * @param int $min lower bound + * @param int $max upper bound + * @param bool $toInt if true, variable type of $value will be set to int in addition to clamping */ - public static function clamp(int &$value, int $min, int $max) + public static function clamp(&$value, int $min, int $max, bool $toInt = true): void { - if ($value < $min) { + if (!is_numeric($value) || $value < $min) { $value = $min; } elseif ($value > $max) { $value = $max; } + if ($toInt) { + settype($value, 'int'); + } } } diff --git a/index.php b/index.php index 78d23111..6b5305b2 100644 --- a/index.php +++ b/index.php @@ -48,7 +48,7 @@ abstract class Page public static function render() { $pageTitle = self::$module->getPageTitle(); - if ($pageTitle !== false) { + if (!empty($pageTitle)) { Render::setTitle($pageTitle, false); } self::$instance->doRender(); @@ -155,9 +155,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!Util::verifyToken()) { if (AJAX) { die('CSRF/XSS? Missing token in POST request!'); - } else { - Util::redirect('?do=Main'); } + Util::redirect('?do=Main'); } } @@ -190,7 +189,7 @@ if (defined('CONFIG_DEBUG') && CONFIG_DEBUG) { * @param int $code Error code to map * @return string Readable error type */ - function mapErrorCode($code) + function mapErrorCode(int $code): string { switch ($code) { case E_PARSE: diff --git a/install.php b/install.php index d411d834..530298b1 100644 --- a/install.php +++ b/install.php @@ -19,6 +19,8 @@ * they might depend on some tables that do not exist yet. ;) */ +use JetBrains\PhpStorm\NoReturn; + /** * Report back the update status to the browser/client and terminate execution. * This has to be called by an update module at some point to signal the result @@ -27,7 +29,8 @@ * @param string $status one of the UPDATE_* status codes * @param string $message Human readable description of the status (optional) */ -function finalResponse($status, $message = '') +#[NoReturn] +function finalResponse(string $status, string $message = '') { if (!DIRECT_MODE && AJAX) { echo json_encode(array('status' => $status, 'message' => $message)); @@ -58,7 +61,7 @@ function handleUpdateResult($res) * Helper functions for dealing with the database */ -function tableHasColumn($table, $column) +function tableHasColumn(string $table, string $column): bool { return tableColumnType($table, $column) !== false; } @@ -66,7 +69,7 @@ function tableHasColumn($table, $column) /** * Get type of column, as reported by DESCRIBE ; */ -function tableColumnType($table, $column) +function tableColumnType(string $table, string $column) { return tableGetDescribeColumn($table, $column, 'Type'); } @@ -78,8 +81,10 @@ function tableColumnKeyType($table, $column) /** * For internal use + * @param string|string[] $column + * @return string|false */ -function tableGetDescribeColumn($table, $column, $what) +function tableGetDescribeColumn(string $table, $column, string $what) { $table = preg_replace('/\W/', '', $table); $res = Database::simpleQuery("DESCRIBE `$table`", array(), true); @@ -92,33 +97,37 @@ function tableGetDescribeColumn($table, $column, $what) return false; } -function tableGetIndex($table, $index) +/** + * Return name of index that spans all the columns given, in the same order. + * Returns false if not found + * + * @param string[] $columns + * @return false|string + */ +function tableGetIndex(string $table, array $columns) { $table = preg_replace('/\W/', '', $table); - if (!is_array($index)) { - $index = [$index]; - } $res = Database::simpleQuery("SHOW INDEX FROM `$table`", array(), true); if ($res !== false) { $matches = []; foreach ($res as $row) { $i = $row['Seq_in_index'] - 1; - if (isset($index[$i]) && $index[$i] === $row['Column_name']) { + if (isset($columns[$i]) && $columns[$i] === $row['Column_name']) { if (!isset($matches[$row['Key_name']])) { $matches[$row['Key_name']] = 0; } $matches[$row['Key_name']]++; } } - } - foreach ($matches as $key => $m) { - if ($m === count($index)) - return $key; + foreach ($matches as $key => $m) { + if ($m === count($columns)) + return $key; + } } return false; } -function tableDropColumn($table, $column) +function tableDropColumn(string $table, string $column): void { $table = preg_replace('/\W/', '', $table); $column = preg_replace('/\W/', '', $column); @@ -131,7 +140,7 @@ function tableDropColumn($table, $column) } } -function tableExists($table) +function tableExists(string $table): bool { $res = Database::simpleQuery("SHOW TABLES", array(), true); while ($row = $res->fetch(PDO::FETCH_NUM)) { @@ -141,8 +150,9 @@ function tableExists($table) return false; } -function tableRename($old, $new) { - return Database::simpleQuery("RENAME TABLE $old TO $new", []); +function tableRename(string $old, string $new): bool +{ + return Database::simpleQuery("RENAME TABLE $old TO $new", []) !== false; } @@ -155,7 +165,7 @@ function tableRename($old, $new) { * @param string $refColumn referenced column * @return false|string[] false == doesn't exist, assoc array otherwise */ -function tableGetConstraints($table, $column, $refTable, $refColumn) +function tableGetConstraints(string $table, string $column, string $refTable, string $refColumn) { $db = 'openslx'; if (defined('CONFIG_SQL_DB')) { @@ -188,21 +198,22 @@ function tableGetConstraints($table, $column, $refTable, $refColumn) * @param string $actions "ON xxx ON yyy" string * @return string UPDATE_* result code */ -function tableAddConstraint($table, $column, $refTable, $refColumn, $actions, $ignoreError = false, $name = '') +function tableAddConstraint(string $table, string $column, string $refTable, string $refColumn, string $actions, + bool $ignoreError = false, $name = ''): string { $test = tableExists($refTable) && tableHasColumn($refTable, $refColumn); if ($test === false) { - // Most likely, destination table does not exist yet or isn't up to date + // Most likely, destination table does not exist yet or isn't up-to-date return UPDATE_RETRY; } // TODO: Refactor function, make this two args $update = 'RESTRICT'; $delete = 'RESTRICT'; - if (preg_match('/on\s+update\s+(RESTRICT|SET\s+NULL|CASCADE)/ims', $actions, $out)) { - $update = preg_replace('/\s+/ms', ' ', strtoupper($out[1])); + if (preg_match('/on\s+update\s+(RESTRICT|SET\s+NULL|CASCADE)/im', $actions, $out)) { + $update = preg_replace('/\s+/m', ' ', strtoupper($out[1])); } - if (preg_match('/on\s+delete\s+(RESTRICT|SET\s+NULL|CASCADE)/ims', $actions, $out)) { - $delete = preg_replace('/\s+/ms', ' ', strtoupper($out[1])); + if (preg_match('/on\s+delete\s+(RESTRICT|SET\s+NULL|CASCADE)/im', $actions, $out)) { + $delete = preg_replace('/\s+/m', ' ', strtoupper($out[1])); } $test = tableGetConstraints($table, $column, $refTable, $refColumn); if ($test !== false) { @@ -239,9 +250,8 @@ function tableAddConstraint($table, $column, $refTable, $refColumn, $actions, $i if ($ret === false) { if ($ignoreError) { return UPDATE_FAILED; - } else { - finalResponse(UPDATE_FAILED, "Cannot add constraint $table.$column -> $refTable.$refColumn: " . Database::lastError()); } + finalResponse(UPDATE_FAILED, "Cannot add constraint $table.$column -> $refTable.$refColumn: " . Database::lastError()); } return UPDATE_DONE; } @@ -253,12 +263,12 @@ function tableAddConstraint($table, $column, $refTable, $refColumn, $actions, $i * @param string $constraint constraint name * @return bool success indicator */ -function tableDeleteConstraint($table, $constraint) +function tableDeleteConstraint(string $table, string $constraint): bool { return Database::exec("ALTER TABLE `$table` DROP FOREIGN KEY `$constraint`") !== false; } -function tableCreate($table, $structure, $fatalOnError = true) +function tableCreate(string $table, string $structure, bool $fatalOnError = true): string { if (tableExists($table)) { return UPDATE_NOOP; @@ -273,7 +283,8 @@ function tableCreate($table, $structure, $fatalOnError = true) return UPDATE_FAILED; } -function responseFromArray($array) +#[NoReturn] +function responseFromArray(array $array) { if (in_array(UPDATE_FAILED, $array)) { finalResponse(UPDATE_FAILED, 'Update failed!'); @@ -286,7 +297,6 @@ function responseFromArray($array) } finalResponse(UPDATE_NOOP, 'Everything already up to date'); - } /* @@ -329,19 +339,12 @@ if (!Database::init(true)) { // Good to go so far -/** - * @param \Module $module - * @return bool - */ -function hasUpdateScript($module) +function hasUpdateScript(Module $module): bool { return is_readable($module->getDir() . '/install.inc.php'); } -/** - * @param Module $module - */ -function runUpdateScript($module) +function runUpdateScript(Module $module): void { require_once $module->getDir() . '/install.inc.php'; } diff --git a/modules-available/adduser/page.inc.php b/modules-available/adduser/page.inc.php index 499436ff..0ef28a3e 100644 --- a/modules-available/adduser/page.inc.php +++ b/modules-available/adduser/page.inc.php @@ -215,13 +215,13 @@ class Page_AddUser extends Page } } - private function showRoles($userid = false) + private function showRoles(int $userid = null): void { if (!Module::isAvailable('permissionmanager')) return; if (!User::hasPermission('.permissionmanager.users.edit-roles')) return; - $data = ['roles' => PermissionUtil::getRoles($userid, false)]; + $data = ['roles' => PermissionUtil::getRoles($userid)]; Render::addTemplate('user-permissions', $data); } diff --git a/modules-available/baseconfig/inc/baseconfig.inc.php b/modules-available/baseconfig/inc/baseconfig.inc.php index 2e8efeda..36622dce 100644 --- a/modules-available/baseconfig/inc/baseconfig.inc.php +++ b/modules-available/baseconfig/inc/baseconfig.inc.php @@ -17,13 +17,15 @@ class BaseConfig */ public static function prepareFromRequest() { - $ip = $_SERVER['REMOTE_ADDR']; + $ip = $_SERVER['REMOTE_ADDR'] ?? null; + if ($ip === null) + ErrorHandler::traceError('No REMOTE_ADDR given in $_SERVER'); 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; } // Handle any hooks by other modules first // other modules should generally only populate $configVars @@ -42,10 +44,10 @@ class BaseConfig * 'locationid' * @param array $overrides key value pairs of overrides */ - public static function prepareWithOverrides($overrides) + public static function prepareWithOverrides(array $overrides): void { self::$overrides = $overrides; - $ip = $uuid = false; + $ip = $uuid = null; if (self::hasOverride('ip')) { $ip = self::getOverride('ip'); } @@ -78,7 +80,7 @@ class BaseConfig // Dump global config from DB ConfigHolder::setContext('', function($id) { return [ - 'name' => Dictionary::translate('source-global', true), + 'name' => Dictionary::translate('source-global'), 'locationid' => 0, ]; }); @@ -98,7 +100,7 @@ class BaseConfig { ConfigHolder::setContext('', function($id) { return [ - 'name' => Dictionary::translate('source-default', true), + 'name' => Dictionary::translate('source-default'), 'locationid' => 0, ]; }); @@ -107,8 +109,9 @@ class BaseConfig } } - private static function handleModule($name, $ip, $uuid, $needJsonHook) // Pass ip and uuid instead of global to make them read only + private static function handleModule(string $name, ?string $ip, ?string $uuid, bool $needJsonHook): void { + // Pass ip and uuid instead of global to make them read only if (isset(self::$modulesDone[$name])) return; self::$modulesDone[$name] = true; @@ -130,12 +133,12 @@ class BaseConfig self::handleModule($dep, $ip, $uuid, $needJsonHook); } ConfigHolder::setContext($name); - (function ($file, $ip, $uuid) { + (function (string $file, ?string $ip, ?string $uuid) { include_once($file); })($file, $ip, $uuid); } - public static function hasOverride($key) + public static function hasOverride($key): bool { return array_key_exists($key, self::$overrides); } diff --git a/modules-available/baseconfig/inc/baseconfigutil.inc.php b/modules-available/baseconfig/inc/baseconfigutil.inc.php index a48eb93b..4d1ef8c1 100644 --- a/modules-available/baseconfig/inc/baseconfigutil.inc.php +++ b/modules-available/baseconfig/inc/baseconfigutil.inc.php @@ -16,7 +16,7 @@ class BaseConfigUtil * @param \Module $module optional, only consider given module, not all enabled modules * @return array all known config variables */ - public static function getVariables($module = false) + public static function getVariables($module = false): array { $settings = array(); if ($module === false) { @@ -39,16 +39,13 @@ class BaseConfigUtil /** * Get configuration categories for given module, or all modules if false is passed. - * - * @param \Module $module - * @return array */ - public static function getCategories($module = false) + public static function getCategories(Module $module = null): array { $categories = array(); - if ($module === false) { + if ($module === null) { $module = '*'; - } elseif (is_object($module)) { + } else { $module = $module->getIdentifier(); } foreach (glob("modules/{$module}/baseconfig/categories.json", GLOB_NOSORT) as $file) { @@ -70,7 +67,8 @@ class BaseConfigUtil * @param array $vars list of vars as obtained from BaseConfigUtil::getVariables() * @param array $values key-value-pairs of variable assignments to work with */ - public static function markShadowedVars(&$vars, $values) { + public static function markShadowedVars(array &$vars, array $values): void + { foreach ($vars as $key => &$var) { if (!isset($var['shadows'])) continue; diff --git a/modules-available/baseconfig/inc/configholder.inc.php b/modules-available/baseconfig/inc/configholder.inc.php index 224f2aab..75b43460 100644 --- a/modules-available/baseconfig/inc/configholder.inc.php +++ b/modules-available/baseconfig/inc/configholder.inc.php @@ -19,7 +19,7 @@ class ConfigHolder * @param false|string|array $value false to unset, string value, or array with keys value and displayvalue * @param int $prio priority of this value, in case the same key gets set multiple times */ - public static function add($key, $value, $prio = 0) + public static function add(string $key, $value, int $prio = 0): void { if (!isset(self::$config[$key])) { self::$config[$key] = []; @@ -43,22 +43,19 @@ class ConfigHolder } } - public static function get($key) + public static function get(string $key): ?string { if (!isset(self::$config[$key])) - return false; + return null; return self::$config[$key][0]['value']; } - /** - * @param callable $func - */ - public static function addPostHook($func) + public static function addPostHook(callable $func): void { self::$postHooks[] = array('context' => &self::$context, 'function' => $func); } - public static function applyPostHooks() + public static function applyPostHooks(): void { foreach (self::$postHooks as $hook) { $newContext = $hook['context']; @@ -69,7 +66,7 @@ class ConfigHolder self::$postHooks = []; } - public static function getRecursiveConfig($prettyPrint = true) + public static function getRecursiveConfig(bool $prettyPrint = true): array { $ret = []; foreach (self::$config as $key => $list) { @@ -97,7 +94,7 @@ class ConfigHolder return $ret; } - public static function outputConfig() + public static function outputConfig(): void { foreach (self::$config as $key => $list) { echo str_pad('# ' . $key . ' ', 35, '#', STR_PAD_BOTH), "\n"; @@ -129,7 +126,7 @@ class ConfigHolder * @param string $string input * @return string escaped sh string */ - private static function escape($string) + private static function escape(string $string): string { return str_replace(["'", "\n", "\r"], ["'\"'\"'", ' ', ' '], $string); } diff --git a/modules-available/baseconfig/inc/validator.inc.php b/modules-available/baseconfig/inc/validator.inc.php index ee883895..be71c3df 100644 --- a/modules-available/baseconfig/inc/validator.inc.php +++ b/modules-available/baseconfig/inc/validator.inc.php @@ -38,7 +38,6 @@ class Validator default: ErrorHandler::traceError('Unknown validation method: ' . $data[0]); } - return false; // make code inspector happy - doesn't know traceError doesn't return } @@ -64,7 +63,7 @@ class Validator * @param string $displayValue network path * @return string cleaned up path */ - private static function networkShare(&$displayValue) + private static function networkShare(string &$displayValue): string { $displayValue = trim($displayValue); if (substr($displayValue, 0, 2) === '\\\\') @@ -89,7 +88,7 @@ class Validator return $displayValue; return false; } - private static function validateMultiList(string $list, string &$displayValue): string + private static function validateMultiList(string $list, array &$displayValue): string { $allowedValues = explode('|', $list); $values = []; diff --git a/modules-available/baseconfig/page.inc.php b/modules-available/baseconfig/page.inc.php index 8a9a7534..5d684a8e 100644 --- a/modules-available/baseconfig/page.inc.php +++ b/modules-available/baseconfig/page.inc.php @@ -68,7 +68,7 @@ class Page_BaseConfig extends Page if (isset($var['shadowed'])) continue; $validator = $var['validator']; - $displayValue = (isset($newValues[$key]) ? $newValues[$key] : ''); + $displayValue = $newValues[$key] ?? ''; // Validate data first! $mangledValue = Validator::validate($validator, $displayValue); if ($mangledValue === false) { @@ -101,7 +101,7 @@ class Page_BaseConfig extends Page foreach ($this->categories as $catid => $val) { Dashboard::addSubmenu( '#category_' . $catid, - Dictionary::translateFileModule($this->categories[$catid]['module'], 'config-variable-categories', $catid, true) + Dictionary::translateFileModule($this->categories[$catid]['module'], 'config-variable-categories', $catid) ); } } @@ -153,7 +153,7 @@ class Page_BaseConfig extends Page } } if (!isset($entry['shadows'])) { - $entry['shadows'] = isset($var['shadows']) ? $var['shadows'] : null; + $entry['shadows'] = $var['shadows'] ?? null; } $entry += array( 'item' => $this->makeInput( @@ -165,7 +165,7 @@ class Page_BaseConfig extends Page ), 'description' => Util::markup(Dictionary::translateFileModule($var['module'], 'config-variables', $key)), 'setting' => $key, - 'tree' => isset($parents[$key]) ? $parents[$key] : false, + 'tree' => $parents[$key] ?? false, ); } unset($entry); @@ -260,7 +260,7 @@ class Page_BaseConfig extends Page $this->qry_extra = $hook; } - private function getPermissionLocationId() + private function getPermissionLocationId(): int { if (!isset($this->qry_extra['locationResolver']) || !isset($this->qry_extra['field_value'])) return 0; @@ -280,10 +280,8 @@ class Page_BaseConfig extends Page /** * Create html snippet for setting, based on given validator - * @param string $validator - * @return boolean */ - private function makeInput($validator, $setting, $current, $shadows, $disabled) + private function makeInput(string $validator, string $setting, string $current, ?array $shadows, bool $disabled): string { /* for the html snippet we need: */ $args = array('class' => 'form-control', 'name' => "setting[$setting]", 'id' => $setting); diff --git a/modules-available/baseconfig_bwidm/hooks/translation.inc.php b/modules-available/baseconfig_bwidm/hooks/translation.inc.php index a53500fc..da7c70af 100644 --- a/modules-available/baseconfig_bwidm/hooks/translation.inc.php +++ b/modules-available/baseconfig_bwidm/hooks/translation.inc.php @@ -16,10 +16,8 @@ $HANDLER['subsections'] = array( /** * Configuration categories. - * @param \Module $module - * @return array */ -$HANDLER['grep_config-variable-categories'] = function($module) { +$HANDLER['grep_config-variable-categories'] = function (Module $module): array { if (!$module->activate(1, false)) return array(); $want = BaseConfigUtil::getCategories($module); @@ -31,10 +29,8 @@ $HANDLER['grep_config-variable-categories'] = function($module) { /** * Configuration variables. - * @param \Module $module - * @return array */ -$HANDLER['grep_config-variables'] = function($module) { +$HANDLER['grep_config-variables'] = function (Module $module): array { if (!$module->activate(1, false)) return array(); $want = BaseConfigUtil::getVariables($module); diff --git a/modules-available/baseconfig_bwlp/hooks/translation.inc.php b/modules-available/baseconfig_bwlp/hooks/translation.inc.php index a53500fc..da7c70af 100644 --- a/modules-available/baseconfig_bwlp/hooks/translation.inc.php +++ b/modules-available/baseconfig_bwlp/hooks/translation.inc.php @@ -16,10 +16,8 @@ $HANDLER['subsections'] = array( /** * Configuration categories. - * @param \Module $module - * @return array */ -$HANDLER['grep_config-variable-categories'] = function($module) { +$HANDLER['grep_config-variable-categories'] = function (Module $module): array { if (!$module->activate(1, false)) return array(); $want = BaseConfigUtil::getCategories($module); @@ -31,10 +29,8 @@ $HANDLER['grep_config-variable-categories'] = function($module) { /** * Configuration variables. - * @param \Module $module - * @return array */ -$HANDLER['grep_config-variables'] = function($module) { +$HANDLER['grep_config-variables'] = function (Module $module): array { if (!$module->activate(1, false)) return array(); $want = BaseConfigUtil::getVariables($module); diff --git a/modules-available/dnbd3/baseconfig/getconfig.inc.php b/modules-available/dnbd3/baseconfig/getconfig.inc.php index eecb4642..eff821fc 100644 --- a/modules-available/dnbd3/baseconfig/getconfig.inc.php +++ b/modules-available/dnbd3/baseconfig/getconfig.inc.php @@ -1,5 +1,8 @@ activate(1, false) || !Module::isAvailable('baseconfig')) return array(); $want = BaseConfigUtil::getVariables($module); diff --git a/modules-available/dnbd3/inc/dnbd3rpc.inc.php b/modules-available/dnbd3/inc/dnbd3rpc.inc.php index a26ae4fd..f6bbf0ca 100644 --- a/modules-available/dnbd3/inc/dnbd3rpc.inc.php +++ b/modules-available/dnbd3/inc/dnbd3rpc.inc.php @@ -18,17 +18,9 @@ class Dnbd3Rpc { // Special case - local server if ($server === '') { $server = '127.0.0.1:5003'; - } elseif (($out = Dnbd3Util::matchAddress($server))) { - if (isset($out['v4'])) { - $server = $out['v4']; - } else { - $server = '[' . $out['v6'] . ']'; - } - if (isset($out['port'])) { - $server .= $out['port']; - } else { - $server .= ':5003'; - } + } elseif (($out = Dnbd3Util::matchAddress($server)) !== false) { + $server = $out['v4'] ?? '[' . $out['v6'] . ']'; + $server .= $out['port'] ?? ':5003'; } return $server; } @@ -72,7 +64,6 @@ class Dnbd3Rpc { /** * Get statistics for multiple servers at once. * @param string[] $servers - * @return array */ public static function getStatsMulti(array $servers, array $queryOptions = [], int $timeout = 2): array { @@ -91,7 +82,7 @@ class Dnbd3Rpc { $url = 'http://' . self::translateServer($server) . '/query?q=version' . $extra; $res = curl_init($url); if ($res === false) { - error_log("curl_init($url) failed with $res"); + error_log("curl_init($url) failed"); continue; } curl_setopt_array($res, [ diff --git a/modules-available/dnbd3/inc/dnbd3util.inc.php b/modules-available/dnbd3/inc/dnbd3util.inc.php index 90940e8a..47d7a4ea 100644 --- a/modules-available/dnbd3/inc/dnbd3util.inc.php +++ b/modules-available/dnbd3/inc/dnbd3util.inc.php @@ -108,11 +108,9 @@ class Dnbd3Util { /** * A client is booting that has runmode dnbd3 proxy - set config vars accordingly. * - * @param string $machineUuid * @param string $mode always 'proxy' - * @param string $modeData */ - public static function runmodeConfigHook($machineUuid, $mode, $modeData) + public static function runmodeConfigHook(string $machineUuid, string $mode, string $modeData) { $self = Property::getServerIp(); // Get all directly assigned locations @@ -125,7 +123,7 @@ class Dnbd3Util { $assignedLocs[] = $row['locationid']; } $modeData = (array)json_decode($modeData, true) + self::defaultRunmodeConfig(); - if (!empty($assignedLocs) && isset($modeData['firewall']) && $modeData['firewall']) { + if (!empty($assignedLocs) && ($modeData['firewall'] ?? false)) { // Get all sub-locations too $recursiveLocs = $assignedLocs; $locations = Location::getLocationsAssoc(); @@ -215,10 +213,10 @@ class Dnbd3Util { * @param int $end end address * @return string CIDR notation */ - private static function range2Cidr($start, $end) + private static function range2Cidr(int $start, int $end): string { if (PHP_INT_SIZE > 4) { - $bin = decbin((int)$start ^ (int)$end); + $bin = decbin($start ^ $end); } else { $bin = decbin((int)(float)$start ^ (int)(float)$end); } @@ -258,12 +256,15 @@ class Dnbd3Util { $ranges[] = $row; } - public static function defaultRunmodeConfig() + /** + * @return array{bgr: bool, firewall: bool} + */ + public static function defaultRunmodeConfig(): array { - return array( + return [ 'bgr' => true, 'firewall' => false - ); + ]; } public static function matchAddress($server) diff --git a/modules-available/dnbd3/page.inc.php b/modules-available/dnbd3/page.inc.php index 35f03199..ffaa995e 100644 --- a/modules-available/dnbd3/page.inc.php +++ b/modules-available/dnbd3/page.inc.php @@ -361,6 +361,7 @@ class Page_Dnbd3 extends Page $loc['clientCount'] = 0; $loc['recCount'] = 0; } + unset($loc); $showLocs = false; foreach ($res as $row) { settype($row['locationid'], 'int'); diff --git a/modules-available/dozmod/api.inc.php b/modules-available/dozmod/api.inc.php index 90e663aa..afc53853 100644 --- a/modules-available/dozmod/api.inc.php +++ b/modules-available/dozmod/api.inc.php @@ -10,6 +10,8 @@ **/ +use JetBrains\PhpStorm\NoReturn; + if (!Module::isAvailable('locations')) { die('require locations module'); } @@ -21,17 +23,17 @@ $availableRessources = ['list', 'netrules', 'metadata', 'imagemeta']; /* BEGIN: A simple caching mechanism ---------------------------- */ -function cache_hash($obj) +function cache_hash($obj): string { return md5(serialize($obj)); } -function cache_key_to_filename($key) +function cache_key_to_filename(string $key): string { return "/tmp/bwlp-slxadmin-cache-$key"; } -function cache_put($key, $value) +function cache_put(string $key, string $value): void { $filename = cache_key_to_filename($key); // Try to avoid another client concurrently accessing the cache seeing an empty file @@ -40,7 +42,7 @@ function cache_put($key, $value) rename($tmp, $filename); } -function cache_has($key) +function cache_has(string $key): bool { $filename = cache_key_to_filename($key); $mtime = @filemtime($filename); @@ -49,21 +51,18 @@ function cache_has($key) return false; // cache miss } $now = time(); - if ($now < $mtime || $now - $mtime > CONFIG_DOZMOD_EXPIRE) { - return false; - } else { - return true; - } + return $now >= $mtime && $now - $mtime <= CONFIG_DOZMOD_EXPIRE; } -function cache_get($key) +function cache_get(string $key): string { $filename = cache_key_to_filename($key); return file_get_contents($filename); } /* good for large binary files */ -function cache_get_passthru($key) +#[NoReturn] +function cache_get_passthru(string $key): void { $filename = cache_key_to_filename($key); $fp = fopen($filename, "r"); @@ -88,11 +87,16 @@ function cache_get_passthru($key) * Takes raw lecture list xml, returns array of uuids. * * @param string $responseXML XML from dozmod server - * @return array list of UUIDs, false on error + * @return array list of UUIDs */ -function xmlToLectureIds($responseXML) +function xmlToLectureIds(string $responseXML): array { - $xml = new SimpleXMLElement($responseXML); + try { + $xml = new SimpleXMLElement($responseXML); + } catch (Exception $e) { + EventLog::warning('Error parsing XML response data from DMSD: ' . $e->getMessage(), $responseXML); + return []; + } if (!isset($xml->eintrag)) return []; @@ -105,7 +109,8 @@ function xmlToLectureIds($responseXML) return $uuids; } -function sendExamModeMismatch() +#[NoReturn] +function sendExamModeMismatch(): void { Header('Content-Type: text/xml; charset=utf-8'); echo @@ -145,7 +150,7 @@ BLA; } /** Caching wrapper around _getLecturesForLocations() */ -function getListForLocations($locationIds, $raw) +function getListForLocations(array $locationIds, bool $raw) { /* if in any of the locations there is an exam active, consider the client to be in "exam-mode" and only offer him exams (no lectures) */ @@ -199,20 +204,20 @@ function getListForLocations($locationIds, $raw) return $list; } -function getLectureUuidsForLocations($locationIds) +function getLectureUuidsForLocations(array $locationIds) { return getListForLocations($locationIds, false); } -function outputLectureXmlForLocation($locationIds) +function outputLectureXmlForLocation(array $locationIds) { return getListForLocations($locationIds, true); } -function _getVmData($lecture_uuid, $subResource = false) +function _getVmData(string $lecture_uuid, string $subResource = null) { $url = VMX_URL . '/' . $lecture_uuid; - if ($subResource !== false) { + if ($subResource !== null) { $url .= '/' . $subResource; } $t = microtime(true); @@ -229,7 +234,7 @@ function _getVmData($lecture_uuid, $subResource = false) } /** Caching wrapper around _getVmData() **/ -function outputResource($lecture_uuid, $resource) +function outputResource(string $lecture_uuid, string $resource): void { if ($resource === 'metadata') { // HACK: config.tgz is compressed, don't use gzip output handler @@ -250,7 +255,7 @@ function outputResource($lecture_uuid, $resource) } else { $value = _getVmData($lecture_uuid, $resource); if ($value === false) - return false; + return; if (is_int($value)) { http_response_code($value); exit; @@ -258,16 +263,16 @@ function outputResource($lecture_uuid, $resource) cache_put($key, $value); die($value); } - return false; } +#[NoReturn] function fatalDozmodUnreachable() { Header('HTTP/1.1 504 Gateway Timeout'); die('DMSD currently not available'); } -function readLectureParam($locationIds) +function readLectureParam(array $locationIds): string { $lecture = Request::get('lecture', false, 'string'); if ($lecture === false) { @@ -290,7 +295,7 @@ function readLectureParam($locationIds) // in this context the lecture param is an image id (container), // just read and check if valid. // TODO do we need to check if this is allowed? -function readImageParam() +function readImageParam(): string { $image = Request::get('lecture', false, 'string'); @@ -335,6 +340,3 @@ if ($resource === 'list') { outputResource($lecture, $resource); } fatalDozmodUnreachable(); - -Header('HTTP/1.1 400 Bad Request'); -die("I don't know how to give you that resource"); diff --git a/modules-available/dozmod/page.inc.php b/modules-available/dozmod/page.inc.php index bf2a6fa4..4a43d881 100644 --- a/modules-available/dozmod/page.inc.php +++ b/modules-available/dozmod/page.inc.php @@ -68,7 +68,7 @@ class Page_DozMod extends Page /* add sub-menus */ foreach ($this->validSections as $section) { if ($section !== 'special' && User::hasPermission($section . '.*')) { - Dashboard::addSubmenu('?do=dozmod§ion=' . $section, Dictionary::translate('submenu_' . $section, true)); + Dashboard::addSubmenu('?do=dozmod§ion=' . $section, Dictionary::translate('submenu_' . $section)); } } } diff --git a/modules-available/dozmod/pages/actionlog.inc.php b/modules-available/dozmod/pages/actionlog.inc.php index 0b6feb6f..182198c2 100644 --- a/modules-available/dozmod/pages/actionlog.inc.php +++ b/modules-available/dozmod/pages/actionlog.inc.php @@ -92,7 +92,7 @@ class SubPage return $desc; } - private static function addImageHeader() + private static function addImageHeader(): bool { $image = Database::queryFirst('SELECT o.userid AS ouserid, o.firstname AS ofirstname, o.lastname AS olastname, u.userid AS uuserid, u.firstname AS ufirstname, u.lastname AS ulastname, @@ -114,7 +114,7 @@ class SubPage return $image !== false; } - private static function addLectureHeader() + private static function addLectureHeader(): bool { $lecture = Database::queryFirst('SELECT o.userid AS ouserid, o.firstname AS ofirstname, o.lastname AS olastname, u.userid AS uuserid, u.firstname AS ufirstname, u.lastname AS ulastname, diff --git a/modules-available/dozmod/pages/expiredimages.inc.php b/modules-available/dozmod/pages/expiredimages.inc.php index b61b863b..ab563273 100644 --- a/modules-available/dozmod/pages/expiredimages.inc.php +++ b/modules-available/dozmod/pages/expiredimages.inc.php @@ -8,7 +8,7 @@ class SubPage } - private static function loadExpiredImages() + private static function loadExpiredImages(): array { $res = Database::simpleQuery("SELECT b.displayname, own.firstname, own.lastname, own.userid, diff --git a/modules-available/dozmod/pages/mailconfig.inc.php b/modules-available/dozmod/pages/mailconfig.inc.php index 08205f2e..aa03a4d3 100644 --- a/modules-available/dozmod/pages/mailconfig.inc.php +++ b/modules-available/dozmod/pages/mailconfig.inc.php @@ -34,7 +34,7 @@ class SubPage Util::redirect('?do=DozMod§ion=mailconfig'); } - private static function cleanMailArray() + private static function cleanMailArray(): array { $keys = array('host', 'port', 'ssl', 'senderAddress', 'replyTo', 'username', 'password', 'serverName'); $data = array(); diff --git a/modules-available/dozmod/pages/templates.inc.php b/modules-available/dozmod/pages/templates.inc.php index b857115f..b916e14c 100644 --- a/modules-available/dozmod/pages/templates.inc.php +++ b/modules-available/dozmod/pages/templates.inc.php @@ -69,7 +69,7 @@ class SubPage ]); } - private static function forcmp($string) + private static function forcmp(string $string): string { return trim(str_replace("\r\n", "\n", $string)); } diff --git a/modules-available/dozmod/pages/users.inc.php b/modules-available/dozmod/pages/users.inc.php index cdf22b9d..fe00a71b 100644 --- a/modules-available/dozmod/pages/users.inc.php +++ b/modules-available/dozmod/pages/users.inc.php @@ -64,13 +64,13 @@ class SubPage . ' ORDER BY displayname ASC'); $rows = array(); foreach ($res as $row) { - $row['canlogin'] = self::checked($row['canlogin']); + $row['canlogin'] = self::checked((bool)$row['canlogin']); $rows[] = $row; } Render::addTemplate('orglist', array('organizations' => $rows)); } - private static function checked($val) + private static function checked(bool $val): string { if ($val) return 'checked="checked"'; diff --git a/modules-available/eventlog/inc/filterruleprocessor.inc.php b/modules-available/eventlog/inc/filterruleprocessor.inc.php index 24b37444..dd0160d7 100644 --- a/modules-available/eventlog/inc/filterruleprocessor.inc.php +++ b/modules-available/eventlog/inc/filterruleprocessor.inc.php @@ -254,7 +254,7 @@ class FilterRuleProcessor * @param array $filter filter struct [op, arg, result] * @return ?array null if op doesn't match, processed result otherwise */ - private static function matches(string $item, array $filter) + private static function matches(string $item, array $filter): ?array { $ok = false; switch ($filter['op']) { @@ -291,7 +291,7 @@ class FilterRuleProcessor if ($filter['op'] !== 'regex') { $out = [1 => $item]; } - return $out; + return $out ?? []; } private static function fillTemplate(string $template, array $values): string diff --git a/modules-available/eventlog/pages/log.inc.php b/modules-available/eventlog/pages/log.inc.php index bfb16d11..66826b08 100644 --- a/modules-available/eventlog/pages/log.inc.php +++ b/modules-available/eventlog/pages/log.inc.php @@ -26,7 +26,7 @@ class SubPage )); } - private static function typeToIcon($type) + private static function typeToIcon(string $type): string { switch ($type) { case 'info': @@ -40,7 +40,7 @@ class SubPage } } - private static function typeToColor($type) + private static function typeToColor(string $type): string { switch ($type) { case 'warning': diff --git a/modules-available/exams/baseconfig/getconfig.inc.php b/modules-available/exams/baseconfig/getconfig.inc.php index 120bdbff..748149ad 100644 --- a/modules-available/exams/baseconfig/getconfig.inc.php +++ b/modules-available/exams/baseconfig/getconfig.inc.php @@ -1,14 +1,17 @@ $machineUuid), true); + array('uuid' => $uuid), true); if (is_array($res)) return; // Check if exam mode should apply $locations = ConfigHolder::get('SLX_LOCATIONS'); - if ($locations === false) { + if ($locations === null) { $locationIds = []; } else { $locationIds = explode(' ', $locations); @@ -26,6 +29,4 @@ $foofoo = function($machineUuid) { // No saver ConfigHolder::add('SLX_SCREEN_SAVER_TIMEOUT', '0', 1000); } -}; - -$foofoo($uuid); \ No newline at end of file +} \ No newline at end of file diff --git a/modules-available/exams/inc/exams.inc.php b/modules-available/exams/inc/exams.inc.php index da4dec85..86dc6d89 100644 --- a/modules-available/exams/inc/exams.inc.php +++ b/modules-available/exams/inc/exams.inc.php @@ -4,14 +4,11 @@ class Exams { /** - * @param int[] of location ids. must bot be an associative array. - * @return: bool true iff for any of the given location ids an exam is scheduled. + * @param int[] $locationIds of location ids. must be an associative array. + * @return bool true iff for any of the given location ids an exam is scheduled. **/ - public static function isInExamMode($locationIds, &$lectureId = false, &$autoLogin = false) + public static function isInExamMode(array $locationIds, &$lectureId = false, &$autoLogin = false): bool { - if (!is_array($locationIds)) { - $locationIds = array($locationIds); - } if (empty($locationIds)) { $locationIds[] = 0; } diff --git a/modules-available/exams/page.inc.php b/modules-available/exams/page.inc.php index 458ae5b1..d229b883 100644 --- a/modules-available/exams/page.inc.php +++ b/modules-available/exams/page.inc.php @@ -103,7 +103,7 @@ class Page_Exams extends Page } // returns true if user is allowed to edit the exam - protected function userCanEditExam($examid = NULL) + protected function userCanEditExam(string $examid = NULL): bool { if (in_array(0, $this->userEditLocations)) // Trivial case -- don't query if global perms return true; @@ -118,9 +118,12 @@ class Page_Exams extends Page return true; } - // checks if user is allowed to save an exam with all the locations - // needs information if it's add (second para = true) or edit (second para = false) - protected function userCanEditLocation($locationids) { + /** + * checks if user is allowed to save an exam with all the locations + * needs information if it's add (second para = true) or edit (second para = false) + */ + protected function userCanEditLocation(array $locationids): bool + { return empty(array_diff($locationids, $this->userEditLocations)); } @@ -213,7 +216,10 @@ class Page_Exams extends Page return json_encode($out); } - protected function makeExamsForTemplate() + /** + * @return array{exams: array, decollapse: bool} + */ + protected function makeExamsForTemplate(): array { $out = []; $now = time(); @@ -248,7 +254,7 @@ class Page_Exams extends Page return ['exams' => $out, 'decollapse' => $hasCollapsed]; } - protected function makeLectureExamList() + protected function makeLectureExamList(): array { $out = []; $now = time(); @@ -288,7 +294,7 @@ class Page_Exams extends Page ] + $source; } - private function isDateSane($time) + private function isDateSane(int $time): bool { return ($time >= strtotime('-10 years') && $time <= strtotime('+10 years')); } diff --git a/modules-available/locationinfo/api.inc.php b/modules-available/locationinfo/api.inc.php index 14be7718..24919ba1 100644 --- a/modules-available/locationinfo/api.inc.php +++ b/modules-available/locationinfo/api.inc.php @@ -14,7 +14,7 @@ function HandleParameters() $get = Request::get('get', 0, 'string'); $uuid = Request::get('uuid', false, 'string'); - $output = false; + $output = null; if ($get === "timestamp") { $output = array('ts' => getLastChangeTs($uuid)); } elseif ($get === "machines") { @@ -24,7 +24,7 @@ function HandleParameters() $output = array_values($output); } elseif ($get === "config") { $type = InfoPanel::getConfig($uuid, $output); - if ($type === false) { + if ($type === null) { http_response_code(404); die('Panel not found'); } @@ -38,7 +38,7 @@ function HandleParameters() $locationIds = LocationInfo::getLocationsOr404($uuid); $output = LocationInfo::getCalendar($locationIds); } - if ($output !== false) { + if ($output !== null) { Header('Content-Type: application/json; charset=utf-8'); echo json_encode($output); } else { @@ -59,7 +59,7 @@ function HandleParameters() * @param string $paneluuid panels uuid * @return int UNIX_TIMESTAMP */ -function getLastChangeTs($paneluuid) +function getLastChangeTs(string $paneluuid): int { $panel = Database::queryFirst('SELECT lastchange, locationids FROM locationinfo_panel WHERE paneluuid = :paneluuid', compact('paneluuid')); @@ -84,7 +84,7 @@ function getLastChangeTs($paneluuid) * @param int[] $idList list of the location ids. * @return array aggregated PC states */ -function getPcStates($idList, $paneluuid) +function getPcStates(array $idList, string $paneluuid): array { $pcStates = array(); foreach ($idList as $id) { @@ -130,7 +130,7 @@ function getPcStates($idList, $paneluuid) * @param int[] $idList Array list of the locations. * @return array location tree data */ -function getLocationTree($idList) +function getLocationTree(array $idList): array { if (in_array(0, $idList)) { return array_values(Location::getTree()); @@ -140,7 +140,7 @@ function getLocationTree($idList) return findLocations($locations, $idList); } -function findLocations($locations, $idList) +function findLocations(array $locations, array $idList): array { $ret = array(); foreach ($locations as $location) { diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringsType.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringsType.php index 6443d31d..28792929 100644 --- a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringsType.php +++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpEws/ArrayType/ArrayOfStringsType.php @@ -32,6 +32,6 @@ class ArrayOfStringsType extends ArrayType */ public function __toString() { - return $this->String; + return implode(' + ', $this->String); } } diff --git a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php index 21c77cbf..98f23dfa 100644 --- a/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php +++ b/modules-available/locationinfo/exchange-includes/jamesiarmes/PhpNtlm/SoapClient.php @@ -26,6 +26,9 @@ class SoapClient extends \SoapClient */ protected $options; + protected $__last_response; + protected $__last_request_headers; + /** * {@inheritdoc} * @@ -68,7 +71,7 @@ class SoapClient extends \SoapClient /** * {@inheritdoc} */ - public function __doRequest($request, $location, $action, $version, $one_way = 0) + public function __doRequest($request, $location, $action, $version, $oneWay = 0) { $headers = $this->buildHeaders($action); $this->__last_request = $request; diff --git a/modules-available/locationinfo/inc/coursebackend.inc.php b/modules-available/locationinfo/inc/coursebackend.inc.php index 04b5aa92..ea1bebac 100644 --- a/modules-available/locationinfo/inc/coursebackend.inc.php +++ b/modules-available/locationinfo/inc/coursebackend.inc.php @@ -152,10 +152,6 @@ abstract class CourseBackend /** * In case you want to sanitize or otherwise mangle a property for your backend, * override this. - * - * @param string $prop - * @param $value - * @return mixed */ public function mangleProperty(string $prop, $value) { @@ -179,9 +175,9 @@ abstract class CourseBackend * Method for fetching the schedule of the given rooms on a server. * * @param array $requestedLocationIds array of room ID to fetch - * @return array|bool array containing the timetables as value and roomid as key as result, or false on error + * @return array array containing the timetables as value and roomid as key as result, or false on error */ - public final function fetchSchedule(array $requestedLocationIds) + public final function fetchSchedule(array $requestedLocationIds): array { if (empty($requestedLocationIds)) return array(); @@ -236,9 +232,6 @@ abstract class CourseBackend ]); } $backendResponse = $this->fetchSchedulesInternal(array_unique($remoteIds)); - if ($backendResponse === false) { - return false; - } // Fetching might have taken a while, get current time again $NOW = time(); diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php index f03444c2..786ab459 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php @@ -68,7 +68,7 @@ class CourseBackend_Davinci extends CourseBackend * @param string $roomId unique name of the room, as used by davinci * @param \DateTime $startDate start date to fetch * @param \DateTime $endDate end date of range to fetch - * @return array|bool if successful the array representation of the timetable + * @return false|string if successful the array representation of the timetable */ private function fetchRoomRaw(string $roomId, DateTime $startDate, DateTime $endDate) { diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php index 5920231f..df33dadd 100755 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php @@ -173,8 +173,13 @@ class CourseBackend_Exchange extends CourseBackend // Iterate over the events that were found, printing some data for each. foreach ($items as $item) { - $start = new DateTime($item->Start); - $end = new DateTime($item->End); + try { + $start = new DateTime($item->Start); + $end = new DateTime($item->End); + } catch (Exception $e) { + $this->addError("Invalid date range: '{$item->Start}' -> '{$item->End}'", false); + continue; + } $schedules[$roomId][] = array( 'title' => $item->Subject, diff --git a/modules-available/locationinfo/inc/icalcoursebackend.inc.php b/modules-available/locationinfo/inc/icalcoursebackend.inc.php index 44691bb4..838d18b7 100644 --- a/modules-available/locationinfo/inc/icalcoursebackend.inc.php +++ b/modules-available/locationinfo/inc/icalcoursebackend.inc.php @@ -18,16 +18,6 @@ abstract class ICalCourseBackend extends CourseBackend /** @var bool|resource */ private $curlHandle = false; - /** - * Initialize values - * - * @param string $location - * @param bool $verifyCert - * @param bool $verifyHostname - * @param string $authMethod - * @param string $user - * @param string $pass - */ protected function init( string $location, bool $verifyCert, bool $verifyHostname, string $authMethod = 'NONE', string $user = '', string $pass = '') @@ -52,11 +42,18 @@ abstract class ICalCourseBackend extends CourseBackend { if (!$this->isOK()) return null; + + try { + $ical = new ICalParser(['filterDaysBefore' => 7, 'filterDaysAfter' => 7]); + } catch (Exception $e) { + $this->addError('Error instantiating ICalParser: ' . $e->getMessage(), true); + return null; + } + if ($this->curlHandle === false) { $this->curlHandle = curl_init(); } - $ical = new ICalParser(['filterDaysBefore' => 7, 'filterDaysAfter' => 7]); $options = [ CURLOPT_WRITEFUNCTION => function ($ch, $data) use ($ical) { $ical->feedData($data); @@ -119,8 +116,6 @@ abstract class ICalCourseBackend extends CourseBackend /** * Get a usable title from either SUMMARY or DESCRIPTION - * - * @param ICalEvent $event */ protected function toTitle(ICalEvent $event): string { diff --git a/modules-available/locationinfo/inc/icalevent.inc.php b/modules-available/locationinfo/inc/icalevent.inc.php index 0c234f48..c5aea349 100644 --- a/modules-available/locationinfo/inc/icalevent.inc.php +++ b/modules-available/locationinfo/inc/icalevent.inc.php @@ -153,10 +153,10 @@ class ICalEvent /** * Magic getter method * - * @param string $additionalPropertyName + * @param string $additionalPropertyName * @return mixed */ - public function __get($additionalPropertyName) + public function __get(string $additionalPropertyName) { if (array_key_exists($additionalPropertyName, $this->additionalProperties)) { return $this->additionalProperties[$additionalPropertyName]; @@ -167,11 +167,8 @@ class ICalEvent /** * Magic isset method - * - * @param string $name - * @return boolean */ - public function __isset($name) + public function __isset(string $name): bool { return is_null($this->$name) === false; } diff --git a/modules-available/locationinfo/inc/icalparser.inc.php b/modules-available/locationinfo/inc/icalparser.inc.php index 69ff84d0..c6d94a12 100644 --- a/modules-available/locationinfo/inc/icalparser.inc.php +++ b/modules-available/locationinfo/inc/icalparser.inc.php @@ -989,9 +989,8 @@ class ICalParser } return $matches; - } else { - return null; // Ignore this match } + return null; // Ignore this match } /** @@ -1968,9 +1967,8 @@ class ICalParser { if (empty($event['EXDATE_array'])) { return array(); - } else { - $exdates = $event['EXDATE_array']; } + $exdates = $event['EXDATE_array']; $output = array(); $currentTimeZone = $this->defaultTimeZone; diff --git a/modules-available/locationinfo/inc/infopanel.inc.php b/modules-available/locationinfo/inc/infopanel.inc.php index 14d2d949..c0352c26 100644 --- a/modules-available/locationinfo/inc/infopanel.inc.php +++ b/modules-available/locationinfo/inc/infopanel.inc.php @@ -7,16 +7,16 @@ class InfoPanel * Gets the config of the location. * * @param int $locationID ID of the location - * @param mixed $config the panel config will be returned here - * @return string|bool paneltype, false if not exists + * @param ?array $config the panel config will be returned here + * @return ?string panel type, null if not exists */ - public static function getConfig($paneluuid, &$config) + public static function getConfig(string $paneluuid, ?array &$config): ?string { $panel = Database::queryFirst('SELECT panelname, panelconfig, paneltype, locationids FROM locationinfo_panel WHERE paneluuid = :paneluuid', compact('paneluuid')); if ($panel === false) { - return false; + return null; } $config = LocationInfo::defaultPanelConfig($panel['paneltype']); @@ -87,13 +87,10 @@ class InfoPanel * @param array $array location list to populate with machine data * @param bool $withPosition Defines if coords should be included or not. */ - public static function appendMachineData(&$array, $idList = false, $withPosition = false, $withHostname = false) + public static function appendMachineData(?array &$array, array $idList, bool $withPosition = false, bool $withHostname = false): void { - if (empty($array) && $idList === false) + if (empty($array) || empty($idList)) return; - if ($idList === false) { - $idList = array_keys($array); - } $ignoreList = array(); if (Module::isAvailable('runmode')) { @@ -217,12 +214,12 @@ class InfoPanel * @param int[] $idList location ids * @return int[] more location ids */ - private static function getLocationsWithParents($idList) + private static function getLocationsWithParents(array $idList): array { $locations = Location::getLocationsAssoc(); $allIds = $idList; foreach ($idList as $id) { - if (isset($locations[$id]) && isset($locations[$id]['parents'])) { + if (isset($locations[$id]['parents'])) { $allIds = array_merge($allIds, $locations[$id]['parents']); } } @@ -238,9 +235,9 @@ class InfoPanel * 'HourClose' => hh, 'MinutesClose' => mm } * * @param array $openingtime The opening time in the db saved format. - * @return mixed The opening time in the frontend needed format. + * @return array The opening time in the frontend needed format. */ - private static function formatOpeningtime($openingtime) + private static function formatOpeningtime(array $openingtime): array { $result = array(); foreach ($openingtime as $entry) { diff --git a/modules-available/locationinfo/inc/locationinfo.inc.php b/modules-available/locationinfo/inc/locationinfo.inc.php index 004ef881..42829a18 100644 --- a/modules-available/locationinfo/inc/locationinfo.inc.php +++ b/modules-available/locationinfo/inc/locationinfo.inc.php @@ -7,9 +7,9 @@ class LocationInfo * Gets the pc data and returns it's state. * * @param array $pc The pc data from the db. Array('state' => xx, 'lastseen' => xxx) - * @return int pc state + * @return string pc state */ - public static function getPcState($pc) + public static function getPcState(array $pc): string { $lastseen = (int)$pc['lastseen']; $NOW = time(); @@ -22,11 +22,12 @@ class LocationInfo /** * Return list of locationids associated with given panel. + * * @param string $paneluuid panel * @param bool $recursive if true and paneltype == SUMMARY the result is recursive with all child room ids. * @return int[] locationIds */ - public static function getLocationsOr404($paneluuid, $recursive = true) + public static function getLocationsOr404(string $paneluuid, bool $recursive = true): array { $panel = Database::queryFirst('SELECT paneltype, locationids FROM locationinfo_panel WHERE paneluuid = :paneluuid', compact('paneluuid')); @@ -48,7 +49,7 @@ class LocationInfo * @param int $serverId id of server * @param string|array $message error message to set, array of error message struct, null or false clears error. */ - public static function setServerError($serverId, $message) + public static function setServerError(int $serverId, $message): void { if (is_array($message)) { $fatal = false; @@ -86,7 +87,7 @@ class LocationInfo * * @return array Return a default config. */ - public static function defaultPanelConfig($type) + public static function defaultPanelConfig(string $type): array { if ($type === 'DEFAULT') { return array( diff --git a/modules-available/locationinfo/inc/locationinfohooks.inc.php b/modules-available/locationinfo/inc/locationinfohooks.inc.php index ee46260a..8ec217cc 100644 --- a/modules-available/locationinfo/inc/locationinfohooks.inc.php +++ b/modules-available/locationinfo/inc/locationinfohooks.inc.php @@ -5,9 +5,9 @@ class LocationInfoHooks /** * @param string $uuid panel uuid - * @return bool|string panel name if exists, false otherwise + * @return false|string panel name if exists, false otherwise */ - public static function getPanelName($uuid) + public static function getPanelName(string $uuid) { $ret = Database::queryFirst('SELECT panelname FROM locationinfo_panel WHERE paneluuid = :uuid', compact('uuid')); if ($ret === false) @@ -18,14 +18,11 @@ class LocationInfoHooks /** * Hook called by runmode module where we should modify the client config according to our * needs. Disable standby/logout timeouts, enable autologin, set URL. - * - * @param $machineUuid - * @param $panelUuid */ - public static function configHook($machineUuid, $panelUuid) + public static function configHook(string $machineUuid, string $panelUuid): void { $type = InfoPanel::getConfig($panelUuid, $data); - if ($type === false) + if ($type === null) return; // TODO: Invalid panel - what should we do? if ($type === 'URL') { // Check if we should set the insecure SSL mode (accept invalid/self signed certs etc.) @@ -93,10 +90,8 @@ class LocationInfoHooks /** * Turn multiline list into space separated list, removing any * comments (starting with #) - * @param string $list - * @return string */ - private static function mangleList($list) + private static function mangleList(string $list): string { return preg_replace('/\s*(#[^\n]*)?(\n|$)/', ' ', $list); } diff --git a/modules-available/locationinfo/page.inc.php b/modules-available/locationinfo/page.inc.php index 91de0012..5e5b66f0 100644 --- a/modules-available/locationinfo/page.inc.php +++ b/modules-available/locationinfo/page.inc.php @@ -81,7 +81,7 @@ class Page_LocationInfo extends Page $this->showLocationsTable(); break; case 'backends': - $this->showBackendsTable($backends); + $this->showBackendsTable($backends ?? []); break; case 'edit-panel': $this->showPanelConfig(); @@ -130,11 +130,13 @@ class Page_LocationInfo extends Page } } - private function getTime(string $str): int + private static function getTime(string $str): ?int { $str = explode(':', $str); - if (count($str) !== 2) return false; - if ($str[0] < 0 || $str[0] > 23 || $str[1] < 0 || $str[1] > 59) return false; + if (count($str) !== 2) + return null; + if ($str[0] < 0 || $str[0] > 23 || $str[1] < 0 || $str[1] > 59) + return null; return $str[0] * 60 + $str[1]; } @@ -247,7 +249,7 @@ class Page_LocationInfo extends Page } // Permission - $this->assertPanelPermission($paneluuid, 'panel.edit', $params['locationids']); + $this->assertPanelPermission($paneluuid, 'panel.edit', $params['locationids'] ?? []); if ($paneluuid === 'new') { $paneluuid = Util::randomUuid(); @@ -270,6 +272,9 @@ class Page_LocationInfo extends Page Util::redirect('?do=locationinfo'); } + /** + * @return array{config: array, locationids: array} + */ private function preparePanelConfigDefault(): array { // Check locations @@ -325,6 +330,9 @@ class Page_LocationInfo extends Page return array('config' => $conf, 'locationids' => $locationids); } + /** + * @return array{config: array, locationids: array} + */ private function preparePanelConfigUrl(): array { $bookmarkNames = Request::post('bookmarkNames', [], 'array'); @@ -343,8 +351,8 @@ class Page_LocationInfo extends Page 'url' => Request::post('url', 'https://www.bwlehrpool.de/', 'string'), 'insecure-ssl' => Request::post('insecure-ssl', 0, 'int'), 'reload-minutes' => max(0, Request::post('reloadminutes', 0, 'int')), - 'whitelist' => preg_replace("/[\r\n]+/ms", "\n", Request::post('whitelist', '', 'string')), - 'blacklist' => preg_replace("/[\r\n]+/ms", "\n", Request::post('blacklist', '', 'string')), + 'whitelist' => preg_replace("/[\r\n]+/m", "\n", Request::post('whitelist', '', 'string')), + 'blacklist' => preg_replace("/[\r\n]+/m", "\n", Request::post('blacklist', '', 'string')), 'split-login' => Request::post('split-login', 0, 'bool'), 'browser' => Request::post('browser', 'slx-browser', 'string'), 'interactive' => Request::post('interactive', '0', 'bool'), @@ -355,6 +363,9 @@ class Page_LocationInfo extends Page return array('config' => $conf, 'locationids' => []); } + /** + * @return array{config: array, locationids: array} + */ private function preparePanelConfigSummary(): array { // Build json structure @@ -687,7 +698,7 @@ class Page_LocationInfo extends Page } else { $cred->initForRender(); } - $cred->title = Dictionary::translateFile('backend-' . $s, $cred->property, true); + $cred->title = Dictionary::translateFile('backend-' . $s, $cred->property); $cred->helptext = Dictionary::translateFile('backend-' . $s, $cred->property . "_helptext"); $cred->credentialsHtml = Render::parse('server-prop-' . $cred->template, (array)$cred); } @@ -776,9 +787,9 @@ class Page_LocationInfo extends Page $DAYLIST = array_flip(['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']); $new = []; foreach ($array as $row) { - $s = $this->getTime($row['openingtime']); - $e = $this->getTime($row['closingtime']); - if ($s === false || $e === false || $e <= $s) + $s = Page_LocationInfo::getTime($row['openingtime']); + $e = Page_LocationInfo::getTime($row['closingtime']); + if ($s === null || $e === null || $e <= $s) continue; foreach ($row['days'] as $day) { $day = $DAYLIST[$day] ?? -1; @@ -833,10 +844,10 @@ class Page_LocationInfo extends Page // Chain $last++; } else { - $string = Dictionary::translate($DAYLIST[$first], true); + $string = Dictionary::translate($DAYLIST[$first]); if ($first !== $last) { $string .= ($first + 1 === $last ? ",\xe2\x80\x89" : "\xe2\x80\x89-\xe2\x80\x89") - . Dictionary::translate($DAYLIST[$last], true); + . Dictionary::translate($DAYLIST[$last]); } $output[] = $string; $first = $last = $day; @@ -1034,7 +1045,7 @@ class Page_LocationInfo extends Page die('Missing parameter uuid'); } $type = InfoPanel::getConfig($uuid, $config); - if ($type === false) { + if ($type === null) { http_response_code(404); die('Panel with given uuid not found'); } @@ -1082,8 +1093,7 @@ class Page_LocationInfo extends Page /** * @param string|array $panelOrUuid UUID of panel, or array with keys paneltype and locationds - * @param string $permission - * @param int[]|null $additionalLocations + * @param int[] $additionalLocations */ private function assertPanelPermission($panelOrUuid, string $permission, array $additionalLocations = null): void { diff --git a/modules-available/locations/baseconfig/getconfig.inc.php b/modules-available/locations/baseconfig/getconfig.inc.php index f2aa2b46..1bed5de7 100644 --- a/modules-available/locations/baseconfig/getconfig.inc.php +++ b/modules-available/locations/baseconfig/getconfig.inc.php @@ -1,5 +1,8 @@ 20) { ErrorHandler::traceError('Recursive location definition detected at ' . print_r($tree, true)); @@ -121,12 +117,12 @@ class Location /** * @param int|int[] $selected Which locationIDs to mark as selected - * @param int $excludeId Which locationID to explude + * @param int $excludeId Which locationID to exclude * @param bool $addNoParent Add entry for "no location" at the top * @param bool $keepArrayKeys Keep location IDs as array index * @return array Locations */ - public static function getLocations($selected = 0, $excludeId = 0, $addNoParent = false, $keepArrayKeys = false) + public static function getLocations($selected = 0, int $excludeId = 0, bool $addNoParent = false, bool $keepArrayKeys = false): array { if (self::$flatLocationCache === false) { $rows = self::getTree(); @@ -173,7 +169,7 @@ class Location * @param bool $locationTree used in recursive calls, don't pass * @return array list of passed locations plus their children */ - public static function getRecursive($idList, $locationTree = false) + public static function getRecursive($idList, bool $locationTree = false): array { if (!is_array($idList)) { $idList = array($idList); @@ -207,7 +203,7 @@ class Location return $ret; } - public static function buildTree($elements, $parentId = 0) + public static function buildTree(array $elements, int $parentId = 0): array { $branch = array(); $sort = array(); @@ -227,7 +223,7 @@ class Location return $branch; } - private static function flattenTree($tree, $depth = 0) + private static function flattenTree(array $tree, int $depth = 0): array { if ($depth > 20) { ErrorHandler::traceError('Recursive location definition detected at ' . print_r($tree, true)); @@ -249,7 +245,8 @@ class Location return $output; } - public static function isLeaf($locationid) { + public static function isLeaf(int $locationid): bool + { $result = Database::queryFirst('SELECT COUNT(locationid) = 0 AS isleaf ' . 'FROM location ' . 'WHERE parentlocationid = :locationid', ['locationid' => $locationid]); @@ -257,7 +254,7 @@ class Location return (bool)$result; } - public static function extractIds($tree) + public static function extractIds(array $tree): array { $ids = array(); foreach ($tree as $node) { @@ -271,10 +268,11 @@ class Location /** * Get location id for given machine (by uuid) + * * @param string $uuid machine uuid - * @return bool|int locationid, false if no match + * @return false|int locationid, false if no match */ - public static function getFromMachineUuid($uuid) + public static function getFromMachineUuid(string $uuid) { // Only if we have the statistics module which supplies the machine table if (Module::get('statistics') === false) @@ -291,9 +289,9 @@ class Location * * @param string $ip IP address of client * @param bool $honorRoomPlanner consider a fixed location assigned manually by roomplanner - * @return bool|int locationid, or false if no match + * @return false|int locationid, or false if no match */ - public static function getFromIp($ip, $honorRoomPlanner = false) + public static function getFromIp(string $ip, bool $honorRoomPlanner = false) { if (Module::get('statistics') !== false) { // Shortcut - try to use subnetlocationid in machine table @@ -322,17 +320,17 @@ class Location * client, so if it seems too fishy, the UUID will be ignored. * * @param string $ip IP address of client - * @param string $uuid System-UUID of client - * @return int|bool location id, or false if none matches + * @param ?string $uuid System-UUID of client + * @return int|false location id, or false if none matches */ - public static function getFromIpAndUuid($ip, $uuid) + public static function getFromIpAndUuid(string $ip, ?string $uuid) { $locationId = false; $ipLoc = self::getFromIp($ip); if ($ipLoc !== false) { // Set locationId to ipLoc for now, it will be overwritten later if another case applies. $locationId = $ipLoc; - if ($uuid !== false) { + if ($uuid !== null) { // Machine ip maps to a location, and we have a client supplied uuid (which might not be known if the client boots for the first time) $uuidLoc = self::getFromMachineUuid($uuid); if (self::isFixedLocationValid($uuidLoc, $ipLoc)) { @@ -343,7 +341,7 @@ class Location return $locationId; } - public static function isFixedLocationValid($uuidLoc, $ipLoc) + public static function isFixedLocationValid($uuidLoc, $ipLoc): bool { if ($uuidLoc === false) return false; @@ -366,12 +364,10 @@ class Location /** * Get all location IDs from the given location up to the root. * - * @param int $locationId * @return int[] location ids, including $locationId */ - public static function getLocationRootChain($locationId) + public static function getLocationRootChain(int $locationId): array { - $locationId = (int)$locationId; if (self::$assocLocationCache === false) { self::getLocationsAssoc(); } @@ -385,7 +381,7 @@ class Location /** * @return array list of subnets as numeric array */ - public static function getSubnets() + public static function getSubnets(): array { $res = Database::simpleQuery("SELECT startaddr, endaddr, locationid FROM subnet"); $subnets = array(); @@ -397,9 +393,9 @@ class Location } /** - * @return array|bool assoc array mapping from locationid to subnets + * @return array assoc array mapping from locationid to subnets */ - public static function getSubnetsByLocation($recursive = false) + public static function getSubnetsByLocation($recursive = false): array { $locs = self::getLocationsAssoc(); $subnets = self::getSubnets(); @@ -433,9 +429,9 @@ class Location * random one will be returned. * * @param string $ip IP to look up - * @return bool|int locationid ip matches, false = no match + * @return false|int locationid ip matches, false = no match */ - public static function mapIpToLocation($ip) + public static function mapIpToLocation(string $ip) { if (self::$subnetMapCache === false) { self::$subnetMapCache = self::getSubnetsByLocation(); @@ -464,7 +460,10 @@ class Location return (int)$best; } - public static function updateMapIpToLocation($uuid, $ip) + /** + * @return false|int newly determined location + */ + public static function updateMapIpToLocation(string $uuid, string $ip) { $loc = self::mapIpToLocation($ip); if ($loc === false) { diff --git a/modules-available/locations/inc/locationhooks.inc.php b/modules-available/locations/inc/locationhooks.inc.php index 5ce3bbfe..fca85575 100644 --- a/modules-available/locations/inc/locationhooks.inc.php +++ b/modules-available/locations/inc/locationhooks.inc.php @@ -6,7 +6,7 @@ class LocationHooks /** * Resolve baseconfig id to locationid -- noop in this case */ - public static function baseconfigLocationResolver($id) + public static function baseconfigLocationResolver(int $id): int { return $id; } @@ -15,7 +15,7 @@ class LocationHooks * Hook to get inheritance tree for all config vars * @param int $id Locationid currently being edited */ - public static function baseconfigInheritance($id) + public static function baseconfigInheritance(int $id): array { $locs = Location::getLocationsAssoc(); if ($locs === false || !isset($locs[$id])) diff --git a/modules-available/locations/inc/locationutil.inc.php b/modules-available/locations/inc/locationutil.inc.php index 907bcc99..17608203 100644 --- a/modules-available/locations/inc/locationutil.inc.php +++ b/modules-available/locations/inc/locationutil.inc.php @@ -159,19 +159,17 @@ class LocationUtil } if (empty($return)) return $return; - if ($locationId === 0) { + if ($locationId === 0) return array_values($return); - } else { - return $return[$locationId]; - } + return $return[$locationId]; } - private static function overlap($net1, $net2) + private static function overlap(array $net1, array $net2): bool { return ($net1['startaddr'] <= $net2['endaddr'] && $net1['endaddr'] >= $net2['startaddr']); } - public static function rangeToLongVerbose($start, $end) + public static function rangeToLongVerbose(int $start, int $end): ?array { $result = self::rangeToLong($start, $end); list($startLong, $endLong) = $result; @@ -182,15 +180,15 @@ class LocationUtil Message::addWarning('main.value-invalid', 'end addr', $start); } if ($startLong === false || $endLong === false) - return false; + return null; if ($startLong > $endLong) { Message::addWarning('main.value-invalid', 'range', $start . ' - ' . $end); - return false; + return null; } return $result; } - public static function rangeToLong($start, $end) + public static function rangeToLong(int $start, int $end): array { $startLong = ip2long($start); $endLong = ip2long($end); diff --git a/modules-available/locations/inc/openingtimes.inc.php b/modules-available/locations/inc/openingtimes.inc.php index 18e25063..74dae7c3 100644 --- a/modules-available/locations/inc/openingtimes.inc.php +++ b/modules-available/locations/inc/openingtimes.inc.php @@ -11,9 +11,8 @@ class OpeningTimes * "openingtime": "8:00", * "closingtime": "20:00" * } - * @return array|null */ - public static function forLocation(int $locationId) + public static function forLocation(int $locationId): ?array { static $openingTimesList = false; if ($openingTimesList === false) { diff --git a/modules-available/locations/pages/cleanup.inc.php b/modules-available/locations/pages/cleanup.inc.php index a7562c50..423d6a6b 100644 --- a/modules-available/locations/pages/cleanup.inc.php +++ b/modules-available/locations/pages/cleanup.inc.php @@ -3,7 +3,7 @@ class SubPage { - public static function doPreprocess($action) + public static function doPreprocess($action): bool { if ($action === 'resetmachines') { self::resetMachines(); @@ -16,7 +16,7 @@ class SubPage return false; } - public static function doRender($action) + public static function doRender($action): bool { $list = self::loadForLocation(); if ($list === false) @@ -29,7 +29,7 @@ class SubPage return true; } - public static function doAjax($action) + public static function doAjax($action): bool { return false; } diff --git a/modules-available/locations/pages/details.inc.php b/modules-available/locations/pages/details.inc.php index e75aaf7d..279eee44 100644 --- a/modules-available/locations/pages/details.inc.php +++ b/modules-available/locations/pages/details.inc.php @@ -3,24 +3,25 @@ class SubPage { - public static function doPreprocess($action) + public static function doPreprocess($action): bool { if ($action === 'updatelocation') { self::updateLocation(); return true; - } else if ($action === 'updateOpeningtimes') { + } + if ($action === 'updateOpeningtimes') { self::updateOpeningTimes(); return true; } return false; } - public static function doRender($action) + public static function doRender($action): bool { return false; } - public static function doAjax($action) + public static function doAjax($action): bool { if ($action === 'showlocation') { self::ajaxShowLocation(); @@ -172,7 +173,7 @@ class SubPage Util::redirect('?do=Locations'); } - private static function updateLocationData($location) + private static function updateLocationData(array $location): bool { $locationId = (int)$location['locationid']; $newParent = Request::post('parentlocationid', false, 'integer'); @@ -216,7 +217,7 @@ class SubPage return $newParent != $location['parentlocationid']; } - private static function updateLocationSubnets() + private static function updateLocationSubnets(): bool { $locationId = Request::post('locationid', false, 'integer'); if (!User::hasPermission('location.edit.subnets', $locationId)) @@ -257,7 +258,7 @@ class SubPage continue; } $range = LocationUtil::rangeToLongVerbose($start, $end); - if ($range === false) + if ($range === null) continue; list($startLong, $endLong) = $range; if ($stmt->execute(array('id' => $subnetid, 'start' => $startLong, 'end' => $endLong))) { @@ -275,7 +276,7 @@ class SubPage return $change; } - private static function addNewLocationSubnets($location) + private static function addNewLocationSubnets(array $location): bool { $locationId = (int)$location['locationid']; if (!User::hasPermission('location.edit.subnets', $locationId)) diff --git a/modules-available/locations/pages/locations.inc.php b/modules-available/locations/pages/locations.inc.php index 8ba4793e..78818328 100644 --- a/modules-available/locations/pages/locations.inc.php +++ b/modules-available/locations/pages/locations.inc.php @@ -3,7 +3,7 @@ class SubPage { - public static function doPreprocess($action) + public static function doPreprocess($action): bool { if ($action === 'addlocations') { self::addLocations(); @@ -12,7 +12,7 @@ class SubPage return false; } - public static function doRender($getAction) + public static function doRender($getAction): bool { if ($getAction === false) { if (User::hasPermission('location.view')) { @@ -32,7 +32,7 @@ class SubPage return false; } - public static function doAjax($action) + public static function doAjax($action): bool { return false; } diff --git a/modules-available/locations/pages/subnets.inc.php b/modules-available/locations/pages/subnets.inc.php index e568c655..7628486b 100644 --- a/modules-available/locations/pages/subnets.inc.php +++ b/modules-available/locations/pages/subnets.inc.php @@ -3,7 +3,7 @@ class SubPage { - public static function doPreprocess($action) + public static function doPreprocess(string $action): bool { if ($action === 'updatesubnets') { self::updateSubnets(); @@ -42,7 +42,7 @@ class SubPage continue; } $range = LocationUtil::rangeToLongVerbose($start, $end); - if ($range === false) + if ($range === null) continue; list($startLong, $endLong) = $range; if ($stmt->execute(compact('startLong', 'endLong', 'loc', 'subnetid'))) { @@ -59,7 +59,7 @@ class SubPage Util::redirect('?do=Locations'); } - public static function doRender($getAction) + public static function doRender($getAction): bool { if ($getAction === false) { User::assertPermission('subnets.edit', NULL, '?do=locations'); @@ -81,7 +81,7 @@ class SubPage return false; } - public static function doAjax($action) + public static function doAjax($action): bool { return false; } diff --git a/modules-available/main/hooks/cron.inc.php b/modules-available/main/hooks/cron.inc.php index 747115c2..5b20b6d0 100644 --- a/modules-available/main/hooks/cron.inc.php +++ b/modules-available/main/hooks/cron.inc.php @@ -10,6 +10,8 @@ case 3: case 4: Database::exec("DELETE FROM callback WHERE (UNIX_TIMESTAMP() - 86400) > dateline"); break; +default: + // Do nothing } Trigger::checkCallbacks(); diff --git a/modules-available/main/hooks/translation.inc.php b/modules-available/main/hooks/translation.inc.php index 7590dcb6..28247374 100644 --- a/modules-available/main/hooks/translation.inc.php +++ b/modules-available/main/hooks/translation.inc.php @@ -18,11 +18,8 @@ $HANDLER['subsections'] = array( * Global tags. * This just returns the union of global tags of all languages, as there is no * way to define a definite set of required global tags. - * - * @param Module $module - * @return array dem tags */ -$HANDLER['grep_global-tags'] = function($module) { +$HANDLER['grep_global-tags'] = function(Module $module): array { $want = array(); foreach (Dictionary::getLanguages() as $lang) { $want += Dictionary::getArray($module->getIdentifier(), 'global-tags', $lang); diff --git a/modules-available/main/page.inc.php b/modules-available/main/page.inc.php index 016a510d..b0d7d125 100644 --- a/modules-available/main/page.inc.php +++ b/modules-available/main/page.inc.php @@ -33,7 +33,7 @@ class Page_Main extends Page } // Update warning state - Property::setNeedsSetup($needSetup ? 1 : 0); + Property::setNeedsSetup($needSetup); } protected function doAjax() diff --git a/modules-available/minilinux/inc/linuxbootentryhook.inc.php b/modules-available/minilinux/inc/linuxbootentryhook.inc.php index 03d7f11f..56b3db69 100644 --- a/modules-available/minilinux/inc/linuxbootentryhook.inc.php +++ b/modules-available/minilinux/inc/linuxbootentryhook.inc.php @@ -10,9 +10,9 @@ class LinuxBootEntryHook extends BootEntryHook { - public function name() + public function name(): string { - return Dictionary::translateFileModule('minilinux', 'module', 'module_name', true); + return Dictionary::translateFileModule('minilinux', 'module', 'module_name'); } public function extraFields(): array @@ -44,7 +44,7 @@ class LinuxBootEntryHook extends BootEntryHook $array = []; $array[] = new HookEntryGroup($this->name(), [ new HookEntry('default', - Dictionary::translateFileModule('minilinux', 'module', 'default_boot_entry', true), + Dictionary::translateFileModule('minilinux', 'module', 'default_boot_entry'), MiniLinux::updateCurrentBootSetting()) ]); $branches = Database::queryAll('SELECT sourceid, branchid, title FROM minilinux_branch ORDER BY title'); @@ -56,7 +56,7 @@ class LinuxBootEntryHook extends BootEntryHook new HookEntry($branch['branchid'], $branch['branchid'] . ' ' . Dictionary::translateFileModule('minilinux', 'module', - 'latest_of_branch', true), + 'latest_of_branch'), true), ]; foreach ($versions[$branch['branchid']] as $version) { @@ -64,7 +64,7 @@ class LinuxBootEntryHook extends BootEntryHook $title = $version['versionid'] . ' ' . $version['title']; if (!$valid) { $title .= ' ' . Dictionary::translateFileModule('minilinux', 'module', - 'not_installed_hint', true); + 'not_installed_hint'); } $group[] = new HookEntry($version['versionid'], $title, $valid); } @@ -75,10 +75,9 @@ class LinuxBootEntryHook extends BootEntryHook } /** - * @param $localData - * @return BootEntry the actual boot entry instance for given entry, false if invalid id + * @return ?BootEntry the actual boot entry instance for given entry, false if invalid id */ - public function getBootEntryInternal($localData): BootEntry + public function getBootEntryInternal(array $localData): ?BootEntry { $id = $localData['id']; if ($id === 'default') { // Special case @@ -183,7 +182,7 @@ class LinuxBootEntryHook extends BootEntryHook return $exec; } - public function isValidId($id) + public function isValidId(string $id): bool { if ($id === 'default') return true; // Meta-version that links to whatever the default is set to diff --git a/modules-available/minilinux/inc/minilinux.inc.php b/modules-available/minilinux/inc/minilinux.inc.php index daae7048..9c1b9011 100644 --- a/modules-available/minilinux/inc/minilinux.inc.php +++ b/modules-available/minilinux/inc/minilinux.inc.php @@ -19,7 +19,7 @@ class MiniLinux * Query all known sources for metadata * @return int number of sources query was just initialized for */ - public static function updateList() + public static function updateList(): int { $stamp = time(); $last = Property::get(self::PROPERTY_KEY_FETCHTIME); @@ -49,10 +49,11 @@ class MiniLinux /** * Called when downloading metadata from a specific update source is finished - * @param mixed $task task structure + * + * @param array $task task structure * @param string $sourceid see minilinux_source table */ - public static function listDownloadCallback($task, $sourceid) + public static function listDownloadCallback(array $task, string $sourceid): void { if (!Taskmanager::isFinished($task)) return; @@ -177,7 +178,7 @@ class MiniLinux ]); } - private static function isValidIdPart($str) + private static function isValidIdPart(string $str): bool { return preg_match('/^[a-z0-9_\-]+$/', $str) > 0; } @@ -186,10 +187,10 @@ class MiniLinux * Download of specific version */ - public static function validateDownloadTask($versionid, $taskid) + public static function validateDownloadTask(string $versionid, ?string $taskid): ?string { if ($taskid === null) - return false; + return null; $task = Taskmanager::status($taskid); if (Taskmanager::isTask($task) && !Taskmanager::isFailed($task) && (is_dir(CONFIG_HTTP_DIR . '/' . $versionid) || !Taskmanager::isFinished($task))) @@ -197,15 +198,13 @@ class MiniLinux Database::exec('UPDATE minilinux_version SET taskid = NULL WHERE versionid = :versionid AND taskid = :taskid', ['versionid' => $versionid, 'taskid' => $taskid]); - return false; + return null; } /** * Download the files for the given version id - * @param $versionid - * @return bool */ - public static function downloadVersion($versionid) + public static function downloadVersion(string $versionid): ?string { $ver = Database::queryFirst('SELECT s.url, s.pubkey, v.versionid, v.taskid, v.data FROM minilinux_version v INNER JOIN minilinux_branch b USING (branchid) @@ -213,17 +212,17 @@ class MiniLinux WHERE versionid = :versionid', ['versionid' => $versionid]); if ($ver === false) - return false; + return null; $taskid = self::validateDownloadTask($versionid, $ver['taskid']); - if ($taskid !== false) + if ($taskid !== null) return $taskid; $data = json_decode($ver['data'], true); if (!is_array($data)) { EventLog::warning("Cannot download Linux '$versionid': Corrupted meta data.", $ver['data']); - return false; + return null; } if (empty($data['files'])) - return false; + return null; $list = []; $legacyDir = preg_replace(',^[^/]*/,', '', $versionid); foreach ($data['files'] as $file) { @@ -242,6 +241,7 @@ class MiniLinux Database::exec('LOCK TABLES minilinux_version WRITE'); $aff = Database::exec('UPDATE minilinux_version SET taskid = :taskid WHERE versionid = :versionid AND taskid IS NULL', ['taskid' => $uuid, 'versionid' => $versionid]); + $task = false; if ($aff > 0) { $task = Taskmanager::submit('DownloadFiles', [ 'id' => $uuid, @@ -252,10 +252,8 @@ class MiniLinux if (Taskmanager::isFailed($task)) { $task = false; } else { - $task = $task['id']; + $task = (string)$task['id']; } - } else { - $task = false; } Database::exec('UNLOCK TABLES'); if ($task !== false) { @@ -269,7 +267,7 @@ class MiniLinux return $task; } - public static function fileToId($versionid, $fileName) + public static function fileToId(string $versionid, string $fileName): string { return 'x' . substr(md5($fileName . $versionid), 0, 8); } @@ -282,7 +280,7 @@ class MiniLinux * Generate messages regarding setup und update availability. * @return bool true if severe problems were found, false otherwise */ - public static function generateUpdateNotice() + public static function generateUpdateNotice(): bool { // Messages in here are with module name, as required by the // main-warning hook. @@ -325,7 +323,7 @@ class MiniLinux * actually installed locally. * @return bool true if installed locally, false otherwise */ - public static function updateCurrentBootSetting() + public static function updateCurrentBootSetting(): bool { $default = Property::get(self::PROPERTY_DEFAULT_BOOT); if ($default === false) @@ -371,7 +369,7 @@ class MiniLinux } } - public static function queryAllVersionsByBranch() + public static function queryAllVersionsByBranch(): array { $list = []; $res = Database::simpleQuery('SELECT branchid, versionid, title, Length(description) AS desclen, @@ -401,11 +399,12 @@ class MiniLinux * Check whether an optionally required stage4 is available. * Return true if there is no stage4, otherwise check filesystem, * or try to request from local dnbd3-server. + * * @param array $data decoded data column from minilinux_version * @param string[] $errors in array of error messages if not available * @return bool true if stage4 is available or none required */ - public static function checkStage4($data, &$errors = false) + public static function checkStage4(array $data, &$errors = false): bool { $errors = []; $image = false; @@ -506,8 +505,6 @@ class MiniLinux if (!isset($data['id'])) continue; $id = self::resolveEntryId($data['id']); - if ($id === false) - continue; $new = [ 'entryids' => [$row['entryid']], 'menus' => explode(',', $row['menus'] ?? ''), @@ -546,7 +543,7 @@ class MiniLinux * Take a configured versionid from a bootentry (serversetup module) and translate * it, in case it's "default" or just a branch name. */ - private static function resolveEntryId($id) + private static function resolveEntryId(string $id): string { if ($id === 'default') { // Special case $id = Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT_EFFECTIVE); diff --git a/modules-available/minilinux/page.inc.php b/modules-available/minilinux/page.inc.php index 2099b8c5..349bbfad 100644 --- a/modules-available/minilinux/page.inc.php +++ b/modules-available/minilinux/page.inc.php @@ -25,8 +25,8 @@ class Page_MiniLinux extends Page } User::assertPermission('view'); - Dashboard::addSubmenu('?do=minilinux', Dictionary::translate('menu-versions', true)); - Dashboard::addSubmenu('?do=minilinux&show=sources', Dictionary::translate('menu-sources', true)); + Dashboard::addSubmenu('?do=minilinux', Dictionary::translate('menu-versions')); + Dashboard::addSubmenu('?do=minilinux&show=sources', Dictionary::translate('menu-sources')); } protected function doRender() @@ -107,7 +107,7 @@ class Page_MiniLinux extends Page } } - private function renderVersionList($versions, $usage) + private function renderVersionList(array $versions, array $usage): string { $def = Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT); //$eff = Property::get(MiniLinux::PROPERTY_DEFAULT_BOOT_EFFECTIVE); @@ -152,7 +152,7 @@ class Page_MiniLinux extends Page } $data['versionid'] = $versionid; $data['dltask'] = MiniLinux::validateDownloadTask($versionid, $ver['taskid']); - $data['verify_button'] = !$verify && $data['dltask'] === false; + $data['verify_button'] = !$verify && $data['dltask'] === null; if (is_array($data['files'])) { $valid = true; $sort = []; @@ -176,7 +176,7 @@ class Page_MiniLinux extends Page if (isset($file['mtime'])) { $file['mtime_s'] = Util::prettyTime($file['mtime']); } - if ($data['dltask']) { + if ($data['dltask'] !== null) { $file['fileid'] = MiniLinux::fileToId($versionid, $file['name']); } } @@ -191,7 +191,7 @@ class Page_MiniLinux extends Page MiniLinux::setInstalledState($versionid, true); } } - if ($data['dltask'] !== false || $ver['installed']) { + if ($data['dltask'] !== null || $ver['installed']) { MiniLinux::checkStage4($data, $data['s4_errors']); } $data['changelog'] = Util::markup($ver['description'] ?? ''); @@ -204,7 +204,7 @@ class Page_MiniLinux extends Page const FILE_CHECKSUM_BAD = 3; const FILE_NOT_READABLE = 4; - private function getFileState($versionid, $file, $verify) + private function getFileState(string $versionid, array $file, bool $verify): int { $path = CONFIG_HTTP_DIR . '/' . $versionid . '/' . $file['name']; if (!is_file($path)) @@ -231,15 +231,15 @@ class Page_MiniLinux extends Page { switch ($state) { case self::FILE_CHECKSUM_BAD: - return Dictionary::translate('file-checksum-bad', true); + return Dictionary::translate('file-checksum-bad'); case self::FILE_SIZE_MISMATCH: - return Dictionary::translate('file-size-mismatch', true); + return Dictionary::translate('file-size-mismatch'); case self::FILE_MISSING: - return Dictionary::translate('file-missing', true); + return Dictionary::translate('file-missing'); case self::FILE_NOT_READABLE: - return Dictionary::translate('file-not-readable', true); + return Dictionary::translate('file-not-readable'); case self::FILE_OK: - return Dictionary::translate('file-ok', true); + return Dictionary::translate('file-ok'); } return '???'; } @@ -252,7 +252,7 @@ class Page_MiniLinux extends Page die('No version'); } $task = MiniLinux::downloadVersion($version); - if ($task === false) { + if ($task === null) { Message::addError('no-such-version', $version); Message::renderList(); } else { diff --git a/modules-available/news/page.inc.php b/modules-available/news/page.inc.php index bb74c711..291f15fc 100644 --- a/modules-available/news/page.inc.php +++ b/modules-available/news/page.inc.php @@ -67,18 +67,18 @@ class Page_News extends Page User::assertPermission('access-page'); /* and also the news (or help) with the given id */ - $newsId = Request::get('newsid', false, 'int'); - $pageType = Request::get('type', false, 'string'); + $newsId = Request::get('newsid', null, 'int'); + $pageType = Request::get('type', null, 'string'); $this->locationId = Request::get('locationid', 0, 'int'); - if ($pageType === false && $newsId === false) { + if ($pageType === null && $newsId === null) { Util::redirect('?do=news&type=news&locationid=' . $this->locationId); } - $this->pageType = $pageType === false ? 'news' : $pageType; - $this->loadNews($newsId, $pageType); + $this->pageType = $pageType ?? 'news'; + $this->loadNews($newsId); foreach (self::TYPES as $type => $entry) { Dashboard::addSubmenu('?do=news&type=' . $type . '&locationid=' . $this->locationId, - Dictionary::translate('type_' . $type, true)); + Dictionary::translate('type_' . $type)); } } else { @@ -103,7 +103,7 @@ class Page_News extends Page } elseif ($action === 'delete') { // delete it User::assertPermission("$pageType.delete", $this->locationId); - $this->delNews(Request::post('newsid', false, 'int'), $pageType); + $this->delNews(Request::post('newsid', Request::REQUIRED, 'int'), $pageType); } else { // unknown action, redirect user Message::addError('invalid-action', $action); @@ -149,7 +149,7 @@ class Page_News extends Page $data = array( 'withTitle' => self::TYPES[$this->pageType]['headline'], - 'newsTypeName' => Dictionary::translate('type_' . $this->pageType, true), + 'newsTypeName' => Dictionary::translate('type_' . $this->pageType), 'dateline_s' => Util::prettyTime($this->newsDateline), 'expires_s' => $this->formatExpires($this->newsExpires), 'currentContent' => $this->newsContent, @@ -189,7 +189,7 @@ class Page_News extends Page Render::addTemplate('page-news', $data); } - private function formatExpires($ts) + private function formatExpires(int $ts): string { if ($ts - 86400 * 365 * 5 > time()) return '-'; @@ -199,13 +199,12 @@ class Page_News extends Page /** * Loads the news with the given ID into the form. * - * @param int $newsId ID of the news to be shown. - * @param string $pageType type if news id is not given. + * @param ?int $newsId ID of the news to be shown, or latest if null */ - private function loadNews($newsId, $pageType) + private function loadNews(?int $newsId): void { // check to see if we need to request a specific newsid - if ($newsId !== false) { + if ($newsId !== null) { $row = Database::queryFirst('SELECT newsid, title, content, dateline, expires, type FROM vmchooser_pages WHERE newsid = :newsid LIMIT 1', [ 'newsid' => $newsId, @@ -217,7 +216,7 @@ class Page_News extends Page $str = $this->locationId === 0 ? 'IS NULL' : ' = ' . $this->locationId; $row = Database::queryFirst("SELECT newsid, title, content, dateline, expires, type FROM vmchooser_pages WHERE type = :type AND locationid $str AND expires > UNIX_TIMESTAMP() ORDER BY dateline DESC LIMIT 1", [ - 'type' => $pageType, + 'type' => $this->pageType, ]); } if ($row === false) @@ -235,7 +234,7 @@ class Page_News extends Page /** * Save the given $newsTitle and $newsContent as POST'ed into the database. */ - private function saveNews($pageType) + private function saveNews(string $pageType): bool { // check if news content were set by the user $newsTitle = Request::post('news-title', '', 'string'); @@ -290,18 +289,12 @@ class Page_News extends Page * @param int $newsId ID of the entry to be deleted. * @param string $pageType type of news to be deleted. Must match the ID, otherwise do nothing. */ - private function delNews($newsId, $pageType) + private function delNews(int $newsId, string $pageType): void { - // sanity check: is newsId even numeric? - if (!is_numeric($newsId)) { - Message::addError('main.value-invalid', 'newsid', $newsId); - } else { - // check passed - do delete - Database::exec('DELETE FROM vmchooser_pages WHERE newsid = :newsid AND type = :type LIMIT 1', array( - 'newsid' => $newsId, - 'type' => $pageType, - )); - Message::addSuccess('news-del-success'); - } + Database::exec('DELETE FROM vmchooser_pages WHERE newsid = :newsid AND type = :type LIMIT 1', array( + 'newsid' => $newsId, + 'type' => $pageType, + )); + Message::addSuccess('news-del-success'); } } diff --git a/modules-available/permissionmanager/hooks/translation-global.inc.php b/modules-available/permissionmanager/hooks/translation-global.inc.php index 4810a719..cf2166bc 100644 --- a/modules-available/permissionmanager/hooks/translation-global.inc.php +++ b/modules-available/permissionmanager/hooks/translation-global.inc.php @@ -18,11 +18,8 @@ if (file_exists('modules/' . $moduleName . '/permissions/permissions.json')) { /** * Configuration categories. - * - * @param \Module $module - * @return array */ - $HANDLER['grep_permissions'] = function ($module) { + $HANDLER['grep_permissions'] = function (Module $module): array { $file = 'modules/' . $module->getIdentifier() . '/permissions/permissions.json'; if (!file_exists($file)) return []; diff --git a/modules-available/permissionmanager/inc/getpermissiondata.inc.php b/modules-available/permissionmanager/inc/getpermissiondata.inc.php index ead1e020..a51619e0 100644 --- a/modules-available/permissionmanager/inc/getpermissiondata.inc.php +++ b/modules-available/permissionmanager/inc/getpermissiondata.inc.php @@ -11,7 +11,7 @@ class GetPermissionData * * @return array array of users (each with userid, username and roles (each with roleid and rolename)) */ - public static function getUserData() + public static function getUserData(): array { $res = Database::simpleQuery("SELECT user.userid AS userid, user.login AS login, role.rolename AS rolename, role.roleid AS roleid FROM user @@ -42,7 +42,7 @@ class GetPermissionData * * @return array array of locations (each including the roles that have permissions for them) */ - public static function getLocationData() + public static function getLocationData(): array { $res = Database::simpleQuery("SELECT role.roleid AS roleid, rolename, GROUP_CONCAT(COALESCE(locationid, 0)) AS locationids FROM role INNER JOIN role_x_location ON role.roleid = role_x_location.roleid GROUP BY roleid ORDER BY rolename ASC"); @@ -70,7 +70,7 @@ class GetPermissionData * @param int $flags Bitmask specifying additional data to fetch (WITH_* constants of this class) * @return array array roles (each with roleid and rolename) */ - public static function getRoles($flags = 0) + public static function getRoles(int $flags = 0): array { $cols = $joins = ''; if ($flags & self::WITH_USER_COUNT) { @@ -93,15 +93,15 @@ class GetPermissionData * Get permissions and locations for a given role. * * @param string $roleid id of the role - * @return array|false array containing an array of permissions and an array of locations, false if not found + * @return ?array array containing an array of permissions and an array of locations, null if not found */ - public static function getRoleData($roleid) + public static function getRoleData(string $roleid): ?array { $data = self::getRole($roleid); $res = Database::simpleQuery("SELECT roleid, locationid FROM role_x_location WHERE roleid = :roleid", array("roleid" => $roleid)); if ($res === false) - return false; + return null; $data["locations"] = array(); foreach ($res as $row) { $data["locations"][] = $row['locationid']; diff --git a/modules-available/permissionmanager/inc/permissiondbupdate.inc.php b/modules-available/permissionmanager/inc/permissiondbupdate.inc.php index 0cd89b3a..49988420 100644 --- a/modules-available/permissionmanager/inc/permissiondbupdate.inc.php +++ b/modules-available/permissionmanager/inc/permissiondbupdate.inc.php @@ -9,14 +9,14 @@ class PermissionDbUpdate * @param int[] $users userids * @param int[] $roles roleids */ - public static function addRoleToUser($users, $roles) + public static function addRoleToUser(array $users, array $roles): int { if (empty($users) || empty($roles)) return 0; - $arg = array(); + $arg = []; foreach ($users AS $userid) { foreach ($roles AS $roleid) { - $arg[] = compact('userid', 'roleid'); + $arg[] = ['userid' => $userid, 'roleid' => $roleid]; } } return Database::exec("INSERT IGNORE INTO role_x_user (userid, roleid) VALUES :arg", @@ -29,12 +29,12 @@ class PermissionDbUpdate * @param int[] $users userids * @param int[] $roles roleids */ - public static function removeRoleFromUser($users, $roles) + public static function removeRoleFromUser(array $users, array $roles): int { if (empty($users) || empty($roles)) return 0; $query = "DELETE FROM role_x_user WHERE userid IN (:users) AND roleid IN (:roles)"; - return Database::exec($query, array("users" => $users, "roles" => $roles)); + return Database::exec($query, ["users" => $users, "roles" => $roles]); } /** @@ -44,7 +44,7 @@ class PermissionDbUpdate * @param int[] $users list of user ids * @param int[] $roles list of role ids */ - public static function setRolesForUser($users, $roles) + public static function setRolesForUser(array $users, array $roles): int { $count = Database::exec("DELETE FROM role_x_user WHERE userid in (:users) AND roleid NOT IN (:roles)", compact('users', 'roles')); @@ -56,7 +56,7 @@ class PermissionDbUpdate * * @param int $roleid roleid */ - public static function deleteRole($roleid) + public static function deleteRole(int $roleid): int { return Database::exec("DELETE FROM role WHERE roleid = :roleid", array("roleid" => $roleid)); } @@ -69,7 +69,8 @@ class PermissionDbUpdate * @param string[] $permissions array of permissions * @param int|null $roleId roleid or null if the role does not exist yet */ - public static function saveRole($roleName, $roleDescription, $locations, $permissions, $roleId = null) + public static function saveRole(string $roleName, string $roleDescription, array $locations, array $permissions, + ?int $roleId = null): void { foreach ($permissions as &$permission) { $permission = strtolower($permission); @@ -92,14 +93,14 @@ class PermissionDbUpdate if (!empty($locations)) { $arg = array_map(function ($loc) use ($roleId) { - return compact('roleId', 'loc'); + return ['roleId' => $roleId, 'loc' => $loc]; }, $locations); Database::exec("INSERT IGNORE INTO role_x_location (roleid, locationid) VALUES :arg", ['arg' => $arg]); } if (!empty($permissions)) { $arg = array_map(function ($perm) use ($roleId) { - return compact('roleId', 'perm'); + return ['roleId' => $roleId, 'perm' => $perm]; }, $permissions); Database::exec("INSERT IGNORE INTO role_x_permission (roleid, permissionid) VALUES :arg", ['arg' => $arg]); } diff --git a/modules-available/permissionmanager/inc/permissionutil.inc.php b/modules-available/permissionmanager/inc/permissionutil.inc.php index d3f20b4f..170fd699 100644 --- a/modules-available/permissionmanager/inc/permissionutil.inc.php +++ b/modules-available/permissionmanager/inc/permissionutil.inc.php @@ -14,7 +14,7 @@ class PermissionUtil * @param string|false $wildcard if $permission is a wildcard string this returns the matching variant * @param int|false $wclen if $permission is a wildcard string, this is the length of the matching variant */ - private static function makeComparisonVariants($permission, &$compare, &$wildcard, &$wclen) + private static function makeComparisonVariants($permission, ?array &$compare, &$wildcard, &$wclen): void { if (!is_array($permission)) { $permission = explode('.', $permission); @@ -46,12 +46,12 @@ class PermissionUtil /** * Check if the user has the given permission (for the given location). * - * @param string $userid userid to check + * @param int $userid userid to check * @param string $permissionid permissionid to check * @param int|null $locationid locationid to check or null if the location should be disregarded * @return bool true if user has permission, false if not */ - public static function userHasPermission($userid, $permissionid, $locationid) + public static function userHasPermission(int $userid, string $permissionid, ?int $locationid): bool { $permissionid = strtolower($permissionid); self::validatePermission($permissionid); @@ -121,6 +121,8 @@ class PermissionUtil // Compare to database result if ($cacheAll) { $allLocs = Location::getLocationsAssoc(); + } else { + $allLocs = []; } self::makeComparisonVariants($parts, $compare, $wildcard, $wclen); $retval = false; @@ -152,11 +154,11 @@ class PermissionUtil /** * Get all locations where the user has the given permission. * - * @param string $userid userid to check + * @param int $userid userid to check * @param string $permissionid permissionid to check * @return array array of locationids where the user has the given permission */ - public static function getAllowedLocations($userid, $permissionid) + public static function getAllowedLocations(int $userid, string $permissionid): array { $permissionid = strtolower($permissionid); self::validatePermission($permissionid); @@ -199,10 +201,10 @@ class PermissionUtil * Extend an array of locations by adding all sublocations. * * @param array $tree tree of all locations (structured like Location::getTree()) - * @param array $allowedLocations the array of locationids to extend + * @param int[] $allowedLocations the array of locationids to extend * @return array extended array of locationids */ - public static function getSublocations($tree, $allowedLocations) + public static function getSublocations(array $tree, array $allowedLocations): array { $result = $allowedLocations; foreach ($tree as $location) { @@ -224,7 +226,7 @@ class PermissionUtil * * @param string $permissionId permission to check */ - private static function validatePermission($permissionId) + private static function validatePermission(string $permissionId): void { if (!CONFIG_DEBUG || $permissionId === '*') return; @@ -253,7 +255,7 @@ class PermissionUtil * * @return array permission tree as a multidimensional array */ - public static function getPermissions() + public static function getPermissions(): array { $permissions = array(); foreach (glob("modules/*/permissions/permissions.json", GLOB_NOSORT) as $file) { @@ -291,18 +293,17 @@ class PermissionUtil /** * Get all existing roles. * - * @param int|false $userid Which user to consider, false = none - * @param bool $onlyMatching true = filter roles the user doesn't have + * @param ?int $userid Which user to consider, false = none (list all) * @return array list of roles */ - public static function getRoles($userid = false, $onlyMatching = true) + public static function getRoles(?int $userid = null): array { if ($userid === false) { return Database::queryAll('SELECT roleid, rolename FROM role ORDER BY rolename ASC'); } $ret = Database::queryAll('SELECT r.roleid, r.rolename, u.userid AS hasRole FROM role r LEFT JOIN role_x_user u ON (r.roleid = u.roleid AND u.userid = :userid) - GROUP BY r.roleid + GROUP BY r.roleid, r.rolename ORDER BY rolename ASC', ['userid' => $userid]); foreach ($ret as &$role) { settype($role['hasRole'], 'bool'); @@ -318,7 +319,7 @@ class PermissionUtil * @param string $description the description of the permission * @param array $tree the permission tree to modify */ - private static function putInPermissionTree($permission, $locationAware, $description, &$tree) + private static function putInPermissionTree(string $permission, bool $locationAware, string $description, array &$tree): void { $subPermissions = explode('.', $permission); foreach ($subPermissions as $subPermission) { diff --git a/modules-available/permissionmanager/page.inc.php b/modules-available/permissionmanager/page.inc.php index b431d9c9..7e9f17e4 100644 --- a/modules-available/permissionmanager/page.inc.php +++ b/modules-available/permissionmanager/page.inc.php @@ -18,13 +18,13 @@ class Page_PermissionManager extends Page $action = Request::any('action', 'show', 'string'); if ($action === 'addRoleToUser') { User::assertPermission('users.edit-roles'); - $users = Request::post('users', ''); - $roles = Request::post('roles', ''); + $users = Request::post('users', [], 'array'); + $roles = Request::post('roles', [], 'array'); PermissionDbUpdate::addRoleToUser($users, $roles); } elseif ($action === 'removeRoleFromUser') { User::assertPermission('users.edit-roles'); - $users = Request::post('users', ''); - $roles = Request::post('roles', ''); + $users = Request::post('users', [], 'array'); + $roles = Request::post('roles', [], 'array'); PermissionDbUpdate::removeRoleFromUser($users, $roles); } elseif ($action === 'deleteRole') { User::assertPermission('roles.edit'); @@ -115,7 +115,7 @@ class Page_PermissionManager extends Page $roleid = Request::get("roleid", false, 'int'); if ($roleid !== false) { $role = GetPermissionData::getRoleData($roleid); - if ($role === false) { + if ($role === null) { Message::addError('invalid-role-id', $roleid); Util::redirect('?do=permissionmanager'); } @@ -147,7 +147,8 @@ class Page_PermissionManager extends Page * @param string $permString the prefix permission string with which all permissions in the permission tree should start * @return string generated html code */ - private static function generatePermissionHTML($permissions, $selectedPermissions = array(), $selectAll = false, $permString = "", $tags = []) + private static function generatePermissionHTML(array $permissions, array $selectedPermissions = [], + bool $selectAll = false, string $permString = "", array $tags = []): string { $res = ""; $toplevel = $permString == ""; @@ -203,11 +204,12 @@ class Page_PermissionManager extends Page * * @param array $locations the location tree * @param array $selectedLocations locations that should be preselected - * @param array $selectAll true if all locations should be preselected, false if only those in $selectedLocations - * @param array $toplevel true if the location tree are the children of the root location, false if not + * @param bool $selectAll true if all locations should be preselected, false if only those in $selectedLocations + * @param bool $toplevel true if the location tree are the children of the root location, false if not * @return string generated html code */ - private static function generateLocationHTML($locations, $selectedLocations = array(), $selectAll = false, $toplevel = true, $tags = []) + private static function generateLocationHTML(array $locations, array $selectedLocations = [], + bool $selectAll = false, bool $toplevel = true, array $tags = []): string { $res = ""; if ($toplevel && in_array(0, $selectedLocations)) { @@ -242,7 +244,7 @@ class Page_PermissionManager extends Page * @param array $locations the locationid array * @return array the locationid array without redundant locationids */ - private static function processLocations($locations) + private static function processLocations(array $locations): array { if (in_array(0, $locations)) return array(null); @@ -267,7 +269,7 @@ class Page_PermissionManager extends Page * @param array $permissions the permissionid array * @return array the permissionid array without redundant permissionids */ - private static function processPermissions($permissions) + private static function processPermissions(array $permissions): array { if (in_array("*", $permissions)) return array("*"); @@ -287,7 +289,7 @@ class Page_PermissionManager extends Page * @param array $permissions multidimensional array of permissionids * @return array flat array of permissionids */ - private static function extractPermissions($permissions) + private static function extractPermissions(array $permissions): array { $result = array(); foreach ($permissions as $permission => $a) { @@ -306,7 +308,7 @@ class Page_PermissionManager extends Page return $result; } - private function denyActionIfBuiltin($roleID) + private function denyActionIfBuiltin(string $roleID): void { if ($roleID) { $existing = GetPermissionData::getRole($roleID); diff --git a/modules-available/rebootcontrol/hooks/client-update.inc.php b/modules-available/rebootcontrol/hooks/client-update.inc.php index 006a5e11..e934988d 100644 --- a/modules-available/rebootcontrol/hooks/client-update.inc.php +++ b/modules-available/rebootcontrol/hooks/client-update.inc.php @@ -7,7 +7,7 @@ if ($type === '~poweron') { && $subnet[0] === $ip && $subnet[1] >= 8 && $subnet[1] < 32) { $start = ip2long($ip); if ($start !== false) { - $maskHost = (int)(pow(2, 32 - $subnet[1]) - 1); + $maskHost = (int)(2 ** (32 - $subnet[1]) - 1); $maskNet = ~$maskHost & 0xffffffff; $end = $start | $maskHost; $start &= $maskNet; diff --git a/modules-available/rebootcontrol/hooks/config-tgz.inc.php b/modules-available/rebootcontrol/hooks/config-tgz.inc.php index 90e32e8a..c9ce1255 100644 --- a/modules-available/rebootcontrol/hooks/config-tgz.inc.php +++ b/modules-available/rebootcontrol/hooks/config-tgz.inc.php @@ -8,8 +8,10 @@ if (!is_file($tmpfile) || !is_readable($tmpfile) || filemtime($tmpfile) + 86400 } try { $a = new PharData($tmpfile); - $a["/etc/ssh/mgmt/authorized_keys"] = $pubkey; - $a["/etc/ssh/mgmt/authorized_keys"]->chmod(0600); + $a->addFromString("/etc/ssh/mgmt/authorized_keys", $pubkey); + $fi = $a->offsetGet("/etc/ssh/mgmt/authorized_keys"); + /** @var PharFileInfo $fi */ + $fi->chmod(0600); $file = $tmpfile; } catch (Exception $e) { EventLog::failure('Could not include ssh key for reboot-control in config.tgz', (string)$e); diff --git a/modules-available/rebootcontrol/hooks/cron.inc.php b/modules-available/rebootcontrol/hooks/cron.inc.php index cdecc31b..289426c7 100644 --- a/modules-available/rebootcontrol/hooks/cron.inc.php +++ b/modules-available/rebootcontrol/hooks/cron.inc.php @@ -24,7 +24,7 @@ class Stuff public static $subnets; } -function destSawPw($destTask, $destMachine, $passwd) +function destSawPw(array $destTask, array $destMachine, string $passwd): bool { return strpos($destTask['data']['result'][$destMachine['machineuuid']]['stdout'], "passwd=$passwd") !== false; } diff --git a/modules-available/rebootcontrol/inc/rebootcontrol.inc.php b/modules-available/rebootcontrol/inc/rebootcontrol.inc.php index a37b070c..ab308084 100644 --- a/modules-available/rebootcontrol/inc/rebootcontrol.inc.php +++ b/modules-available/rebootcontrol/inc/rebootcontrol.inc.php @@ -61,13 +61,8 @@ class RebootControl /** * Add wake task metadata to database, so we can display job details on the summary page. - * @param string $taskId - * @param string $type - * @param array $clients - * @param ?array $other - * @return void */ - private static function addTask(string $taskId, string $type, array $clients, array $other = null) + private static function addTask(string $taskId, string $type, array $clients, array $other = null): void { $lids = ArrayUtil::flattenByKey($clients, 'locationid'); $lids = array_unique($lids); @@ -220,12 +215,10 @@ class RebootControl } /** - * @param string|string[] $macs - * @param ?string $bcast - * @param ?string $passwd - * @return string + * Wake clients given by MAC address(es) via jawol util. + * Multiple MAC addresses can be passed as a space separated list. */ - private static function buildClientWakeCommand($macs, string $bcast = null, string $passwd = null): string + private static function buildClientWakeCommand(string $macs, string $bcast = null, string $passwd = null): string { $command = 'jawol'; if (!empty($bcast)) { @@ -236,21 +229,18 @@ class RebootControl if (!empty($passwd)) { $command .= " -p '$passwd'"; } - if (is_array($macs)) { - $macs = implode(" ", $macs); - } $command .= " $macs"; return $command; } /** * @param array $sourceMachines list of source machines. array of [clientip, machineuuid] entries - * @param string|string[] $macaddr destination mac address(es) - * @param ?string $bcast directed broadcast address to send to - * @param ?string $passwd optional WOL password, mac address or ipv4 notation + * @param string $macaddr destination mac address(es) + * @param string $bcast directed broadcast address to send to + * @param string $passwd optional WOL password, mac address or ipv4 notation * @return array|false task struct, false on error */ - public static function wakeViaClient($sourceMachines, $macaddr, string $bcast = null, string $passwd = null) + public static function wakeViaClient(array $sourceMachines, string $macaddr, string $bcast = null, string $passwd = null) { $command = self::buildClientWakeCommand($macaddr, $bcast, $passwd); // Yes there is one zero "missing" from the usleep -- that's the whole point: we prefer 100ms sleeps @@ -320,7 +310,7 @@ class RebootControl * @param ?array $failed list of failed clients from $clientList * @return ?string taskid of this job */ - public static function wakeMachines(array $clientList, array &$failed = null) + public static function wakeMachines(array $clientList, array &$failed = null): ?string { $errors = ''; $sent = $unknown = $unreachable = $failed = []; diff --git a/modules-available/rebootcontrol/inc/rebootutils.inc.php b/modules-available/rebootcontrol/inc/rebootutils.inc.php index f6843150..e05d90dc 100644 --- a/modules-available/rebootcontrol/inc/rebootutils.inc.php +++ b/modules-available/rebootcontrol/inc/rebootutils.inc.php @@ -8,13 +8,12 @@ class RebootUtils * @param string[] $list list of system UUIDs * @return array list of machines with machineuuid, hostname, clientip, state and locationid */ - public static function getMachinesByUuid($list, $assoc = false, $columns = ['machineuuid', 'hostname', 'clientip', 'state', 'locationid']) + public static function getMachinesByUuid(array $list, bool $assoc = false, + array $columns = ['machineuuid', 'hostname', 'clientip', 'state', 'locationid']): array { if (empty($list)) return array(); - if (is_array($columns)) { - $columns = implode(',', $columns); - } + $columns = implode(',', $columns); $res = Database::simpleQuery("SELECT $columns FROM machine WHERE machineuuid IN (:list)", compact('list')); if (!$assoc) @@ -31,7 +30,7 @@ class RebootUtils * Requires the array elements to have key "state" from machine table. * @param array $clients list of clients */ - public static function sortRunningFirst(&$clients) + public static function sortRunningFirst(array &$clients): void { usort($clients, function($a, $b) { $a = ($a['state'] === 'IDLE' || $a['state'] === 'OCCUPIED'); @@ -49,7 +48,7 @@ class RebootUtils * @param string $permission name of location-aware permission to check * @return array|false List of clients the user has access to. */ - public static function getFilteredMachineList($requestedClients, $permission) + public static function getFilteredMachineList(array $requestedClients, string $permission) { $actualClients = RebootUtils::getMachinesByUuid($requestedClients); if (count($actualClients) !== count($requestedClients)) { diff --git a/modules-available/rebootcontrol/inc/scheduler.inc.php b/modules-available/rebootcontrol/inc/scheduler.inc.php index 937cc000..19a01beb 100644 --- a/modules-available/rebootcontrol/inc/scheduler.inc.php +++ b/modules-available/rebootcontrol/inc/scheduler.inc.php @@ -199,8 +199,7 @@ class Scheduler } /** - * Get current settings for given location, or false if none. - * @param int $id + * Get current settings for given location. */ public static function getLocationOptions(int $id): array { @@ -216,7 +215,6 @@ class Scheduler /** * Write new WOL/Shutdown options for given location. - * @param int $locationId * @param array $options 'wol' 'sd' 'wol-offset' 'sd-offset' 'ra-mode' */ public static function setLocationOptions(int $locationId, array $options) diff --git a/modules-available/rebootcontrol/inc/sshkey.inc.php b/modules-available/rebootcontrol/inc/sshkey.inc.php index cce9b3dc..e0954415 100644 --- a/modules-available/rebootcontrol/inc/sshkey.inc.php +++ b/modules-available/rebootcontrol/inc/sshkey.inc.php @@ -3,13 +3,17 @@ class SSHKey { - public static function getPrivateKey(&$regen = false) { + public static function getPrivateKey(?bool &$regen = false): ?string + { $privKey = Property::get("rebootcontrol-private-key"); if (!$privKey) { - $rsaKey = openssl_pkey_new(array( + $rsaKey = openssl_pkey_new([ 'private_key_bits' => 2048, - 'private_key_type' => OPENSSL_KEYTYPE_RSA)); - openssl_pkey_export( openssl_pkey_get_private($rsaKey), $privKey); + 'private_key_type' => OPENSSL_KEYTYPE_RSA]); + if (!openssl_pkey_export( openssl_pkey_get_private($rsaKey), $privKey)) { + $regen = false; + return null; + } Property::set("rebootcontrol-private-key", $privKey); if (Module::isAvailable('sysconfig')) { ConfigTgz::rebuildAllConfigs(); @@ -19,21 +23,30 @@ class SSHKey return $privKey; } - public static function getPublicKey() { + public static function getPublicKey(): ?string + { $pkImport = openssl_pkey_get_private(self::getPrivateKey()); + if ($pkImport === false) + return null; return self::sshEncodePublicKey($pkImport); } - private static function sshEncodePublicKey($privKey) { + private static function sshEncodePublicKey($privKey): ?string + { $keyInfo = openssl_pkey_get_details($privKey); + if ($keyInfo === false) + return null; $buffer = pack("N", 7) . "ssh-rsa" . self::sshEncodeBuffer($keyInfo['rsa']['e']) . self::sshEncodeBuffer($keyInfo['rsa']['n']); return "ssh-rsa " . base64_encode($buffer); } - private static function sshEncodeBuffer($buffer) { + private static function sshEncodeBuffer(string $buffer): string + { $len = strlen($buffer); + // Prefix with extra null byte if the MSB is set, to ensure + // nobody will ever interpret this as a negative number if (ord($buffer[0]) & 0x80) { $len++; $buffer = "\x00" . $buffer; diff --git a/modules-available/rebootcontrol/page.inc.php b/modules-available/rebootcontrol/page.inc.php index c189e1fc..80eff842 100644 --- a/modules-available/rebootcontrol/page.inc.php +++ b/modules-available/rebootcontrol/page.inc.php @@ -21,10 +21,10 @@ class Page_RebootControl extends Page } if (User::hasPermission('jumphost.*')) { - Dashboard::addSubmenu('?do=rebootcontrol&show=jumphost', Dictionary::translate('jumphosts', true)); + Dashboard::addSubmenu('?do=rebootcontrol&show=jumphost', Dictionary::translate('jumphosts')); } if (User::hasPermission('subnet.*')) { - Dashboard::addSubmenu('?do=rebootcontrol&show=subnet', Dictionary::translate('subnets', true)); + Dashboard::addSubmenu('?do=rebootcontrol&show=subnet', Dictionary::translate('subnets')); } $section = Request::any('show', false, 'string'); diff --git a/modules-available/rebootcontrol/pages/subnet.inc.php b/modules-available/rebootcontrol/pages/subnet.inc.php index c1631cbd..3e593505 100644 --- a/modules-available/rebootcontrol/pages/subnet.inc.php +++ b/modules-available/rebootcontrol/pages/subnet.inc.php @@ -24,7 +24,7 @@ class SubPage User::assertPermission('subnet.edit'); $cidr = Request::post('cidr', Request::REQUIRED, 'string'); $range = IpUtil::parseCidr($cidr); - if ($range === false) { + if ($range === null) { Message::addError('invalid-cidr', $cidr); return; } diff --git a/modules-available/rebootcontrol/pages/task.inc.php b/modules-available/rebootcontrol/pages/task.inc.php index dc50bfff..7e1f6fbf 100644 --- a/modules-available/rebootcontrol/pages/task.inc.php +++ b/modules-available/rebootcontrol/pages/task.inc.php @@ -145,14 +145,3 @@ class SubPage } } - - -// Remove when we require >= 7.3.0 -if (!function_exists('array_key_first')) { - function array_key_first(array $arr) { - foreach($arr as $key => $unused) { - return $key; - } - return NULL; - } -} diff --git a/modules-available/remoteaccess/api.inc.php b/modules-available/remoteaccess/api.inc.php index ec5fe7ad..ca04eec4 100644 --- a/modules-available/remoteaccess/api.inc.php +++ b/modules-available/remoteaccess/api.inc.php @@ -21,7 +21,7 @@ if ($password !== false) { } $range = IpUtil::parseCidr(Property::get(RemoteAccess::PROP_ALLOWED_VNC_NET)); -if ($range === false) { +if ($range === null) { die('No allowed IP defined'); } $iplong = ip2long($ip); diff --git a/modules-available/remoteaccess/baseconfig/getconfig.inc.php b/modules-available/remoteaccess/baseconfig/getconfig.inc.php index 6403538d..182daef1 100644 --- a/modules-available/remoteaccess/baseconfig/getconfig.inc.php +++ b/modules-available/remoteaccess/baseconfig/getconfig.inc.php @@ -1,15 +1,18 @@ $machineUuid], true); + ['uuid' => $uuid], true); if (is_array($res)) return; // Locations from closest to furthest (order) $locationId = ConfigHolder::get('SLX_LOCATIONS'); - if ($locationId === false) + if ($locationId === null) return; $locationId = (int)$locationId; $ret = Database::queryFirst("SELECT l.locationid FROM remoteaccess_x_location l @@ -44,4 +47,4 @@ ConfigHolder::add('SLX_SCREEN_SAVER_GRACE_TIME', '86400', 1000); // Autologin will never work as the machine is immediately in use and will never get assigned ConfigHolder::add('SLX_AUTOLOGIN', 'OFF', 10000); -})($uuid); +} diff --git a/modules-available/remoteaccess/inc/remoteaccess.inc.php b/modules-available/remoteaccess/inc/remoteaccess.inc.php index 7bd0e966..95ca3821 100644 --- a/modules-available/remoteaccess/inc/remoteaccess.inc.php +++ b/modules-available/remoteaccess/inc/remoteaccess.inc.php @@ -93,7 +93,7 @@ class RemoteAccess $NOW = time(); while ($num > 0) { $list = []; - for ($i = 0; $i < $num && $row = $res->fetch(); ++$i) { + for ($i = 0; $i < $num && ($row = $res->fetch()); ++$i) { $list[] = $row; Database::exec("INSERT INTO remoteaccess_machine (machineuuid, password, woltime) VALUES (:uuid, NULL, :now) diff --git a/modules-available/remoteaccess/page.inc.php b/modules-available/remoteaccess/page.inc.php index ee9305dc..ba248b4d 100644 --- a/modules-available/remoteaccess/page.inc.php +++ b/modules-available/remoteaccess/page.inc.php @@ -127,7 +127,7 @@ class Page_RemoteAccess extends Page $last['groups'][] = [ 'groupid' => $row['groupid'], 'groupname' => $row['groupname'], - 'gclass' => $row['active'] ?: 'slx-strike', + 'gclass' => $row['active'] ? '' : 'slx-strike', ]; if ($row['active']) { $last['lclass'] = ''; diff --git a/modules-available/roomplanner/inc/composedroom.inc.php b/modules-available/roomplanner/inc/composedroom.inc.php index cdd50984..3ee892db 100644 --- a/modules-available/roomplanner/inc/composedroom.inc.php +++ b/modules-available/roomplanner/inc/composedroom.inc.php @@ -98,7 +98,7 @@ class ComposedRoom extends Room return $this->orientation; } - public function subLocationIds() + public function subLocationIds(): array { return $this->list; } @@ -108,7 +108,7 @@ class ComposedRoom extends Room return $this->controlRoom; } - public function machineCount() + public function machineCount(): int { $sum = 0; foreach ($this->list as $lid) { @@ -117,10 +117,9 @@ class ComposedRoom extends Room return $sum; } - public function getSize(&$width, &$height) + public function getSize(?int &$width, ?int &$height) { $horz = ($this->orientation == 'horizontal'); - $width = $height = 0; foreach ($this->list as $locId) { self::$rooms[$locId]->getSize($w, $h); $width = $horz ? $width + $w : max($width, $w); @@ -128,7 +127,7 @@ class ComposedRoom extends Room } } - public function getIniClientSection(&$i, $offX = 0, $offY = 0) + public function getIniClientSection(int &$i, int $offX = 0, int $offY = 0) { if (!$this->enabled) return false; @@ -154,10 +153,10 @@ class ComposedRoom extends Room return $out; } - public function getShiftedArray($offX = 0, $offY = 0) + public function getShiftedArray(int $offX = 0, int $offY = 0): ?array { if (!$this->enabled) - return false; + return null; if ($this->orientation == 'horizontal') { $x = 1; $y = 0; @@ -168,7 +167,7 @@ class ComposedRoom extends Room $ret = []; foreach ($this->list as $locId) { $new = self::$rooms[$locId]->getShiftedArray($offX, $offY); - if ($new !== false) { + if ($new !== null) { $ret = array_merge($ret, $new); self::$rooms[$locId]->getSize($w, $h); $offX += $w * $x; @@ -176,7 +175,7 @@ class ComposedRoom extends Room } } if (empty($ret)) - return false; + return null; return $ret; } @@ -194,12 +193,12 @@ class ComposedRoom extends Room return false; } - public function isLeaf() + public function isLeaf(): bool { return false; } - public function shouldSkip() + public function shouldSkip(): bool { return !$this->enabled; } diff --git a/modules-available/roomplanner/inc/pvsgenerator.inc.php b/modules-available/roomplanner/inc/pvsgenerator.inc.php index f23dcb20..f3c5c838 100644 --- a/modules-available/roomplanner/inc/pvsgenerator.inc.php +++ b/modules-available/roomplanner/inc/pvsgenerator.inc.php @@ -3,7 +3,7 @@ class PvsGenerator { - public static function generate() + public static function generate(): string { /* collect names and build room blocks - filter empty rooms while at it */ $roomNames = array(); @@ -36,7 +36,7 @@ class PvsGenerator * @param Room $room room/location data as fetched from db * @return string|false .ini section for room, or false if room is empty */ - private static function generateRoomBlock($room) + private static function generateRoomBlock(Room $room) { $room->getSize($sizeX, $sizeY); if ($sizeX === 0 || $sizeY === 0) @@ -91,13 +91,13 @@ class PvsGenerator } // Load room $room = Room::get($locationId); - if ($room === false) + if ($room === null) return false; $room->getSize($sizeX, $sizeY); if ($sizeX === 0 || $sizeY === 0) return false; // Empty - $machines = $room->getShiftedArray(); + $machines = $room->getShiftedArray() ?? []; $ORIENTATION = ['north' => 2, 'east' => 3, 'south' => 0, 'west' => 1]; if (is_string($highlightUuid)) { $highlightUuid = strtoupper($highlightUuid); @@ -176,14 +176,12 @@ class PvsGenerator /** * Get display name for manager of given locationId. * Hook for "runmode" module to resolve mode name. - * @param $locationId - * @return bool|string */ - public static function getManagerName($locationId) + public static function getManagerName(int $locationId): ?string { $names = Location::getNameChain($locationId); if ($names === false) - return false; + return null; return implode(' / ', $names); } diff --git a/modules-available/roomplanner/inc/room.inc.php b/modules-available/roomplanner/inc/room.inc.php index 1a7a80ae..880cb6d0 100644 --- a/modules-available/roomplanner/inc/room.inc.php +++ b/modules-available/roomplanner/inc/room.inc.php @@ -29,10 +29,10 @@ abstract class Room FROM location_roomplan lr LEFT JOIN machine m ON (lr.tutoruuid = m.machineuuid)'); foreach ($ret as $row) { - $row = self::loadSingleRoom($row); - if ($row === false) + $room = self::loadSingleRoom($row); + if ($room === null) continue; - self::$rooms[$row->locationId] = $row; + self::$rooms[$room->locationId] = $room; } foreach (self::$rooms as $room) { $room->sanitize(); @@ -42,14 +42,14 @@ abstract class Room /** * Instantiate ComposedRoom or MachineGroup depending on contents of $row * @param array $row DB row from location_roomplan. - * @return Room|false Room instance, false on error + * @return ?Room Room instance, null on error */ - private static function loadSingleRoom($row) + private static function loadSingleRoom(array $row): ?Room { $locations = Location::getLocationsAssoc(); settype($row['locationid'], 'int'); if (!isset($locations[$row['locationid']])) - return false; + return null; if ($locations[$row['locationid']]['isleaf']) return new SimpleRoom($row); return new ComposedRoom($row, false); @@ -59,7 +59,7 @@ abstract class Room * Get array of all rooms with room plan * @return Room[] */ - public static function getAll() + public static function getAll(): array { self::init(); return self::$rooms; @@ -68,9 +68,9 @@ abstract class Room /** * Get room instance for given location * @param int $locationId room to get - * @return Room|false requested room, false if not configured or not found + * @return ?Room requested room, false if not configured or not found */ - public static function get($locationId) + public static function get(int $locationId): ?Room { if (self::$rooms === null) { $room = Database::queryFirst( @@ -79,8 +79,10 @@ abstract class Room LEFT JOIN machine m ON (lr.tutoruuid = m.machineuuid) WHERE lr.locationid = :lid', ['lid' => $locationId]); if ($room === false) - return false; + return null; $room = self::loadSingleRoom($room); + if ($room === null) + return null; // If it's a leaf room we probably don't need any other rooms, return it if ($room->isLeaf()) return $room; @@ -89,7 +91,7 @@ abstract class Room } if (isset(self::$rooms[$locationId])) return self::$rooms[$locationId]; - return false; + return null; } public function __construct($row) @@ -102,35 +104,34 @@ abstract class Room /** * @return int number of machines in this room */ - abstract public function machineCount(); + abstract public function machineCount(): int; /** * Size of this room, returned by reference. - * @param int $width OUT width of room - * @param int $height OUT height of room + * + * @param int|null $width OUT width of room + * @param int|null $height OUT height of room */ - abstract public function getSize(&$width, &$height); + abstract public function getSize(?int &$width, ?int &$height); /** * Get clients in this room in .ini format for PVS. * Adjusted so the top/left client is at (0|0), which * is further adjustable with $offX and $offY. + * * @param int $i offset for indexing clients * @param int $offX positional X offset for clients * @param int $offY positional Y offset for clients * @return string|false */ - abstract public function getIniClientSection(&$i, $offX = 0, $offY = 0); + abstract public function getIniClientSection(int &$i, int $offX = 0, int $offY = 0); /** * Get clients in this room as array. * Adjusted so the top/left client is at (0|0), which *is further adjustable with $offX and $offY. - * @param int $offX - * @param int $offY - * @return array */ - abstract public function getShiftedArray($offX = 0, $offY = 0); + abstract public function getShiftedArray(int $offX = 0, int $offY = 0): ?array; /** * @return string|false IP address of manager. @@ -145,12 +146,12 @@ abstract class Room /** * @return bool true if this is a simple/leaf room, false for composed rooms. */ - abstract public function isLeaf(); + abstract public function isLeaf(): bool; /** * @return bool should this room be skipped from output? true for empty SimpleRoom or disabled ComposedRoom. */ - abstract public function shouldSkip(); + abstract public function shouldSkip(): bool; /** * Sanitize this room's data. @@ -160,7 +161,7 @@ abstract class Room /** * @return string get room's name. */ - public function locationName() + public function locationName(): string { return $this->locationName; } @@ -168,7 +169,7 @@ abstract class Room /** * @return int get room's id. */ - public function locationId() + public function locationId(): int { return $this->locationId; } diff --git a/modules-available/roomplanner/inc/simpleroom.inc.php b/modules-available/roomplanner/inc/simpleroom.inc.php index 43ae43ca..b4d3e744 100644 --- a/modules-available/roomplanner/inc/simpleroom.inc.php +++ b/modules-available/roomplanner/inc/simpleroom.inc.php @@ -11,6 +11,7 @@ class SimpleRoom extends Room private $tutorIp = false; + /** @var ?string */ private $managerIp = false; public function __construct($row) @@ -55,27 +56,29 @@ class SimpleRoom extends Room } } - public function machineCount() + public function machineCount(): int { return count($this->machines); } - public function getSize(&$width, &$height) + public function getSize(?int &$width, ?int &$height) { if (empty($this->machines)) { $width = $height = 0; return; } + $minX = $minY = $maxX = $maxY = 0; $this->boundingBox($minX, $minY, $maxX, $maxY); // client's size that cannot be configured as of today $width = max($maxX - $minX + self::CLIENT_SIZE, 1); $height = max($maxY - $minY + self::CLIENT_SIZE, 1); } - public function getIniClientSection(&$i, $offX = 0, $offY = 0) + public function getIniClientSection(int &$i, int $offX = 0, int $offY = 0): string { /* output individual client positions, shift coordinates to requested position */ $out = ''; + $minX = $minY = $maxX = $maxY = 0; $this->boundingBox($minX, $minY, $maxX, $maxY); foreach ($this->machines as $pos) { $i++; @@ -86,10 +89,11 @@ class SimpleRoom extends Room return $out; } - public function getShiftedArray($offX = 0, $offY = 0) + public function getShiftedArray(int $offX = 0, int $offY = 0): ?array { /* output individual client positions, shift coordinates to requested position */ $ret = []; + $minX = $minY = $maxX = $maxY = 0; $this->boundingBox($minX, $minY, $maxX, $maxY); foreach ($this->machines as $pos) { $pos['gridCol'] += $offX - $minX; @@ -100,7 +104,7 @@ class SimpleRoom extends Room return $ret; } - private function boundingBox(&$minX, &$minY, &$maxX, &$maxY) + private function boundingBox(int &$minX, int &$minY, int &$maxX, int &$maxY): void { if ($this->bb !== false) { $minX = $this->bb[0]; @@ -130,12 +134,12 @@ class SimpleRoom extends Room return $this->tutorIp; } - public function isLeaf() + public function isLeaf(): bool { return true; } - public function shouldSkip() + public function shouldSkip(): bool { return empty($this->machines); } diff --git a/modules-available/roomplanner/page.inc.php b/modules-available/roomplanner/page.inc.php index 7ac6890d..53e8bf0b 100644 --- a/modules-available/roomplanner/page.inc.php +++ b/modules-available/roomplanner/page.inc.php @@ -82,22 +82,17 @@ class Page_Roomplanner extends Page $config = Database::queryFirst('SELECT roomplan, managerip, tutoruuid FROM location_roomplan WHERE locationid = :locationid', ['locationid' => $this->locationid]); + if ($config === false) { + $config = ['dedicatedmgr' => false, 'managerip' => '']; + } $runmode = RunMode::getForMode(Page::getModule(), $this->locationid, true); - if (empty($runmode)) { - $config['dedicatedmgr'] = false; - } else { + if (!empty($runmode)) { $runmode = array_pop($runmode); $config['managerip'] = $runmode['clientip']; $config['manageruuid'] = $runmode['machineuuid']; $data = json_decode($runmode['modedata'], true); $config['dedicatedmgr'] = (isset($data['dedicatedmgr']) && $data['dedicatedmgr']); } - if ($config !== false) { - $managerIp = $config['managerip'] ?? ''; - $dediMgr = $config['dedicatedmgr'] ? 'checked' : ''; - } else { - $dediMgr = $managerIp = ''; - } $furniture = $this->getFurniture($config); $subnetMachines = $this->getPotentialMachines(); $machinesOnPlan = $this->getMachinesOnPlan($config['tutoruuid'] ?? ''); @@ -105,8 +100,8 @@ class Page_Roomplanner extends Page $canEdit = User::hasPermission('edit', $this->locationid); $params = [ 'location' => $this->location, - 'managerip' => $managerIp, - 'dediMgrChecked' => $dediMgr, + 'managerip' => $config['managerip'], + 'dediMgrChecked' => $config['dedicatedmgr'] ? 'checked' : '', 'subnetMachines' => json_encode($subnetMachines), 'locationid' => $this->locationid, 'roomConfiguration' => json_encode($roomConfig), @@ -229,11 +224,9 @@ class Page_Roomplanner extends Page if ($leaf !== $this->isLeaf) { if ($isAjax) { die('Leaf mode mismatch. Did you restructure locations while editing this room?'); - } else { - Message::addError('leaf-mode-mismatch'); - Util::redirect("?do=roomplanner&locationid={$this->locationid}&action=show"); } - return; + Message::addError('leaf-mode-mismatch'); + Util::redirect("?do=roomplanner&locationid={$this->locationid}&action=show"); } if ($this->isLeaf) { $this->saveLeafRoom($isAjax); @@ -250,10 +243,9 @@ class Page_Roomplanner extends Page if (!is_array($config) || !isset($config['furniture']) || !isset($config['computers'])) { if ($isAjax) { die('JSON data incomplete'); - } else { - Message::addError('json-data-invalid'); - Util::redirect("?do=roomplanner&locationid={$this->locationid}&action=show"); } + Message::addError('json-data-invalid'); + Util::redirect("?do=roomplanner&locationid={$this->locationid}&action=show"); } $tutorUuid = Request::post('tutoruuid', '', 'string'); if (empty($tutorUuid)) { @@ -263,10 +255,9 @@ class Page_Roomplanner extends Page if ($ret === false) { if ($isAjax) { die('Invalid tutor UUID'); - } else { - Message::addError('invalid-tutor-uuid'); - Util::redirect("?do=roomplanner&locationid={$this->locationid}&action=show"); } + Message::addError('invalid-tutor-uuid'); + Util::redirect("?do=roomplanner&locationid={$this->locationid}&action=show"); } } $this->saveRoomConfig($config['furniture'], $tutorUuid); @@ -282,10 +273,9 @@ class Page_Roomplanner extends Page if ($res === false) { if ($isAjax) { die('Error writing config to DB'); - } else { - Message::addError('db-error'); - Util::redirect("?do=roomplanner&locationid={$this->locationid}&action=show"); } + Message::addError('db-error'); + Util::redirect("?do=roomplanner&locationid={$this->locationid}&action=show"); } } @@ -302,7 +292,7 @@ class Page_Roomplanner extends Page * @param array $computers Deserialized json from browser with all the computers * @param array $oldComputers Deserialized old roomplan from database, used to find removed computers */ - protected function saveComputerConfig($computers, $oldComputers) + protected function saveComputerConfig(array $computers, array $oldComputers) { $oldUuids = []; @@ -323,12 +313,12 @@ class Page_Roomplanner extends Page if (!isset($computer['gridRow'])) { $computer['gridRow'] = 0; } else { - $this->sanitizeNumber($computer['gridRow'], 0, 32 * 4); + Util::clamp($computer['gridRow'], 0, 32 * 4); } if (!isset($computer['gridCol'])) { $computer['gridCol'] = 0; } else { - $this->sanitizeNumber($computer['gridCol'], 0, 32 * 4); + Util::clamp($computer['gridCol'], 0, 32 * 4); } $position = json_encode(['gridRow' => $computer['gridRow'], @@ -374,17 +364,20 @@ class Page_Roomplanner extends Page } } - protected function getFurniture($config) + protected function getFurniture(array $config): array { - if ($config === false) - return array(); - $config = json_decode($config['roomplan'] ?? '', true); + if (empty($config['roomplan'])) + return []; + $config = json_decode($config['roomplan'], true); if (!is_array($config)) - return array(); + return []; return $config; } - protected function getMachinesOnPlan($tutorUuid) + /** + * @return array{computers: array} + */ + protected function getMachinesOnPlan(string $tutorUuid): array { $result = Database::simpleQuery('SELECT machineuuid, macaddr, clientip, hostname, position FROM machine @@ -418,7 +411,7 @@ class Page_Roomplanner extends Page return ['computers' => $machines]; } - protected function getPotentialMachines() + protected function getPotentialMachines(): array { $result = Database::simpleQuery('SELECT m.machineuuid, m.macaddr, m.clientip, m.hostname, l.locationname AS otherroom, m.fixedlocationid FROM machine m diff --git a/modules-available/runmode/baseconfig/getconfig.inc.php b/modules-available/runmode/baseconfig/getconfig.inc.php index 9c36cc75..a5de1053 100644 --- a/modules-available/runmode/baseconfig/getconfig.inc.php +++ b/modules-available/runmode/baseconfig/getconfig.inc.php @@ -1,20 +1,23 @@ $machineUuid)); + array('uuid' => $uuid)); if ($res === false) return; $config = RunMode::getModuleConfig($res['module']); - if ($config === false) + if ($config === null) return; if (!Module::isAvailable($res['module'])) return; // Not really possible because getModuleConfig would have failed but we should make sure if ($config->configHook !== false) { - call_user_func($config->configHook, $machineUuid, $res['modeid'], $res['modedata']); + call_user_func($config->configHook, $uuid, $res['modeid'], $res['modedata']); } if ($config->systemdDefaultTarget !== false) { ConfigHolder::add('SLX_SYSTEMD_TARGET', $config->systemdDefaultTarget, 10000); } ConfigHolder::add('SLX_RUNMODE_MODULE', $res['module']); -})($uuid); +} diff --git a/modules-available/runmode/inc/runmode.inc.php b/modules-available/runmode/inc/runmode.inc.php index 65b444e7..2d676cae 100644 --- a/modules-available/runmode/inc/runmode.inc.php +++ b/modules-available/runmode/inc/runmode.inc.php @@ -12,36 +12,36 @@ class RunMode * Get runmode config for a specific module * * @param string $module name of module - * @return \RunModeModuleConfig|false config, false if moudles doesn't support run modes + * @return ?RunModeModuleConfig config, null if module doesn't support run modes */ - public static function getModuleConfig($module) + public static function getModuleConfig(string $module): ?RunModeModuleConfig { if (isset(self::$moduleConfigs[$module])) return self::$moduleConfigs[$module]; if (Module::get($module) === false) - return false; + return null; $file = 'modules/' . $module . '/hooks/runmode/config.json'; if (!file_exists($file)) - return false; + return null; return (self::$moduleConfigs[$module] = new RunModeModuleConfig($file)); } /** - * @param string $machineuuid * @param string|\Module $moduleId * @param string|null $modeId an ID specific to the module to further specify the run mode, NULL to delete the run mode entry * @param string|null $modeData optional, additional data for the run mode * @param bool|null $isClient whether to count the machine as a client (in statistics etc.) NULL for looking at module's general runmode config * @return bool whether it was set/deleted */ - public static function setRunMode($machineuuid, $moduleId, $modeId, $modeData = null, $isClient = null) + public static function setRunMode(string $machineuuid, $moduleId, ?string $modeId, + ?string $modeData = null, ?bool $isClient = null): bool { if (is_object($moduleId)) { $moduleId = $moduleId->getIdentifier(); } // - Check if machine exists $machine = Statistics::getMachine($machineuuid, Machine::NO_DATA); - if ($machine === false) + if ($machine === null) return false; // - Delete entry if mode is null if ($modeId === null) { @@ -72,25 +72,21 @@ class RunMode * Change the isClient flag for existing client. * @param string $machineUuid existing machine with some runmode * @param string $moduleId module that assigned the current runmode of that client - * @param bool $isClient + * @param bool $isClient should this machine be considered a normal client? */ - public static function updateClientFlag($machineUuid, $moduleId, $isClient) + public static function updateClientFlag(string $machineUuid, string $moduleId, bool $isClient): void { Database::exec('UPDATE runmode SET isclient = :isclient WHERE machineuuid = :uuid AND module = :module', ['uuid' => $machineUuid, 'module' => $moduleId, 'isclient' => ($isClient ? 1 : 0)]); } /** - * @param string $machineuuid * @param int $returnData bitfield of data to return * @return false|array {'machineuuid', 'isclient', 'module', 'modeid', 'modedata', * ('hostname', 'clientip', 'macaddr', 'locationid', 'lastseen'), ('moduleName', 'modeName')} */ - public static function getRunMode($machineuuid, $returnData = self::DATA_MACHINE_DATA) + public static function getRunMode(string $machineuuid, int $returnData = self::DATA_MACHINE_DATA) { - if ($returnData === true) { - $returnData = self::DATA_MACHINE_DATA | self::DATA_DETAILED; - } if ($returnData & self::DATA_MACHINE_DATA) { if ($returnData & self::DATA_DETAILED) { $sel = ', m.hostname, m.clientip, m.macaddr, m.locationid, m.lastseen'; @@ -127,11 +123,11 @@ class RunMode } /** - * @param string|\Module $module - * @param bool true = wrap in array where key is modeid - * @return array key=machineuuid, value={'machineuuid', 'modeid', 'modedata'} + * @param string|Module $module + * @param bool $groupByModeId true = wrap in array where key is modeid + * @return array - format depending on $groupByModeId */ - public static function getForModule($module, $groupByModeId = false) + public static function getForModule($module, bool $groupByModeId = false): array { if (is_object($module)) { $module = $module->getIdentifier(); @@ -153,14 +149,14 @@ class RunMode } /** - * @param string|\Module $module - * @param string $modeId + * @param string|Module $module Module the mode belongs to + * @param string $modeId module-specific runmode identifier * @param bool $detailed whether to return meta data about machine, not just machineuuid * @param bool $assoc use machineuuid as array key * @return array , value={'machineuuid', 'modedata', * <'hostname', 'clientip', 'macaddr', 'locationid', 'lastseen'>} */ - public static function getForMode($module, $modeId, $detailed = false, $assoc = false) + public static function getForMode($module, string $modeId, bool $detailed = false, bool $assoc = false): array { if (is_object($module)) { $module = $module->getIdentifier(); @@ -192,11 +188,12 @@ class RunMode /** * Return assoc array of all configured clients. + * * @param bool $withData also return data field? - * @param bool $isClient true = return clients only, false = return non-clients only, null = return both + * @param bool|null $isClient true = return clients only, false = return non-clients only, null = return both * @return array all the entries from the table */ - public static function getAllClients($withData = false, $isClient = null) + public static function getAllClients(bool $withData = false, bool $isClient = null): array { $xtra = ''; if ($withData) { @@ -218,11 +215,11 @@ class RunMode * that method is passed through. getModeName by contract should return false if * the module doesn't think the given modeId exists. * - * @param string|\Module $module - * @param string $modeId - * @return string|bool mode name if known, modeId as fallback, or false if mode is not known by module + * @param string|Module $module module the runmode belongs to + * @param string $modeId module-specific runmode identifier + * @return string|false mode name if known, modeId as fallback, or false if mode is not known by module */ - public static function getModeName($module, $modeId) + public static function getModeName($module, string $modeId) { if (is_object($module)) { $module = $module->getIdentifier(); @@ -236,10 +233,10 @@ class RunMode /** * Delete given runmode. * - * @param string|\Module $module Module runmode belongs to + * @param string|Module $module Module runmode belongs to * @param string $modeId run mode id */ - public static function deleteMode($module, $modeId) + public static function deleteMode($module, string $modeId): void { if (is_object($module)) { $module = $module->getIdentifier(); @@ -317,7 +314,7 @@ class RunModeModuleConfig { if (!isset($data[$key])) return; - if (is_string($type) && gettype($data[$key]) !== $type) + if (gettype($data[$key]) !== $type) return; $this->{$key} = $data[$key]; } diff --git a/modules-available/runmode/page.inc.php b/modules-available/runmode/page.inc.php index cceefae8..5654456a 100644 --- a/modules-available/runmode/page.inc.php +++ b/modules-available/runmode/page.inc.php @@ -30,7 +30,7 @@ class Page_RunMode extends Page $module = Request::post('module', false, 'string'); $modeId = Request::post('modeid', false, 'string'); $modConfig = RunMode::getModuleConfig($module); - if ($modConfig === false) { + if ($modConfig === null) { Message::addError('runmode.module-hasnt-runmode', $module); return; } @@ -70,7 +70,7 @@ class Page_RunMode extends Page if ($oldMachineMode !== false) { $machineLocation = $oldMachineMode['locationid']; $oldModule = RunMode::getModuleConfig($oldMachineMode['module']); - if ($oldModule !== false) { + if ($oldModule !== null) { if ($oldMachineMode['module'] !== $module || $oldMachineMode['modeid'] !== $modeId) { if (!$oldModule->allowGenericEditor || $oldModule->deleteUrlSnippet !== false) { Message::addError('runmode.machine-still-assigned', $machine, $oldMachineMode['module']); @@ -87,7 +87,7 @@ class Page_RunMode extends Page } else { // Not existing, no old mode - query machine to get location, so we can do a perm-check for new loc $m = Statistics::getMachine($machine, Machine::NO_DATA); - if ($m !== false) { + if ($m !== null) { $machineLocation = $m->locationid; } } @@ -134,7 +134,7 @@ class Page_RunMode extends Page return; } $modConfig = RunMode::getModuleConfig($mode['module']); - if ($modConfig === false) { + if ($modConfig === null) { Message::addError('module-hasnt-runmode', $mode['moduleName']); return; } @@ -172,7 +172,7 @@ class Page_RunMode extends Page } $module->activate(1, false); $config = RunMode::getModuleConfig($moduleId); - if ($config === false) { + if ($config === null) { Message::addError('module-hasnt-runmode', $moduleId); Util::redirect('?do=runmode'); } @@ -187,7 +187,6 @@ class Page_RunMode extends Page if (!$config->userHasPermission(null) && !User::hasPermission('list-all')) { Message::addError('main.no-permission'); Util::redirect('?do=runmode'); - return; } // Show list of machines with assigned mode for this module $this->renderClientList($moduleId); @@ -212,7 +211,10 @@ class Page_RunMode extends Page if (!isset($modules[$row['module']])) { if (!Module::isAvailable($row['module'])) continue; - $modules[$row['module']] = array('config' => RunMode::getModuleConfig($row['module']), 'list' => array()); + $config = RunMode::getModuleConfig($row['module']); + if ($config === null) + continue; + $modules[$row['module']] = array('config' => $config, 'list' => array()); } if (empty($row['hostname'])) { $row['hostname'] = $row['clientip']; @@ -244,7 +246,7 @@ class Page_RunMode extends Page 'list' => $rows['list'], 'modulename' => $module->getDisplayName(), 'module' => $moduleId, - 'canedit' => $config !== false && $config->allowGenericEditor && $config->deleteUrlSnippet === false, + 'canedit' => $config !== null && $config->allowGenericEditor && $config->deleteUrlSnippet === false, 'deleteUrl' => $config->deleteUrlSnippet, 'disabled' => $disabled, )); @@ -254,12 +256,7 @@ class Page_RunMode extends Page } } - /** - * @param \Module $module - * @param string $modeId - * @param \RunModeModuleConfig $config - */ - private function renderModuleMode($module, $modeId, $config) + private function renderModuleMode(Module $module, string $modeId, RunModeModuleConfig $config) { $moduleId = $module->getIdentifier(); $modeName = RunMode::getModeName($moduleId, $modeId); @@ -283,7 +280,6 @@ class Page_RunMode extends Page } else { Message::addError('main.no-permission'); Util::redirect('?do=runmode'); - return; } $machines = RunMode::getForMode($module, $modeId, true); if ($config->permission !== false) { @@ -317,7 +313,7 @@ class Page_RunMode extends Page $config = RunMode::getModuleConfig(Request::any('module', '', 'string')); $returnObject = ['machines' => []]; - if ($config !== false) { + if ($config !== null) { $params = ['query' => "%$query%"]; if ($config->permission === false) { // Global diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php index 2abb5153..919861f0 100644 --- a/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentry.inc.php @@ -22,17 +22,13 @@ abstract class BootEntry $this->internalId = $internalId; } - public abstract function supportsMode($mode); + public abstract function supportsMode(string $mode): bool; - /** - * @param ScriptBuilderBase $builder - * @return string - */ - public abstract function toScript($builder); + public abstract function toScript(ScriptBuilderBase $builder): string; - public abstract function toArray(); + public abstract function toArray(): array; - public abstract function addFormFields(&$array); + public abstract function addFormFields(array &$array): void; public function internalId(): string { @@ -48,14 +44,14 @@ abstract class BootEntry * * @param string $module module this entry belongs to, or special values .script/.exec * @param string $data serialized entry data - * @return BootEntry|null instance representing boot entry, null on error + * @return ?BootEntry instance representing boot entry, null on error */ - public static function fromJson($module, $data) + public static function fromJson(string $module, string $data): ?BootEntry { if ($module[0] !== '.') { // Hook from other module $hook = Hook::loadSingle($module, 'ipxe-bootentry'); - if ($hook === false) { + if ($hook === null) { error_log('Module ' . $module . ' doesnt have an ipxe-bootentry hook'); return null; } @@ -64,9 +60,9 @@ abstract class BootEntry return null; return $ret->getBootEntry($data); } - if (is_string($data)) { - $data = json_decode($data, true); - } + $data = json_decode($data, true); + if (!is_array($data)) + return null; if ($module === '.script') { return new CustomBootEntry($data); } @@ -79,12 +75,12 @@ abstract class BootEntry return null; } - public static function forMenu($menuId) + public static function forMenu(int $menuId): MenuBootEntry { return new MenuBootEntry($menuId); } - public static function newStandardBootEntry($initData, $efi = false, $arch = false, string $internalId = '') + public static function newStandardBootEntry($initData, $efi = false, $arch = false, string $internalId = ''): ?StandardBootEntry { $ret = new StandardBootEntry($initData, $efi, $arch, $internalId); $list = []; @@ -104,7 +100,7 @@ abstract class BootEntry return $ret; } - public static function newCustomBootEntry($initData) + public static function newCustomBootEntry($initData): ?CustomBootEntry { if (!is_array($initData) || empty($initData)) return null; @@ -114,15 +110,14 @@ abstract class BootEntry /** * Return a BootEntry instance from database with the given id. * - * @param string $id - * @return BootEntry|null|false false == unknown id, null = unknown entry type, BootEntry instance on success + * @return ?BootEntry null = unknown entry type, BootEntry instance on success */ - public static function fromDatabaseId($id) + public static function fromDatabaseId(string $id): ?BootEntry { $row = Database::queryFirst("SELECT module, data FROM serversetup_bootentry WHERE entryid = :id LIMIT 1", ['id' => $id]); if ($row === false) - return false; + return null; return self::fromJson($row['module'], $row['data']); } @@ -132,7 +127,7 @@ abstract class BootEntry * * @return BootEntry[] all existing BootEntries */ - public static function getAll() + public static function getAll(): array { $res = Database::simpleQuery("SELECT entryid, module, data FROM serversetup_bootentry"); $ret = []; @@ -158,13 +153,13 @@ class StandardBootEntry extends BootEntry */ protected $efi; /** - * @var string BootEntry Constants above + * @var ?string BootEntry Constants above */ protected $arch; const KEYS = ['executable', 'initRd', 'commandLine', 'replace', 'imageFree', 'autoUnload', 'resetConsole', 'dhcpOptions']; - public function __construct($data, $efi = false, $arch = false, string $internalId = '') + public function __construct($data, $efi = false, ?string $arch = null, string $internalId = '') { parent::__construct($internalId); $this->pcbios = new ExecData(); @@ -239,10 +234,7 @@ class StandardBootEntry extends BootEntry } } - /** - * @param PxeSection $data - */ - private function fromPxeMenu($data) + private function fromPxeMenu(PxeSection $data): void { $bios = $this->pcbios; $bios->executable = $data->kernel; @@ -266,12 +258,12 @@ class StandardBootEntry extends BootEntry $bios->commandLine = trim(preg_replace('/\s+/', ' ', $bios->commandLine)); } - public function arch() + public function arch(): ?string { return $this->arch; } - public function supportsMode($mode) + public function supportsMode(string $mode): bool { if ($mode === $this->arch || $this->arch === BootEntry::AGNOSTIC) return true; @@ -282,7 +274,7 @@ class StandardBootEntry extends BootEntry return false; } - public function toScript($builder) + public function toScript(ScriptBuilderBase $builder): string { if ($this->arch === BootEntry::AGNOSTIC) // Same as below, could construct fall-through but this is more clear return $builder->execDataToScript($this->pcbios, null, null); @@ -291,7 +283,7 @@ class StandardBootEntry extends BootEntry $this->supportsMode(BootEntry::EFI) ? $this->efi : null); } - public function addFormFields(&$array) + public function addFormFields(array &$array): void { $array[$this->arch . '_selected'] = 'selected'; $array['entries'][] = $this->pcbios->toFormFields(BootEntry::BIOS); @@ -299,7 +291,10 @@ class StandardBootEntry extends BootEntry $array['exec_checked'] = 'checked'; } - public function toArray() + /** + * @return array{PCBIOS: array, EFI: array, arch: string} + */ + public function toArray(): array { return [ BootEntry::BIOS => $this->pcbios->toArray(), @@ -314,7 +309,7 @@ class CustomBootEntry extends BootEntry /** * @var string iPXE */ - protected $ipxe; + protected $ipxe = ''; protected $bash; @@ -331,12 +326,12 @@ class CustomBootEntry extends BootEntry } } - public function supportsMode($mode) + public function supportsMode(string $mode): bool { return true; } - public function toScript($builder) + public function toScript(ScriptBuilderBase $builder): string { if ($builder instanceof ScriptBuilderIpxe) return $this->ipxe; @@ -345,7 +340,7 @@ class CustomBootEntry extends BootEntry return ''; } - public function addFormFields(&$array) + public function addFormFields(array &$array): void { $array['entry'] = [ 'script' => $this->ipxe, @@ -353,7 +348,10 @@ class CustomBootEntry extends BootEntry $array['script_checked'] = 'checked'; } - public function toArray() + /** + * @return array{script: string} + */ + public function toArray(): array { return ['script' => $this->ipxe]; } @@ -361,31 +359,32 @@ class CustomBootEntry extends BootEntry class MenuBootEntry extends BootEntry { + /** @var int */ protected $menuId; - public function __construct($menuId) + public function __construct(int $menuId) { parent::__construct('menu-' . $menuId); $this->menuId = $menuId; } - public function supportsMode($mode) + public function supportsMode(string $mode): bool { return true; } - public function toScript($builder) + public function toScript(ScriptBuilderBase $builder): string { - $menu = IPxeMenu::get($this->menuId); + $menu = IPxeMenu::get($this->menuId, true); return $builder->menuToScript($menu); } - public function toArray() + public function toArray(): array { return []; } - public function addFormFields(&$array) + public function addFormFields(array &$array): void { } } @@ -401,21 +400,21 @@ class SpecialBootEntry extends BootEntry parent::__construct('special-' . $this->type); } - public function supportsMode($mode) + public function supportsMode(string $mode): bool { return true; } - public function toScript($builder) + public function toScript(ScriptBuilderBase $builder): string { return $builder->getSpecial($this->type); } - public function toArray() + public function toArray(): array { return []; } - public function addFormFields(&$array) { } + public function addFormFields(array &$array): void { } } \ No newline at end of file diff --git a/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php index 060b3903..ab55c888 100644 --- a/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/inc/bootentryhook.inc.php @@ -6,41 +6,37 @@ abstract class BootEntryHook /** * @var string -- set by ipxe, not module implementing hook */ - public $moduleId; + public $moduleId = ''; /** * @var string -- set by ipxe, not module implementing hook */ - public $checked; + public $checked = ''; - private $selectedId; + private $selectedId = ''; private $data = []; /** * @return string */ - public abstract function name(); + public abstract function name(): string; /** * @return HookExtraField[] */ - public abstract function extraFields(); + public abstract function extraFields(): array; - /** - * @param string $id - * @return bool - */ - public abstract function isValidId($id); + public abstract function isValidId(string $id): bool; /** * @return HookEntryGroup[] */ - protected abstract function groupsInternal(); + protected abstract function groupsInternal(): array; /** * @return HookEntryGroup[] */ - public final function groups() + public final function groups(): array { $groups = $this->groupsInternal(); foreach ($groups as $group) { @@ -54,16 +50,13 @@ abstract class BootEntryHook } /** - * @param $id * @return BootEntry|null the actual boot entry instance for given entry, null if invalid id */ - public abstract function getBootEntryInternal($localData); + public abstract function getBootEntryInternal(array $localData): ?BootEntry; - public final function getBootEntry($data) + public final function getBootEntry(string $jsonString): ?BootEntry { - if (!is_array($data)) { - $data = json_decode($data, true); - } + $data = json_decode($jsonString, true); return $this->getBootEntryInternal($data); } @@ -71,7 +64,7 @@ abstract class BootEntryHook * @param string $mixed either the plain ID if the entry to be marked as selected, or the JSON string representing * the entire entry, which must have a key called 'id' that will be used as the ID then. */ - public function setSelected($mixed) + public function setSelected(string $mixed): void { $json = @json_decode($mixed, true); if (is_array($json)) { @@ -86,12 +79,15 @@ abstract class BootEntryHook /** * @return string ID of entry that was marked as selected by setSelected() */ - public function getSelected() + public function getSelected(): string { return $this->selectedId; } - public function renderExtraFields() + /** + * @return HookExtraField[] + */ + public function renderExtraFields(): array { $list = $this->extraFields(); foreach ($list as $entry) { @@ -144,14 +140,7 @@ class HookEntry */ public $selected; - /** - * HookEntry constructor. - * - * @param string $id - * @param string $name - * @param bool $valid - */ - public function __construct($id, $name, $valid) + public function __construct(string $id, string $name, bool $valid) { $this->id = $id; $this->name = $name; @@ -182,7 +171,7 @@ class HookExtraField */ public $hook; - public function __construct($name, $type, $default) + public function __construct(string $name, string $type, $default) { $this->name = $name; $this->type = $type; @@ -203,10 +192,10 @@ class HookExtraField return $val; } - public function html() + public function html(): string { $fieldId = 'extra-' . $this->hook->moduleId . '-' . $this->name; - $fieldText = htmlspecialchars(Dictionary::translateFileModule($this->hook->moduleId, 'module', 'ipxe-' . $this->name, true)); + $fieldText = htmlspecialchars(Dictionary::translateFileModule($this->hook->moduleId, 'module', 'ipxe-' . $this->name)); if (is_array($this->type)) { $out = '