addArgument('tenant', InputArgument::REQUIRED, 'Tenant identifier or domain') ->addArgument('office-server', InputArgument::REQUIRED, 'Office server HTTPS base URL') ->addOption('origin-server', null, InputOption::VALUE_REQUIRED, 'Application HTTPS origin reachable from the office server (defaults to the tenant domain)'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); try { $tenantArgument = $input->getArgument('tenant'); $tenant = $this->tenants->fetchById($tenantArgument); $matchedByDomain = $tenant === null; $tenant ??= $this->tenants->fetchByDomain($tenantArgument); if ($tenant === null || !$tenant->getEnabled()) { $io->error('An enabled tenant is required.'); return Command::FAILURE; } $origin = $input->getOption('origin-server'); if ($origin === null) { $domains = array_values(array_unique($tenant->getDomains()?->getArrayCopy() ?? [])); if ($matchedByDomain) { $origin = 'https://' . $tenantArgument; } elseif (count($domains) === 1) { $origin = 'https://' . $domains[0]; } else { $io->error('Specify --origin-server or select the tenant by domain; its origin server cannot be determined unambiguously.'); return Command::FAILURE; } } $wopi = $this->tenants->fetchServiceConfiguration($tenant->getIdentifier(), 'wopi') ?? []; unset($wopi['origin_server']); $wopi = array_replace($wopi, ['enabled' => true, 'office_server' => $input->getArgument('office-server'), 'origin_server' => $origin]); $config = new Configuration($wopi); $document = $this->discovery->fetch($config->office); $viewable = array_filter($document->actions, static fn ($action) => $action->extension === 'docx' && $action->name === 'view' && $action->supportedBy([])); if (!$document->hasProofKeys || $viewable === []) { $io->error('The office server must advertise DOCX viewing and proof keys. Settings were not changed.'); return Command::FAILURE; } $wopi['office_server'] = $config->office->url; $wopi['origin_server'] = $config->origin->origin; if ($input->getOption('origin-server') === null && count(array_unique($tenant->getDomains()?->getArrayCopy() ?? [])) === 1) { unset($wopi['origin_server']); } // Preserve the selected origin when a tenant has multiple aliases. if (!$this->tenants->storeServiceConfiguration($tenant->getIdentifier(), 'wopi', $wopi)) { $io->error('Could not save tenant office settings.'); return Command::FAILURE; } $io->success('Office viewing configured in the tenant database. Reload the application to register the viewer.'); $io->note('The office server must resolve the application hostname and trust its HTTPS certificate. Discovery does not test that return connection.'); return Command::SUCCESS; } catch (\Throwable) { $io->error('Configuration failed. Check the tenant, HTTPS URLs, and office discovery.'); return Command::FAILURE; } } }