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 --- .../serversetup-bwlp-ipxe/inc/ipxe.inc.php | 146 ++++++++++----------- 1 file changed, 70 insertions(+), 76 deletions(-) (limited to 'modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php') diff --git a/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php b/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php index 8731bb7a..5e0531ab 100644 --- a/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php +++ b/modules-available/serversetup-bwlp-ipxe/inc/ipxe.inc.php @@ -12,9 +12,9 @@ class IPxe * Import all IP-Range based pxe menus from the given directory. * * @param string $configPath The pxelinux.cfg path where to look for menu files in hexadecimal IP format. - * @return Number of menus imported + * @return int Number of menus imported */ - public static function importSubnetPxeMenus($configPath) + public static function importSubnetPxeMenus(string $configPath): int { $res = Database::simpleQuery('SELECT menuid, entryid FROM serversetup_menuentry ORDER BY sortval ASC'); $menus = []; @@ -52,6 +52,10 @@ class IPxe $locations[] = $row; } $menu = PxeLinux::parsePxeLinux($content, true); + if ($menu === null) { + error_log("Skipping empty pxelinux menu file $file"); + continue; + } // Insert all entries first, so we can get the list of entry IDs $entries = []; self::importPxeMenuEntries($menu, $entries); @@ -83,10 +87,10 @@ class IPxe } else { error_log('Imported menu ' . $menu->title . ' is NEW, using for ' . count($locations) . ' locations.'); // Insert new menu - $menuId = self::insertMenu($menu, 'Auto Imported', false, 0, [], []); - if ($menuId === false) + $menuId = self::insertMenu($menu, 'Auto Imported', null, 0, [], []); + if ($menuId === null) continue; - $menus[(int)$menuId] = $entries; + $menus[$menuId] = $entries; $importCount++; } foreach ($locations as $loc) { @@ -103,20 +107,20 @@ class IPxe return $importCount; } - public static function importLegacyMenu($force = false) + public static function importLegacyMenu(bool $force = false): bool { // See if anything is there if (!$force && false !== Database::queryFirst("SELECT menuentryid FROM serversetup_menuentry LIMIT 1")) return false; // Already exists // Now create the default entry self::createDefaultEntries(); - $prepend = ['bwlp-default' => false, 'localboot' => false]; + $prepend = ['bwlp-default' => null, 'localboot' => null]; $defaultLabel = 'bwlp-default'; $menuTitle = 'bwLehrpool Bootauswahl'; $pxeConfig = ''; $timeoutSecs = 60; - // Try to import any customization - $oldMenu = Property::getBootMenu(); + // Try to import any customization of the legacy PXELinux menu (despite the property name hinting at iPXE) + $oldMenu = json_decode(Property::get('ipxe-menu'), true); if (is_array($oldMenu)) { // if (isset($oldMenu['timeout'])) { @@ -136,47 +140,45 @@ class IPxe } } $append = [ - '', - 'bwlp-default-dbg' => false, - '', - 'poweroff' => false, + new PxeSection(null), + 'bwlp-default-dbg' => null, + new PxeSection(null), + 'poweroff' => null, ]; - return self::insertMenu(PxeLinux::parsePxeLinux($pxeConfig, false), $menuTitle, $defaultLabel, $timeoutSecs, $prepend, $append); + self::insertMenu(PxeLinux::parsePxeLinux($pxeConfig, false), $menuTitle, $defaultLabel, $timeoutSecs, $prepend, $append); + return !empty($pxeConfig); } /** - * @param PxeMenu $pxeMenu - * @param string $menuTitle - * @param string|false $defaultLabel Fallback for the default label, if PxeMenu doesn't set one + * @param ?string $defaultLabel Fallback for the default label, if PxeMenu doesn't set one * @param int $defaultTimeoutSeconds Default timeout, if PxeMenu doesn't set one - * @param array $prepend - * @param array $append - * @return int|false + * @param (?PxeSection)[] $prepend + * @param (?PxeSection)[] $append + * @return ?int ID of newly created menu, or null on error, e.g. if the menu is empty */ - public static function insertMenu($pxeMenu, $menuTitle, $defaultLabel, $defaultTimeoutSeconds, $prepend, $append) + public static function insertMenu(?PxeMenu $pxeMenu, string $menuTitle, ?string $defaultLabel, int $defaultTimeoutSeconds, + array $prepend, array $append): ?int { $timeoutMs = []; $menuEntries = $prepend; - settype($menuEntries, 'array'); - if (!empty($pxeMenu)) { - $pxe =& $pxeMenu; - if (!empty($pxe->title)) { - $menuTitle = $pxe->title; + if ($pxeMenu !== null) { + if (!empty($pxeMenu->title)) { + $menuTitle = $pxeMenu->title; } - if ($pxe->timeoutLabel !== null && $pxe->hasLabel($pxe->timeoutLabel)) { - $defaultLabel = $pxe->timeoutLabel; - } elseif ($pxe->hasLabel($pxe->default)) { - $defaultLabel = $pxe->default; + if ($pxeMenu->timeoutLabel !== null && $pxeMenu->hasLabel($pxeMenu->timeoutLabel)) { + $defaultLabel = $pxeMenu->timeoutLabel; + } elseif ($pxeMenu->hasLabel($pxeMenu->default)) { + $defaultLabel = $pxeMenu->default; } - $timeoutMs[] = $pxe->timeoutMs; - $timeoutMs[] = $pxe->totalTimeoutMs; - self::importPxeMenuEntries($pxe, $menuEntries); + $timeoutMs[] = $pxeMenu->timeoutMs; + $timeoutMs[] = $pxeMenu->totalTimeoutMs; + self::importPxeMenuEntries($pxeMenu, $menuEntries); } - if (is_array($append)) { + if (!empty($append)) { $menuEntries += $append; } if (empty($menuEntries)) - return false; + return null; // Make menu $timeoutMs = array_filter($timeoutMs, function($x) { return is_int($x) && $x > 0; }); if (empty($timeoutMs)) { @@ -195,25 +197,29 @@ class IPxe // Figure out entryid for default label // Fiddly diddly way of getting the mangled entryid for the wanted pxe menu label $defaultEntryId = false; + $fallbackDefault = false; foreach ($menuEntries as $entryId => $section) { - if ($section instanceof PxeSection) { - if ($section->isDefault) { - $defaultEntryId = $entryId; - break; - } - if ($section->label === $defaultLabel) { - $defaultEntryId = $entryId; - } + if ($section === null) + continue; + if ($section->isDefault) { + $defaultEntryId = $entryId; + break; + } + if ($section->label === $defaultLabel) { + $defaultEntryId = $entryId; + } + if ($fallbackDefault === false && !empty($entryId)) { + $fallbackDefault = $entryId; } } if ($defaultEntryId === false) { - $defaultEntryId = array_keys($menuEntries)[0]; + $defaultEntryId = $fallbackDefault; } // Link boot entries to menu $defaultMenuEntryId = null; $order = 1000; foreach ($menuEntries as $entryId => $entry) { - if (is_string($entry)) { + if ($entry !== null && $entry->isTextOnly()) { // Gap entry Database::exec("INSERT INTO serversetup_menuentry (menuid, entryid, hotkey, title, hidden, sortval, plainpass, md5pass) @@ -221,7 +227,7 @@ class IPxe 'menuid' => $menuId, 'entryid' => null, 'hotkey' => '', - 'title' => self::sanitizeIpxeString($entry), + 'title' => self::sanitizeIpxeString($entry->title), 'hidden' => 0, 'sortval' => $order += 100, ]); @@ -232,7 +238,7 @@ class IPxe continue; $data['pass'] = ''; $data['hidden'] = 0; - if ($entry instanceof PxeSection) { + if ($entry !== null) { $data['hidden'] = (int)$entry->isHidden; // Prefer explicit data from this imported menu over the defaults $title = self::sanitizeIpxeString($entry->title); @@ -243,7 +249,7 @@ class IPxe $data['hotkey'] = $entry->hotkey; } if (!empty($entry->passwd)) { - // Most likely it's a hash so we cannot recover; ask people to reset + // Most likely it's a hash, so we cannot recover; ask people to reset $data['pass'] ='please_reset'; } } @@ -268,36 +274,28 @@ class IPxe /** * Import only the bootentries from the given PXELinux menu - * @param PxeMenu $pxe - * @param array $menuEntries Where to append the generated menu items to + * + * @param PxeSection[] $menuEntries Where to append the generated menu items to */ - public static function importPxeMenuEntries($pxe, &$menuEntries) + public static function importPxeMenuEntries(PxeMenu $pxe, array &$menuEntries): void { if (self::$allEntries === false) { self::$allEntries = BootEntry::getAll(); } foreach ($pxe->sections as $section) { - if ($section->localBoot !== false || preg_match('/chain\.c32$/i', $section->kernel)) { + if ($section->isLocalboot()) { $menuEntries['localboot'] = $section; continue; } - if ($section->label === null) { - if (!$section->isHidden && !empty($section->title)) { - $menuEntries[] = $section->title; - } - continue; - } - if (empty($section->kernel)) { - if (!$section->isHidden && !empty($section->title)) { - $menuEntries[] = $section->title; - } + if ($section->isTextOnly()) { + $menuEntries[] = $section; continue; } $label = self::cleanLabelFixLocal($section); $entry = self::pxe2BootEntry($section); if ($entry === null) continue; // Error? Ignore - if ($label !== false || ($label = array_search($entry, self::$allEntries))) { + if ($label !== false || ($label = array_search($entry, self::$allEntries)) !== false) { // Exact Duplicate, Do Nothing error_log('Ignoring duplicate boot entry ' . $section->label . ' (' . $section->kernel . ')'); } else { @@ -321,7 +319,7 @@ class IPxe Database::exec('INSERT IGNORE INTO serversetup_bootentry (entryid, module, hotkey, title, builtin, data) VALUES (:label, :module, :hotkey, :title, 0, :data)', [ 'label' => $label, - 'module' => ($entry instanceof \StandardBootEntry) ? '.exec' : '.script', + 'module' => ($entry instanceof StandardBootEntry) ? '.exec' : '.script', 'hotkey' => $hotkey, 'title' => $title, 'data' => json_encode($data), @@ -408,10 +406,9 @@ class IPxe * Also it patches the entry if it's referencing the local bwlp install * but with different options. * - * @param PxeSection $section * @return string|false existing label if match, false otherwise */ - private static function cleanLabelFixLocal($section) + private static function cleanLabelFixLocal(PxeSection $section) { $myip = Property::getServerIp(); // Detect our "old" entry types @@ -434,10 +431,9 @@ class IPxe } /** - * @param PxeSection $section * @return BootEntry|null The according boot entry, null if it's unparsable */ - private static function pxe2BootEntry($section) + private static function pxe2BootEntry(PxeSection $section): ?BootEntry { if (preg_match('/(pxechain\.com|pxechn\.c32)$/i', $section->kernel)) { // Chaining -- create script @@ -496,11 +492,8 @@ class IPxe /** * Parse PXELINUX file notion. Basically, turn * server::file into tftp://server/file. - * - * @param string $file - * @return string */ - private static function parseFile($file) + private static function parseFile(string $file): string { if (preg_match(',^([^:/]+)::(.*)$,', $file, $out)) { return 'tftp://' . $out[1] . '/' . $out[2]; @@ -508,12 +501,12 @@ class IPxe return $file; } - public static function sanitizeIpxeString($string) + public static function sanitizeIpxeString(string $string): string { return str_replace(['&', '|', ';', '$', "\r", "\n"], ['+', '/', ':', 'S', ' ', ' '], $string); } - public static function makeMd5Pass($plainpass, $salt) + public static function makeMd5Pass(string $plainpass, string $salt): string { if (empty($plainpass)) return ''; @@ -528,11 +521,12 @@ class IPxe * remove any occurrence of either "option" or "option=something". If the argument starts with a * '+', it will be added to the command line after removing the '+'. If the argument starts with any * other character, it will also be added to the command line. + * * @param string $cmdLine command line to modify - * @param string $modifier modification string of space separated arguments + * @param string $modifier modification string of space separated arguments * @return string the modified command line */ - public static function modifyCommandLine($cmdLine, $modifier) + public static function modifyCommandLine(string $cmdLine, string $modifier): string { $items = preg_split('/\s+/', $modifier, -1, PREG_SPLIT_NO_EMPTY); foreach ($items as $item) { -- cgit v1.2.3-55-g7522