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 --- .../sysconfig/inc/configmodule.inc.php | 197 ++++++++++++--------- 1 file changed, 109 insertions(+), 88 deletions(-) (limited to 'modules-available/sysconfig/inc/configmodule.inc.php') diff --git a/modules-available/sysconfig/inc/configmodule.inc.php b/modules-available/sysconfig/inc/configmodule.inc.php index e414a6cf..729cb959 100644 --- a/modules-available/sysconfig/inc/configmodule.inc.php +++ b/modules-available/sysconfig/inc/configmodule.inc.php @@ -7,18 +7,23 @@ abstract class ConfigModule { /** - * @var array list of known module types + * @var ?array{'title': string, + * 'description': string, + * 'group': string, + * 'unique': bool, + * 'sortOrder': int, + * 'moduleClass': string, + * 'wizardClass': string}[] list of known module types */ - private static $moduleTypes = false; + private static $moduleTypes = null; private $moduleId = 0; - private $moduleArchive = false; - private $moduleTitle = false; - private $moduleStatus = false; - /** - * @var int - */ + private $moduleArchive = ''; + private $moduleTitle = ''; + private $moduleStatus = 'MISSING'; + /** @var int */ private $dateline = 0; + /** @var int */ private $currentVersion = 0; /** * @var false|array Data of module, false if not initialized @@ -33,9 +38,9 @@ abstract class ConfigModule */ public static function loadDb() { - if (self::$moduleTypes !== false) + if (self::$moduleTypes !== null) return; - self::$moduleTypes = array(); + self::$moduleTypes = []; Module::isAvailable('sysconfig'); foreach (glob(dirname(__FILE__) . '/configmodule/*.inc.php', GLOB_NOSORT) as $file) { require_once $file; @@ -44,10 +49,16 @@ abstract class ConfigModule /** * Get all known config module types. - * - * @return array list of modules + * @return array{'title': string, + * 'description': string, + * 'group': string, + * 'unique': bool, + * 'sortOrder': int, + * 'moduleClass': string, + * 'wizardClass': string}[] list of known module types + * / */ - public static function getList() + public static function getList(): array { self::loadDb(); return self::$moduleTypes; @@ -63,9 +74,9 @@ abstract class ConfigModule * @param string $description Description for this module type * @param string $group Title for group this module type belongs to * @param bool $unique Can only one such module be added to a config? - * @param int $sortOrder Lower comes first, alphabetical ordering otherwiese + * @param int $sortOrder Lower comes first, alphabetical ordering otherwise */ - public static function registerModule($id, $title, $description, $group, $unique, $sortOrder = 0) + public static function registerModule(string $id, string $title, string $description, string $group, bool $unique, int $sortOrder = 0): void { if (isset(self::$moduleTypes[$id])) { ErrorHandler::traceError("Config Module $id already registered!"); @@ -93,21 +104,33 @@ abstract class ConfigModule * Get fresh instance of ConfigModule subclass for given module type. * * @param string $moduleType name of module type - * @return false|\ConfigModule module instance + * @return ConfigModule module instance */ - public static function getInstance($moduleType) + public static function getInstance(string $moduleType): ConfigModule + { + $ret = self::getInstanceOrNull($moduleType); + if ($ret === null) { + Message::addError('main.error-read', $moduleType . '.inc.php'); + Util::redirect('?do=sysconfig'); + } + return $ret; + } + + public static function getInstanceOrNull(string $moduleType): ?ConfigModule { self::loadDb(); if (!isset(self::$moduleTypes[$moduleType])) { error_log('Unknown module type: ' . $moduleType); - return false; + return null; } return new self::$moduleTypes[$moduleType]['moduleClass']; } - public static function instanceFromDbRow($dbRow) + private static function instanceFromDbRow(array $dbRow): ?ConfigModule { - $instance = self::getInstance($dbRow['moduletype']); + $instance = self::getInstanceOrNull($dbRow['moduletype']); + if ($instance === null) + return null; $instance->currentVersion = $dbRow['version']; $instance->moduleArchive = $dbRow['filepath']; $instance->moduleData = json_decode($dbRow['contents'], true); @@ -125,37 +148,37 @@ abstract class ConfigModule * Get module instance from id. * * @param int $moduleId module id to get - * @return false|\ConfigModule The requested module from DB, or false on error + * @return ?ConfigModule The requested module from DB, or null on error */ - public static function get($moduleId) + public static function get(int $moduleId): ?ConfigModule { $ret = Database::queryFirst("SELECT moduleid, title, moduletype, filepath, contents, version, status, dateline FROM configtgz_module " . " WHERE moduleid = :moduleid LIMIT 1", array('moduleid' => $moduleId)); if ($ret === false) - return false; + return null; return self::instanceFromDbRow($ret); } /** * Get module instances from module type. * - * @param int $moduleType module type to get - * @return \ConfigModule[]|false The requested modules from DB, or false on error + * @param string $moduleType module type to get + * @return ?ConfigModule[] The requested modules from DB, or null on error */ - public static function getAll($moduleType = false) + public static function getAll(string $moduleType = null): ?array { - if ($moduleType === false) { + if ($moduleType === null) { $ret = Database::simpleQuery("SELECT moduleid, title, moduletype, filepath, contents, version, status, dateline FROM configtgz_module"); } else { $ret = Database::simpleQuery("SELECT moduleid, title, moduletype, filepath, contents, version, status, dateline FROM configtgz_module " . " WHERE moduletype = :moduletype", array('moduletype' => $moduleType)); } if ($ret === false) - return false; + return null; $list = array(); foreach ($ret as $row) { $instance = self::instanceFromDbRow($row); - if ($instance === false) + if ($instance === null) continue; $list[] = $instance; } @@ -167,37 +190,37 @@ abstract class ConfigModule * * @return int module version */ - protected abstract function moduleVersion(); + protected abstract function moduleVersion(): int; /** * Validate the module's configuration. * - * @return boolean ok or not + * @return bool ok or not */ - protected abstract function validateConfig(); + protected abstract function validateConfig(): bool; /** * Set module specific data. * * @param string $key key, name or id of data being set * @param mixed $value Module specific data - * @return boolean true if data was successfully set, false otherwise (i.e. invalid data being set) + * @return bool true if data was successfully set, false otherwise (i.e. invalid data being set) */ - public abstract function setData($key, $value); + public abstract function setData(string $key, $value): bool; /** * Get module specific data. * Can be overridden by modules. * - * @param string $key key, name or id of data to get, or false to get the raw moduleData array + * @param ?string $key key, name or id of data to get, or null to get the raw moduleData array * @return mixed Module specific data */ - public function getData($key) + public function getData(?string $key) { - if ($key === false) + if ($key === null) return $this->moduleData; if (!is_array($this->moduleData) || !isset($this->moduleData[$key])) - return false; + return null; return $this->moduleData[$key]; } @@ -205,25 +228,25 @@ abstract class ConfigModule * Module specific version of generate. * * @param string $tgz File name of tgz module to write final output to - * @param string $parent Parent task of this task + * @param string|null $parent Parent task of this task * @return array|boolean true if generation is completed immediately, * a task struct if some task needs to be run for generation, * false on error */ - protected abstract function generateInternal($tgz, $parent); + protected abstract function generateInternal(string $tgz, ?string $parent); - private function createFileName() + private function createFileName(): string { return CONFIG_TGZ_LIST_DIR . '/modules/' . $this->moduleType() . '_id-' . $this->moduleId . '__' . mt_rand() . '-' . time() . '.tgz'; } - public function allowDownload() + public function allowDownload(): bool { return false; } - public function needRebuild() + public function needRebuild(): bool { return $this->moduleStatus !== 'OK' || $this->currentVersion < $this->moduleVersion(); } @@ -233,17 +256,15 @@ abstract class ConfigModule * * @return int id */ - public final function id() + public final function id(): int { return $this->moduleId; } /** * Get module title. - * - * @return string */ - public final function title() + public final function title(): string { return $this->moduleTitle; } @@ -253,17 +274,17 @@ abstract class ConfigModule * * @return string tgz file absolute path */ - public final function archive() + public final function archive(): string { return $this->moduleArchive; } - public final function status() + public final function status(): string { return $this->moduleStatus; } - public final function currentVersion() + public final function currentVersion(): int { return $this->currentVersion; } @@ -273,11 +294,10 @@ abstract class ConfigModule * * @return string module type */ - public final function moduleType() + public final function moduleType(): string { + // Yes, need to pass $this, otherwise we get ConfigModule, the base class this function is part of $name = get_class($this); - if ($name === false) - ErrorHandler::traceError('ConfigModule::moduleType: get_class($this) returned false!'); // ConfigModule_* if (!preg_match('/^ConfigModule_(\w+)$/', $name, $out)) ErrorHandler::traceError('ConfigModule::moduleType: get_class($this) returned "' . $name . '"'); @@ -292,7 +312,7 @@ abstract class ConfigModule * @param string $title display name of the module * @return boolean true if inserted successfully, false if module config is invalid */ - public final function insert($title) + public final function insert(string $title): bool { if ($this->moduleId !== 0) ErrorHandler::traceError('ConfigModule::insert called when moduleId != 0'); @@ -326,7 +346,7 @@ abstract class ConfigModule * * @return boolean true on success, false otherwise */ - public final function update($title = '') + public final function update(string $title = ''): bool { if ($this->moduleId === 0) ErrorHandler::traceError('ConfigModule::update called when moduleId == 0'); @@ -353,15 +373,15 @@ abstract class ConfigModule * Updating the database etc. will happen later through a callback. * * @param boolean $deleteOnError if true, the db entry will be deleted if generation failed - * @param string $parent Parent task of this task + * @param string|null $parent Parent task of this task * @param int $timeoutMs maximum time in milliseconds we wait for completion * @return string|boolean task id if deferred generation was started, * true if generation succeeded (without using a task or within $timeoutMs) * false on error */ - public final function generate($deleteOnError, $parent = NULL, $timeoutMs = 0) + public final function generate(bool $deleteOnError, string $parent = NULL, int $timeoutMs = 0) { - if ($this->moduleId === 0 || $this->moduleTitle === false) + if ($this->moduleId === 0 || empty($this->moduleTitle)) ErrorHandler::traceError('ConfigModule::generateAsync called on uninitialized/uninserted module!'); $tmpTgz = '/tmp/bwlp-id-' . $this->moduleId . '_' . mt_rand() . '_' . time() . '.tgz'; $ret = $this->generateInternal($tmpTgz, $parent); @@ -395,7 +415,7 @@ abstract class ConfigModule /** * Delete the module. */ - public final function delete() + public final function delete(): void { if ($this->moduleId === 0) ErrorHandler::traceError('ConfigModule::delete called with invalid module id!'); @@ -410,17 +430,19 @@ abstract class ConfigModule $this->moduleTitle = false; $this->moduleArchive = false; } - return $ret; } - private function markUpdated($tmpTgz) + /** + * @param ?string $tmpTgz new tar archive to use for this module, or null if the old one is still valid + */ + private function markUpdated(?string $tmpTgz): bool { if ($this->moduleId === 0) ErrorHandler::traceError('ConfigModule::markUpdated called with invalid module id!'); - if ($this->moduleArchive === false) + if ($this->moduleArchive === null) $this->moduleArchive = $this->createFileName(); // Move file - if ($tmpTgz === false) { + if ($tmpTgz === null) { if (!file_exists($this->moduleArchive)) { EventLog::failure('ConfigModule::markUpdated for "' . $this->moduleTitle . '" called with no tmpTgz and no existing tgz!'); $this->markFailed(); @@ -460,16 +482,18 @@ abstract class ConfigModule return $retval; } - private function markFailed() + private function markFailed(): void { if ($this->moduleId === 0) ErrorHandler::traceError('ConfigModule::markFailed called with invalid module id!'); - if ($this->moduleArchive === false) + if ($this->moduleArchive === '') { $this->moduleArchive = $this->createFileName(); - if (!file_exists($this->moduleArchive)) + } + if (!file_exists($this->moduleArchive)) { $status = 'MISSING'; - else + } else { $status = 'OUTDATED'; + } Database::exec("UPDATE configtgz_module SET filepath = :filename, status = :status WHERE moduleid = :id LIMIT 1", array( 'id' => $this->moduleId, 'filename' => $this->moduleArchive, @@ -477,7 +501,7 @@ abstract class ConfigModule )); } - public function dateline_s() + public function dateline_s(): string { return Util::prettyTime($this->dateline); } @@ -489,7 +513,7 @@ abstract class ConfigModule * Override this if you need to handle this, otherwise * the base implementation does nothing. */ - public function event_serverIpChanged() + public function event_serverIpChanged(): void { // Do::Nothing() } @@ -500,11 +524,10 @@ abstract class ConfigModule * Will be called if the server's IP address changes. The event will be propagated * to all config module classes so action can be taken if appropriate. */ - public static function serverIpChanged() + public static function serverIpChanged(): void { self::loadDb(); - $list = self::getAll(); - foreach ($list as $mod) { + foreach (self::getAll() ?? [] as $mod) { $mod->event_serverIpChanged(); } } @@ -513,53 +536,51 @@ abstract class ConfigModule * Called when (re)generating a config module failed, so we can * update the status in the DB and add a server log entry. * - * @param array $task - * @param array $args contains 'moduleid' and optionally 'deleteOnError' and 'tmpTgz' + * @param array $args contains 'moduleid' and optionally 'deleteOnError' */ - public static function generateFailed($task, $args) + public static function generateFailed(array $task, array $args): void { if (!isset($args['moduleid']) || !is_numeric($args['moduleid'])) { EventLog::warning('Ignoring generateFailed event as it has no moduleid assigned.'); return; } $module = self::get($args['moduleid']); - if ($module === false) { + if ($module === null) { EventLog::warning('generateFailed callback for module id ' . $args['moduleid'] . ', but no instance could be generated.'); return; } - if (isset($task['data']['error'])) + if (isset($task['data']['error'])) { $error = $task['data']['error']; - elseif (isset($task['data']['messages'])) + } elseif (isset($task['data']['messages'])) { $error = $task['data']['messages']; - else + } else { $error = ''; + } EventLog::failure("Generating module '" . $module->moduleTitle . "' failed.", $error); - if ($args['deleteOnError']) + if ($args['deleteOnError'] ?? false) { $module->delete(); - else + } else { $module->markFailed(); + } } /** * (Re)generating a config module succeeded. Update db entry. * - * @param array $args contains 'moduleid' and optionally 'deleteOnError' and 'tmpTgz' + * @param array $args contains 'moduleid' and optionally 'tmpTgz' */ - public static function generateSucceeded($args) + public static function generateSucceeded(array $args): void { if (!isset($args['moduleid']) || !is_numeric($args['moduleid'])) { EventLog::warning('Ignoring generateSucceeded event as it has no moduleid assigned.'); return; } $module = self::get($args['moduleid']); - if ($module === false) { + if ($module === null) { EventLog::warning('generateSucceeded callback for module id ' . $args['moduleid'] . ', but no instance could be generated.'); return; } - if (isset($args['tmpTgz'])) - $module->markUpdated($args['tmpTgz']); - else - $module->markUpdated(false); + $module->markUpdated($args['tmpTgz'] ?? null); } } -- cgit v1.2.3-55-g7522