2 次代碼提交 2a499b6929 ... 16f9778746

作者 SHA1 備註 提交日期
  Sangfroid 16f9778746 On repasse en Feed Laminas pour les flux rss 1 月之前
  Sangfroid 5938753988 On change le content-type pour les flux 1 月之前

+ 1 - 1
composer.json

@@ -7,13 +7,13 @@
         "php": ">=8.2",
         "ext-ctype": "*",
         "ext-iconv": "*",
-        "debril/rss-atom-bundle": "^5.2",
         "doctrine/dbal": "^3",
         "doctrine/doctrine-bundle": "^2.13",
         "doctrine/doctrine-migrations-bundle": "^3.3",
         "doctrine/orm": "^3.3",
         "embed/embed": "^4.4",
         "laminas/laminas-diactoros": "^3.5",
+        "laminas/laminas-feed": "^2.23",
         "league/commonmark": "^2.5",
         "phpdocumentor/reflection-docblock": "^5.4",
         "phpstan/phpdoc-parser": "^1.33",

文件差異過大導致無法顯示
+ 199 - 489
composer.lock


+ 0 - 1
config/bundles.php

@@ -13,5 +13,4 @@ return [
     Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
     Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
     Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
-    Debril\RssAtomBundle\DebrilRssAtomBundle::class => ['all' => true],
 ];

+ 0 - 5
config/packages/rss_atom.yaml

@@ -1,5 +0,0 @@
-debril_rss_atom:
-    # switch to true if you need to set cache-control: private
-    private: false
-    # switch to true if you need to always send status 200
-    force_refresh: false

+ 0 - 2
config/routes/rss_atom.yaml

@@ -1,2 +0,0 @@
-rss_atom_bundle:
-    resource: "@DebrilRssAtomBundle/Resources/config/routing.yml"

+ 1 - 1
config/services.yaml

@@ -6,7 +6,7 @@
 parameters:
     images_directory: '%kernel.project_dir%/public/uploads/images'
     title: '%env(TITLE)%'
-    debril.rss_atom.provider.class: App\Service\BlogFeedProvider
+    
 services:
     # default configuration for services in *this* file
     _defaults:

+ 34 - 0
src/Controller/FeedController.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace App\Controller;
+
+use App\Repository\ArticleRepository;
+use App\Service\FeedService;
+use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\Routing\Attribute\Route;
+
+class FeedController extends AbstractController
+{
+    public function __construct(
+        protected ArticleRepository $articleRepository,
+        protected FeedService $feedService,
+    )
+    {
+        
+    }
+
+    #[Route('/feed/{type}', name: 'app_feed', requirements: ['type' => 'rss|atom'] )]
+    public function feed(
+        string $type = FeedService::RSS,
+    ): Response
+    {
+        $articles = $this->articleRepository->findBy(criteria: ['state' => 'published'], orderBy: ['publicationDate' => 'DESC']);
+
+        $feedContent = $this->feedService->createFeed($articles, $type, $this->articleRepository->findLastPublicationDate());
+
+        $contentType = $type === FeedService::RSS ? 'application/rss+xml' : 'application/atom+xml';
+
+        return new Response($feedContent, Response::HTTP_ACCEPTED, ['Content-Type' => $contentType]);
+    }
+}

+ 11 - 0
src/Repository/ArticleRepository.php

@@ -40,4 +40,15 @@ class ArticleRepository extends ServiceEntityRepository
     //            ->getOneOrNullResult()
     //        ;
     //    }
+
+    public function findLastPublicationDate(): ?\DateTimeImmutable
+    {
+        return $this->createQueryBuilder('a')
+            ->select('a.publicationDate')
+            ->orderBy('a.publicationDate', 'DESC')
+            ->setMaxResults(1)
+            ->getQuery()
+            ->getOneOrNullResult()['publicationDate'] ?? null
+        ;
+    }
 }

+ 0 - 66
src/Service/BlogFeedProvider.php

@@ -1,66 +0,0 @@
-<?php
-
-namespace App\Service;
-
-use App\Entity\Article;
-use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
-use App\Repository\ArticleRepository;
-use Debril\RssAtomBundle\Provider\FeedProviderInterface;
-use FeedIo\Feed;
-use FeedIo\Feed\Item;
-use FeedIo\Feed\Item\Author;
-use Symfony\Component\HttpFoundation\Request;
-use FeedIo\FeedInterface;
-use Symfony\Component\Routing\RouterInterface;
-
-class BlogFeedProvider implements FeedProviderInterface
-{
-
-    public function __construct(
-        protected ArticleRepository $articleRepository,
-        protected UrlGeneratorInterface $router,
-        protected MarkdownParser $markdownParser
-    )
-    {
-
-    }
-
-    public function getFeed(Request $request): FeedInterface
-    {
-        $feed = new Feed();
-        $feed->setTitle('Opinion sur le réel');
-        $feed->setLink($this->router->generate('app_index', [], RouterInterface::ABSOLUTE_URL));
-        $feed->setLanguage('fr');
-        foreach($this->getItems() as $item) {
-            $feed->add($item);
-        }
-        return $feed;
-    }
-
-    public function getItems(): \Iterator
-    {
-        $articles = $this->articleRepository->findBy(criteria: ['state' => 'published'], orderBy: ['publicationDate' => 'DESC']);
-        foreach($articles as $article) {
-            /** @var Article $article */
-            $item = new Item();
-            $item
-                ->setContent($this->markdownParser->convertToHtml($article->getContent()))
-                ->setTitle($article->getTitle())
-                ->setAuthor((new Author())->setName($article->getAuthor()))
-                ->setLastModified(\DateTime::createFromImmutable($article->getPublicationDate()))
-                ->setLink($this->router->generate('app_view', ['slug' => $article->getSlug()], RouterInterface::ABSOLUTE_URL))
-            ;
-            yield $item;
-        }
-    }
-
-    public function getFeedMetadata($feedId)
-    {
-        return [
-            'title' => 'Mon Blog',
-            'description' => 'Les derniers articles de mon blog',
-            'link' => 'https://example.com/blog',
-            'ttl' => 60,
-        ];
-    }
-}

+ 64 - 0
src/Service/FeedService.php

@@ -0,0 +1,64 @@
+<?php
+
+namespace App\Service;
+
+use App\Entity\Article;
+use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
+use App\Repository\ArticleRepository;
+use Laminas\Feed\Writer\Entry;
+use Laminas\Feed\Writer\Feed;
+use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
+use Symfony\Component\Routing\RouterInterface;
+
+class FeedService
+{
+    public const ATOM = 'atom';
+    public const RSS = 'rss';
+
+    public function __construct(
+        protected ArticleRepository $articleRepository,
+        protected UrlGeneratorInterface $router,
+        protected MarkdownParser $markdownParser,
+        protected ParameterBagInterface $parameterBagInterface
+    )
+    {
+
+    }
+
+    public function createFeed(array $articles, string $type = self::RSS, \DateTimeImmutable $updatedAt): string
+    {
+        $feed = new Feed();
+        $feed->setTitle($this->parameterBagInterface->get('title'));
+        $feed->setLink($this->router->generate('app_index', [], RouterInterface::ABSOLUTE_URL));
+        $feed->setFeedLink($this->router->generate('app_feed', ['type' => $type], RouterInterface::ABSOLUTE_URL), $type);
+        $feed->setDescription('Derniers articles du blog');
+        $feed->setLanguage('fr');
+        $feed->setDateModified($updatedAt);
+
+        foreach($this->getItems($articles) as $item) {
+            $feed->addEntry($item);
+        }
+        return $feed->export($type);
+    }
+
+    public function getItems($articles): \Iterator
+    {
+        foreach($articles as $article) {
+            /** @var Article $article */
+            $item = new Entry();
+            $item
+                ->setTitle($article->getTitle())
+                ->setLink($this->router->generate('app_view', ['slug' => $article->getSlug()], RouterInterface::ABSOLUTE_URL))
+                ->setDateCreated($article->getPublicationDate())
+                ->setDateModified($item->getDateCreated())
+                ->addAuthor(['name' => (string) $article->getAuthor()])
+            ;
+            # Fix pour supprimer le allowfullscreen récupéré par l'extension embed pour youtube
+            $content = $this->markdownParser->convertToHtml($article->getContent());
+            $content = str_replace('allowfullscreen', 'allowfullscreen="true"', $content);
+            $item->setContent($content);
+            ;
+            yield $item;
+        }
+    }
+}

+ 0 - 13
symfony.lock

@@ -1,17 +1,4 @@
 {
-    "debril/rss-atom-bundle": {
-        "version": "5.2",
-        "recipe": {
-            "repo": "github.com/symfony/recipes-contrib",
-            "branch": "main",
-            "version": "4.0",
-            "ref": "2c23ed747eda9f4c13f5e7eb55fffa1091fdd505"
-        },
-        "files": [
-            "config/packages/rss_atom.yaml",
-            "config/routes/rss_atom.yaml"
-        ]
-    },
     "doctrine/doctrine-bundle": {
         "version": "2.13",
         "recipe": {

+ 2 - 2
templates/_aside.html.twig

@@ -14,8 +14,8 @@
     <section class="feeds">
         <h2>Flux</h2>
         <ul>
-            <li><a href="{{ path('feed_atom') }}">Atom</a></li>
-            <li><a href="{{ path('feed_rss') }}">RSS</a></li>
+            <li><a href="{{ path('app_feed', {'type': 'atom' }) }}">Atom</a></li>
+            <li><a href="{{ path('app_feed', {'type': 'rss' }) }}">RSS</a></li>
         </ul>
     </section>
     

部分文件因文件數量過多而無法顯示