<?phpnamespace App\Form;use App\Feature\Pools\HostAddresses;use App\Model\Connection;use App\Model\Session;use JumPHP\Gui\Button;use JumPHP\Gui\Container;use JumPHP\Gui\Form;use JumPHP\Gui\Label;use JumPHP\Gui\TextBox;/** * Connection Addresses: for a pool reached through a VPN / a NAT, the address of each host as the user's computer reaches it. One * row per host: its name, XAPI's address, a field (placeholder: the address used when it stays empty). Closes with * ['hostAddresses' => ['connection' => profile key, 'addresses' => [host uuid => address]]]; PoolActions saves it in the profile. * * @property Label $heading * @property Label $where * @property Container $rows * @property Label $error * @property Button $ok * @property Button $cancel */final class HostAddressesForm extends Form{ public function __construct(private Session $session) { parent::__construct(); } /** XAPI's answers, events and the console go on while this dialog is open. */ protected function tick(float $dt): void { $this->session->tick($dt); } private array $params = []; /** @var array<string, TextBox> host uuid => its field */ public array $fields = []; /** @return array<string, mixed> */ public static function paramsFor(Connection $c): array { $hosts = []; $master = (string)$c->cache->master(); foreach ($c->cache->hosts() as $ref => $h) { $guess = HostAddresses::guess($c, $ref); $hosts[] = ['uuid' => (string)$h['uuid'], 'name' => (string)$h['name_label'] . ($ref === $master ? ' (master)' : ''), 'xapi' => (string)$h['address'], 'value' => (string)(HostAddresses::userSet($c, $ref) ?? ''), 'default' => $guess ?? (string)$h['address']]; } return ['connection' => $c->profile->key(), 'name' => $c->name(), 'hosts' => $hosts]; } protected function loaded(array $params = []): void { $this->params = $params; $this->heading->text = 'Connection Addresses'; $this->where->text = "Servers of '" . ($params['name'] ?? '') . "'"; $this->error->text = ''; $this->rows->clear(); $this->fields = []; foreach ((array)($params['hosts'] ?? []) as $h) { $field = new TextBox(['text' => $h['value'], 'placeholder' => $h['default'], 'grow' => 1]); $this->fields[$h['uuid']] = $field; $this->rows->add((new Container(['layout' => 'row', 'gap' => 10, 'items' => 'center']))->add( (new Container(['layout' => 'column', 'gap' => 0, 'width' => 200]))->add( new Label(['text' => $h['name']]), new Label(['text' => 'XAPI: ' . $h['xapi'], 'style' => 'muted', 'size' => 11]), ), $field, )); } $first = reset($this->fields); $this->setFocus($first === false ? null : $first); } public function onOkClick(Button $sender): void { $addresses = []; foreach ($this->fields as $uuid => $field) { $value = trim($field->text); if ($value !== '' && !preg_match('/^[A-Za-z0-9.\-:\[\]]+$/', $value)) { $this->error->text = "'$value' is not a host name or an address."; return; } $addresses[$uuid] = $value; } $this->close(['hostAddresses' => ['connection' => (string)$this->params['connection'], 'addresses' => HostAddresses::clean($addresses)]]); } public function onCancelClick(Button $sender): void { $this->close(); }}