Fassung 1.7.0: verlässliche Installation, übersichtliche Verwaltung und bedienbare Bewegung
This commit is contained in:
1 parent
b164c4edfe
commit
495b26896e
55 files changed
+1632
-423
No files matched your search
@@ -20,6 +20,7 @@ use App\Domain\StaleWrite;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Attribute\Route;
|
||||
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
||||
@@ -27,31 +28,53 @@ use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
|
||||
#[Route('/%kant.admin_path%')]
|
||||
final class EditorController extends AbstractController
|
||||
{
|
||||
public function __construct(private PageRepository $pages, private DocumentValidator $validator, private MenuRepository $menus, private PostRepository $posts, private Theme $theme, private StyleCompiler $styles, private RedirectRepository $redirects, private PartialRepository $partials, private CustomCode $code, private CsrfTokenManagerInterface $csrf)
|
||||
public function __construct(private PageRepository $pages, private DocumentValidator $validator, private MenuRepository $menus, private PostRepository $posts, private Theme $theme, private StyleCompiler $styles, private RedirectRepository $redirects, private PartialRepository $partials, private CustomCode $code, private CsrfTokenManagerInterface $csrf, private RequestStack $requests)
|
||||
{
|
||||
}
|
||||
|
||||
#[Route('', name: 'admin_pages', methods: ['GET'])]
|
||||
public function index(): Response
|
||||
#[Route('/posts', name: 'admin_posts', methods: ['GET'])]
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$pages = $this->pages->listForEditor();
|
||||
$type = 'admin_posts' === $request->attributes->get('_route') ? 'post' : 'page';
|
||||
$query = mb_substr(trim($request->query->getString('q')), 0, 160);
|
||||
$status = $request->query->getString('status', 'all');
|
||||
$status = in_array($status, ['all', 'draft', 'published', 'changed', 'trash'], true) ? $status : 'all';
|
||||
$result = $this->pages->editorPage($type, $request->query->getInt('seite', 1), $request->query->getInt('limit', 20), $query, $status);
|
||||
$pages = $result['items'];
|
||||
$parentChoices = [];
|
||||
foreach ($pages as &$page) {
|
||||
$page['title'] = json_decode($page['document'] ?? '{}', true, 512, JSON_THROW_ON_ERROR)['title'] ?? $page['slug'];
|
||||
$page['document'] = json_decode($page['document'] ?? '{}', true, 512, JSON_THROW_ON_ERROR);
|
||||
$page['title'] = $page['document']['title'] ?? $page['slug'];
|
||||
$page['depth'] = substr_count((string) $page['path'], '/');
|
||||
$page['terms'] = 'post' === $page['type'] ? $this->posts->namesFor($page['id']) : ['category' => '', 'tag' => ''];
|
||||
if ($page['parent_id'] && !isset($parentChoices[$page['parent_id']])) {
|
||||
$parentChoices[$page['parent_id']] = $this->pages->choices(id: $page['parent_id'])[0] ?? null;
|
||||
}
|
||||
}
|
||||
unset($page);
|
||||
|
||||
return $this->render('admin/pages.html.twig', [
|
||||
'pages' => $pages,
|
||||
'trash' => $this->pages->trash(),
|
||||
'parents' => array_values(array_filter($pages, static fn (array $p): bool => 'page' === $p['type'] && $p['depth'] + 2 <= PageRepository::MAX_DEPTH)),
|
||||
'postLayouts' => PostLayouts::all(),
|
||||
// Which header and footer areas a page can choose from.
|
||||
'pages' => 'trash' === $status ? [] : $pages,
|
||||
'trash' => 'trash' === $status ? array_map(static fn (array $p): array => [...$p, 'deletedAt' => $p['deleted_at']], $pages) : [],
|
||||
'parentChoices' => $parentChoices, 'postLayouts' => PostLayouts::all(),
|
||||
'contentType' => $type, 'result' => $result, 'query' => $query, 'status' => $status,
|
||||
'listRoute' => 'post' === $type ? 'admin_posts' : 'admin_pages',
|
||||
'areaChoices' => ['header' => $this->partials->choices('header'), 'footer' => $this->partials->choices('footer')],
|
||||
]);
|
||||
}
|
||||
|
||||
#[Route('/api/content-choices', name: 'admin_content_choices', methods: ['GET'])]
|
||||
public function contentChoices(Request $request): JsonResponse
|
||||
{
|
||||
$this->denyAccessUnlessGranted('ROLE_EDITOR');
|
||||
|
||||
return $this->json(['items' => $this->pages->choices(
|
||||
mb_substr($request->query->getString('q'), 0, 160),
|
||||
$request->query->getString('type'), $request->query->getBoolean('parents'),
|
||||
)]);
|
||||
}
|
||||
|
||||
#[Route('/pages', name: 'admin_create', methods: ['POST'])]
|
||||
public function create(Request $request): Response
|
||||
{
|
||||
@@ -317,8 +340,26 @@ final class EditorController extends AbstractController
|
||||
private function back(string $message, string $type = 'error'): Response
|
||||
{
|
||||
$this->addFlash($type, $message);
|
||||
$request = $this->requests->getCurrentRequest();
|
||||
$post = 'post' === $request?->request->getString('_list_type', $request?->request->getString('type', 'page'));
|
||||
|
||||
return $this->redirectToRoute('admin_pages');
|
||||
if (!$request?->request->has('_list_type')) {
|
||||
return $this->redirectToRoute($post ? 'admin_posts' : 'admin_pages');
|
||||
}
|
||||
|
||||
$params = [
|
||||
'q' => $request?->request->getString('_list_query', ''),
|
||||
'status' => $request?->request->getString('_list_status', 'all'),
|
||||
'seite' => $request?->request->getInt('_list_page', 1),
|
||||
'limit' => $request?->request->getInt('_list_limit', 20),
|
||||
];
|
||||
foreach (['q' => '', 'status' => 'all', 'seite' => 1, 'limit' => 20] as $key => $default) {
|
||||
if ($params[$key] === $default) {
|
||||
unset($params[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->redirectToRoute($post ? 'admin_posts' : 'admin_pages', $params);
|
||||
}
|
||||
|
||||
#[Route('/pages/{id}', name: 'admin_editor', methods: ['GET'])]
|
||||
|
||||
Reference in new issue
Block a user