$menu]); if (!is_array($menu)) { $menu = ['menuid' => 'foo', 'title' => 'Invalid Menu ID: ' . (int)$menu]; } } $this->menuid = (int)$menu['menuid']; $this->timeoutMs = (int)$menu['timeoutms']; $this->title = $menu['title']; $this->defaultEntryId = $menu['defaultentryid']; $res = Database::simpleQuery("SELECT e.menuentryid, e.entryid, e.refmenuid, e.hotkey, e.title, e.hidden, e.sortval, e.md5pass, b.module, b.data AS bootentry FROM serversetup_menuentry e LEFT JOIN serversetup_bootentry b USING (entryid) WHERE e.menuid = :menuid ORDER BY e.sortval ASC, e.title ASC", ['menuid' => $menu['menuid']]); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { $this->items[] = new MenuEntry($row); } // Make sure we have a default entry if the menu isn't empty if ($this->defaultEntryId === null && !empty($this->items)) { $this->defaultEntryId = $this->items[0]->menuEntryId(); } } public function getMenuDefinition($targetVar, $mode, $slxExtensions) { $str = "menu -- {$this->title}\n"; foreach ($this->items as $item) { $str .= $item->getMenuItemScript("m_{$this->menuid}", $this->defaultEntryId, $mode, $slxExtensions); } if ($this->defaultEntryId === null) { $defaultLabel = "mx_{$this->menuid}_poweroff"; } else { $defaultLabel = "m_{$this->menuid}_{$this->defaultEntryId}"; } $str .= "choose"; if ($this->timeoutMs > 0) { $str .= " --timeout {$this->timeoutMs}"; } $str .= " $targetVar || goto $defaultLabel || goto fail\n"; if ($this->defaultEntryId === null) { $str .= "goto skip_{$defaultLabel}\n" . ":{$defaultLabel}\n" . "poweroff || goto fail\n" . ":skip_{$defaultLabel}\n"; } return $str; } public function getItemsCode($mode) { $str = ''; foreach ($this->items as $item) { $str .= $item->getBootEntryScript("m_{$this->menuid}", 'fail', $mode); $str .= "goto slx_menu\n"; } return $str; } public function title() { return $this->title; } public function timeoutMs() { return $this->timeoutMs; } /** * @return int Number of items in this menu */ public function itemCount() { return count($this->items); } /** * @return string|false Return script label of default entry, false if not set */ public function getDefaultScriptLabel() { if ($this->defaultEntryId !== null) return "m_{$this->menuid}_{$this->defaultEntryId}"; return false; } /** * @return MenuEntry|null Return preselected menu entry */ public function defaultEntry() { foreach ($this->items as $item) { if ($item->menuEntryId() == $this->defaultEntryId) return $item; } return null; } /* * */ public static function forLocation($locationId) { $chain = null; if (Module::isAvailable('locations')) { $chain = Location::getLocationRootChain($locationId); } if (!empty($chain)) { $res = Database::simpleQuery("SELECT m.menuid, m.timeoutms, m.title, IFNULL(ml.defaultentryid, m.defaultentryid) AS defaultentryid, ml.locationid FROM serversetup_menu m INNER JOIN serversetup_menu_location ml USING (menuid) WHERE ml.locationid IN (:chain)", ['chain' => $chain]); if ($res->rowCount() > 0) { // Make the location id key, preserving order (closest location is first) $chain = array_flip($chain); while ($row = $res->fetch(PDO::FETCH_ASSOC)) { // Overwrite the value (numeric ascending values, useless) with menu array of according location $chain[(int)$row['locationid']] = $row; } // Use first one that was found foreach ($chain as $menu) { if (is_array($menu)) { return new IPxeMenu($menu); } } // Should never end up here, but we'd just fall through and use the default } } // We're here, no specific menu, use default $menu = Database::queryFirst("SELECT menuid, timeoutms, title, defaultentryid FROM serversetup_menu ORDER BY isdefault DESC LIMIT 1"); if ($menu === false) { return new EmptyIPxeMenu; } return new IPxeMenu($menu); } public static function forClient($ip, $uuid) { $locationId = 0; if (Module::isAvailable('locations')) { $locationId = Location::getFromIpAndUuid($ip, $uuid); } return self::forLocation($locationId); } } class EmptyIPxeMenu extends IPxeMenu { /** @noinspection PhpMissingParentConstructorInspection */ public function __construct() { $this->title = 'No menu defined'; $this->menuid = -1; $this->items[] = new MenuEntry([ 'title' => 'Please create a menu in Server-Setup first' ]); $this->items[] = new MenuEntry([ 'title' => 'Bitte erstellen Sie zunächst ein Menü' ]); } }