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);
}
}