src/Controller/Frontend/ArtikelController.php line 24

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Frontend;
  3. use App\Application\Artikel\ArtikelFrontendData;
  4. use App\Application\Artikel\ArtikelService;
  5. use App\Application\Artikel\ArtikelServiceQuery;
  6. use App\Entity\Artikel\Artikel;
  7. use App\Entity\Artikel\ArtikelTyp;
  8. use App\Form\Abo\AbonnentLoginType;
  9. use Psr\Cache\CacheItemPoolInterface;
  10. use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;
  11. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  12. use Symfony\Component\HttpFoundation\RedirectResponse;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\Routing\Annotation\Route;
  16. #[Route(path: '/artikel')]
  17. #[Cache(expires: '+10 minutes')]
  18. class ArtikelController extends AbstractController
  19. {
  20. #[Route(path: '/', name: 'fe.artikel_liste')]
  21. public function liste(Request $request, ArtikelService $artikelService): Response
  22. {
  23. // Validierung aller möglichen URL-Parameter sonst Fehler (Page- und ApiClientCache Cache Schutz)
  24. if (($urlParams = array_keys($request->query->all())) && ($diff_ = array_diff($urlParams, ['pg']))) {
  25. throw $this->createNotFoundException(sprintf('Nicht konfigurierte URL Parameter abgesetzt: %s', implode(',', $diff_)));
  26. }
  27. // Ende
  28. // --- Artikel ---
  29. $pageSize = 12;
  30. $pageNumber = $request->query->getInt('pg', 1);
  31. if ($pageNumber === 1) {
  32. ++$pageSize;
  33. }
  34. $query = new ArtikelServiceQuery($pageSize, $pageNumber, false);
  35. $query->addFilterOneOfTypOnly([ArtikelTyp::ID_AT_1, ArtikelTyp::ID_AT_3, ArtikelTyp::ID_AT_4]);
  36. $query->addFilterOneOfStatusOnly(['publiziert']);
  37. $query->addSort('publish_at', 'desc');
  38. $artikels = $artikelService->findArtikels(new ArtikelFrontendData(), $query);
  39. // --- End Artikel ---
  40. $paging = [
  41. 'page_size' => $query->getPageSize(),
  42. 'page_curr' => $query->getPageNr(),
  43. 'page_prev' => $query->getPageNr() == 1 ? null : $query->getPageNr() - 1,
  44. 'page_next' => $query->getPageNextExist() ? $query->getPageNr() + 1 : null,
  45. ];
  46. return $this->render('frontend/artikel/liste.html.twig', [
  47. 'h1_titel' => '',
  48. 'artikels' => $artikels,
  49. 'paging' => $paging,
  50. ]);
  51. }
  52. #[Route(path: '/rss.xml', name: 'fe.artikel_rss')]
  53. public function rss(ArtikelService $artikelService, CacheItemPoolInterface $cacheApp): Response
  54. {
  55. $artikels = [];
  56. $pageSize = 20;
  57. $cachedArtikels = $cacheApp->getItem('rss_artikels');
  58. if (!$cachedArtikels->isHit()) {
  59. $query = new ArtikelServiceQuery($pageSize, 1, false);
  60. $query->addFilterOneOfStatusOnly(['publiziert']);
  61. $query->addSort('publish_at', 'desc');
  62. $data = $artikelService->findArtikels(new ArtikelFrontendData(), $query);
  63. foreach ($data as $artikel) {
  64. $image = [];
  65. if ($artikel['images']) {
  66. $imageFilePath = $artikel['images']->current()->getFilepath();
  67. if (file_exists($imageFilePath)) {
  68. $image = [
  69. 'asset_path' => $artikel['images']->current()->getAssetFilepath(),
  70. 'length' => filesize($imageFilePath),
  71. 'type' => image_type_to_mime_type(\exif_imagetype($imageFilePath)),
  72. ];
  73. }
  74. }
  75. $artikels[] = [
  76. 'titel' => $artikel['titel'],
  77. 'lead' => $artikel['lead'],
  78. 'publish_at' => $artikel['publish_at']->format(DATE_RSS),
  79. 'slug' => $artikel['slug'],
  80. 'guid' => $artikel['id'],
  81. 'image' => $image,
  82. ];
  83. }
  84. // save to cache
  85. $cachedArtikels->set($artikels);
  86. $expireDate = new \DateTime('+30 minutes');
  87. $cachedArtikels->expiresAt($expireDate);
  88. $cacheApp->save($cachedArtikels);
  89. // end
  90. } else {
  91. $artikels = $cachedArtikels->get();
  92. }
  93. $response = $this->render('frontend/artikel/rss.xml.twig', [
  94. 'artikels' => $artikels,
  95. ]);
  96. $response->headers->set('Content-Type', 'application/rss+xml');
  97. return $response;
  98. }
  99. #[Route(path: '/{slug}', name: 'fe.artikel_detail')]
  100. public function artikel(Request $request, $slug, ArtikelService $artikelService): Response
  101. {
  102. $abonnentLoginForm = null;
  103. $redaktorPreview = false;
  104. if ($this->isGranted('MODULE_ARTIKEL')) {
  105. $redaktorPreview = true; // Artikel holen, auch wenn nicht publiziert
  106. }
  107. $artikel = $artikelService->getFrontendArtikelBySlug($slug, new ArtikelFrontendData(), $redaktorPreview);
  108. if (!$artikel) {
  109. throw $this->createNotFoundException();
  110. }
  111. // View Template bestimmen
  112. $twigTemplate = 'frontend/artikel/artikel.html.twig';
  113. if ($artikel['typ']->isUWPlus()) {
  114. $twigTemplate = 'frontend/artikel/artikel-uw-plus.html.twig';
  115. // In diesem Template das Loginform dazu generieren!
  116. $abonnentLoginForm = $this->createForm(AbonnentLoginType::class, ['http_referer' => $request->getRequestUri()], ['csrf_protection' => false]);
  117. } elseif ($artikel['typ']->isPublireportage()) {
  118. $twigTemplate = 'frontend/artikel/artikel-publireportage.html.twig';
  119. }
  120. // End
  121. $response = $this->render($twigTemplate, [
  122. 'abonnentLoginForm' => $abonnentLoginForm instanceof \Symfony\Component\Form\FormInterface ? $abonnentLoginForm->createView() : null,
  123. 'artikel' => $artikel,
  124. ]);
  125. if ($artikel['typ']->isUWPlus()) {
  126. // Explizit Cache deaktivieren, damit Paywall Logik einwandfrei funktioniert (einfachste Lösung)
  127. $response->setMaxAge(0);
  128. $response->setSharedMaxAge(0);
  129. }
  130. return $response;
  131. }
  132. #[Route(path: '/legacy-redirector/{slug}')]
  133. public function legacyRedirector(ArtikelService $artikelService, $slug): RedirectResponse
  134. {
  135. // Versuche den Post zu finden
  136. try {
  137. $slug = Artikel::extractUrlSlug($slug);
  138. $artikel = $artikelService->getFrontendArtikelBySlug($slug, new ArtikelFrontendData());
  139. if ($artikel) {
  140. return $this->redirectToRoute('fe.artikel_detail', [
  141. 'slug' => $artikel['slug'],
  142. ], 301);
  143. }
  144. } catch (\Exception $e) {
  145. throw $e;
  146. }
  147. throw $this->createNotFoundException();
  148. }
  149. }