addArgument('pfad', InputArgument::OPTIONAL, 'Die neue Adresse, ohne Schrägstrich. Ohne Angabe wird die aktuelle gezeigt.'); } protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); $neu = trim((string) $input->getArgument('pfad'), " \t/"); if ('' === $neu) { $io->writeln(sprintf('Die Verwaltung liegt unter /%s.', $this->adminPath)); $io->writeln('Ändern: php bin/console cms:admin:path meine-verwaltung'); return Command::SUCCESS; } if (1 !== preg_match('/^[a-z0-9]+(?:-[a-z0-9]+)*$/D', $neu) || strlen($neu) > 40) { $io->error('Erlaubt sind Kleinbuchstaben, Ziffern und Bindestriche, höchstens 40 Zeichen.'); return Command::FAILURE; } if (in_array($neu, self::TABU, true)) { $io->error(sprintf('„%s" ist für die Website selbst reserviert.', $neu)); return Command::FAILURE; } // Eine Seite mit dieser Adresse wäre von der Verwaltung verdeckt - unauffindbar, ohne dass // jemand merkt, warum. $seite = $this->db->fetchOne('SELECT path FROM page WHERE website_id = ? AND path = ? AND deleted_at IS NULL', ['default', $neu]); if (is_string($seite)) { $io->error(sprintf('Es gibt bereits eine Seite unter /%s. Die Verwaltung würde sie verdecken.', $neu)); return Command::FAILURE; } $datei = $this->projectDir.'/.env.local'; $inhalt = is_file($datei) ? (string) file_get_contents($datei) : ''; $zeile = sprintf('ADMIN_PATH=%s', $neu); $inhalt = 1 === preg_match('/^ADMIN_PATH=.*$/m', $inhalt) ? (string) preg_replace('/^ADMIN_PATH=.*$/m', $zeile, $inhalt) : rtrim($inhalt)."\n".$zeile."\n"; if (false === @file_put_contents($datei, ltrim($inhalt, "\n"))) { $io->error('.env.local ist nicht beschreibbar. Trage dort von Hand ein: '.$zeile); return Command::FAILURE; } // Ohne das Aufräumen gälte die alte Adresse weiter - und die neue wäre nicht erreichbar. // Die Umgebung, in der dieser Befehl gerade läuft, bleibt dabei unangetastet: Symfony lädt // Dienste nach, und wer sich den Boden unter den Füßen wegräumt, endet mit einem Fehler, // obwohl alles geklappt hat. Der nächste Aufruf baut sie ohnehin neu. $offen = []; foreach (glob($this->projectDir.'/var/cache/*') ?: [] as $pfad) { if (!is_dir($pfad)) { continue; } if (basename($pfad) === $this->environment) { $offen[] = basename($pfad); continue; } $this->removeDirectory($pfad); } $io->success(sprintf('Die Verwaltung liegt jetzt unter /%s.', $neu)); if ([] !== $offen) { $io->writeln(sprintf('Falls die Website noch die alte Adresse kennt: php bin/console cache:clear --env=%s', implode(' --env=', $offen))); } if ($this->adminPath !== $neu) { $io->writeln('Merk dir die Adresse: /'.$this->adminPath.' antwortet ab sofort mit 404, wie jede andere unbekannte Adresse auch.'); } $io->writeln('Zurück geht es mit: php bin/console cms:admin:path admin'); return Command::SUCCESS; } private function removeDirectory(string $pfad): void { if (!is_dir($pfad)) { return; } foreach (scandir($pfad) ?: [] as $eintrag) { if ('.' === $eintrag || '..' === $eintrag) { continue; } $voll = $pfad.'/'.$eintrag; is_dir($voll) ? $this->removeDirectory($voll) : @unlink($voll); } @rmdir($pfad); } }