pages->listForEditor() as $page) { // Only a published page can serve as the root; a draft would answer every visit with 404. if ('page' === $page['type'] && null !== $page['published_revision_id']) { $document = json_decode($page['document'] ?? '{}', true, 512, JSON_THROW_ON_ERROR); $choosable[] = ['path' => $page['path'], 'title' => $document['title'] ?? $page['path']]; } } return $this->render('admin/settings.html.twig', [ 'settings' => $this->settings->load(), 'notFoundSelection' => $this->notFoundPage->selected(), 'redirects' => $this->redirects->all($request->query->getInt('seite', 1)), 'choosableHome' => $choosable, 'consentGroups' => Consent::GROUPS, 'missingLegal' => $this->settings->missingLegalPages(), 'consentGroupHelp' => Consent::GROUP_HELP, // Für das Symbol der Website: die Mediathek zur Auswahl, die neuesten zuerst. 'images' => $this->media->page(1, false, 96)['items'], // Fuer die Farbfelder: dieselbe Palette, die auch der Editor anbietet. 'palette' => $this->theme->load()['colors'], 'socialNetworks' => SocialProfiles::NETWORKS, 'weekdays' => SiteSettings::DAYS, 'socialPlaceholders' => SocialProfiles::PLACEHOLDERS, ]); } #[Route('/%kant.admin_path%/settings/company', name: 'admin_settings_save', methods: ['POST'])] public function save(Request $request): Response { $this->denyAccessUnlessGranted('ROLE_EDITOR'); if (!$this->isCsrfTokenValid('settings', $request->request->getString('_csrf_token'))) { return $this->back('Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.'); } try { $this->settings->save($request->request->all()); } catch (InvalidPage $e) { return $this->back($e->getMessage()); } return $this->back('Die Unternehmensdaten wurden gespeichert.', 'success'); } #[Route('/%kant.admin_path%/settings/not-found', name: 'admin_not_found_save', methods: ['POST'])] public function saveNotFound(Request $request): Response { $this->denyAccessUnlessGranted('ROLE_PUBLISHER'); if (!$this->isCsrfTokenValid('settings', $request->request->getString('_csrf_token'))) { return $this->back('Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.'); } try { $expectedId = $request->request->getString('expectedId'); if ('create' === $request->request->getString('action')) { $id = $this->notFoundPage->create($expectedId); $this->addFlash('success', 'Die 404-Vorlage wurde als Entwurf angelegt und zugewiesen. Nach dem Veröffentlichen ersetzt sie die Standard-404.'); return $this->redirectToRoute('admin_editor', ['id' => $id]); } $id = $request->request->getString('notFoundPageId'); $this->settings->assignNotFoundPage($id, $expectedId); $selection = $this->notFoundPage->selected(); $message = '' === $id ? 'Die Standard-404 im Website-Design ist wieder aktiv.' : ($selection['published'] ? 'Die 404-Seite wurde zugewiesen.' : 'Die Seite wurde zugewiesen. Bis zu ihrer Veröffentlichung erscheint die Standard-404.'); $this->addFlash('success', $message); } catch (InvalidPage|StaleWrite $error) { $this->addFlash('error', $error->getMessage()); } return $this->redirectToRoute('admin_settings', ['_fragment' => 'not-found']); } #[Route('/%kant.admin_path%/settings/redirects', name: 'admin_redirect_save', methods: ['POST'])] public function saveRedirect(Request $request): Response { $this->denyAccessUnlessGranted('ROLE_EDITOR'); if (!$this->isCsrfTokenValid('settings', $request->request->getString('_csrf_token'))) { return $this->back('Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.'); } $remove = $request->request->getString('remove'); if ('' !== $remove) { $this->redirects->delete($remove); return $this->back('Die Weiterleitung wurde entfernt.', 'success'); } try { $this->redirects->save( $request->request->getString('from'), $request->request->getString('to'), $request->request->getInt('status', 301), ); } catch (InvalidPage $e) { return $this->back($e->getMessage()); } return $this->back('Die Weiterleitung wurde gespeichert.', 'success'); } /** * Creates the privacy statement and the imprint, with a skeleton whose gaps are marked. * * The pages are mandatory, the text is not something a CMS can write: what gets created is the * structure with every required item named and marked as still to be filled in. */ #[Route('/%kant.admin_path%/settings/rechtliches', name: 'admin_legal_pages', methods: ['POST'])] public function legalPages(Request $request): Response { $this->denyAccessUnlessGranted('ROLE_EDITOR'); if (!$this->isCsrfTokenValid('settings', $request->request->getString('_csrf_token'))) { return $this->back('Deine Sitzung ist abgelaufen. Bitte melde dich erneut an.'); } $settings = $this->settings->load(); $created = []; try { foreach (DemoContent::LEGAL as $slug => $label) { $key = 'datenschutz' === $slug ? 'privacyPath' : 'imprintPath'; // An existing page is never overwritten - it may already carry the real text. $existing = null !== $this->pages->findPublished($slug) || $this->pageExists($slug); if (!$existing) { $id = $this->pages->createPage($slug, null, 'page', DemoContent::legalPage($slug)); $page = $this->pages->findForEditor($id); $this->pages->publish($id, $page['draft_revision_id'], $page['version']); $created[] = $label; } $settings[$key] = $slug; } $this->settings->save([...$settings, 'consentGroups' => $settings['consentGroups'], 'sameAs' => implode(' ', $settings['sameAs'])]); } catch (InvalidPage $e) { return $this->back($e->getMessage()); } return $this->back( [] === $created ? 'Die Seiten waren schon vorhanden und sind jetzt verknüpft. Der Inhalt bleibt unverändert.' : sprintf('%s angelegt und verknüpft. Beide Seiten sind veröffentlicht und müssen noch ausgefüllt werden – die Pflichtangaben sind darin markiert.', implode(' und ', $created)), 'success', ); } /** Also finds a page that exists but is not published yet. */ private function pageExists(string $path): bool { foreach ($this->pages->listForEditor() as $page) { if ($path === $page['path']) { return true; } } return false; } private function back(string $message, string $type = 'error'): Response { $this->addFlash($type, $message); return $this->redirectToRoute('admin_settings'); } }