From 29df8ed5904f13160ef02ff1df72e0844e8ec17d Mon Sep 17 00:00:00 2001 From: Adrien Gallou Date: Thu, 10 Mar 2022 08:06:55 +0100 Subject: [PATCH] this change adds an option to sort the feed entires by updated_at There is now an option to sort the feed entires by updated_at, on the controler : a sort querystring argument that accepts either "created" or "updated". --- .../CoreBundle/Controller/FeedController.php | 36 ++++++++++++- .../CoreBundle/Repository/EntryRepository.php | 4 +- .../themes/common/Entry/entries.xml.twig | 4 +- .../Controller/FeedControllerTest.php | 51 ++++++++++++++++++- 4 files changed, 87 insertions(+), 8 deletions(-) diff --git a/src/Wallabag/CoreBundle/Controller/FeedController.php b/src/Wallabag/CoreBundle/Controller/FeedController.php index 3a9634f9a..5e33839eb 100644 --- a/src/Wallabag/CoreBundle/Controller/FeedController.php +++ b/src/Wallabag/CoreBundle/Controller/FeedController.php @@ -8,7 +8,9 @@ use Pagerfanta\Exception\OutOfRangeCurrentPageException; use Pagerfanta\Pagerfanta; use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter; use Symfony\Bundle\FrameworkBundle\Controller\Controller; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Wallabag\CoreBundle\Entity\Tag; @@ -88,8 +90,19 @@ class FeedController extends Controller * * @return \Symfony\Component\HttpFoundation\Response */ - public function showTagsFeedAction(User $user, Tag $tag, $page) + public function showTagsFeedAction(Request $request, User $user, Tag $tag, $page) { + $sort = $request->query->get('sort', 'created'); + + $sorts = [ + 'created' => 'createdAt', + 'updated' => 'updatedAt', + ]; + + if (!isset($sorts[$sort])) { + throw new BadRequestHttpException(sprintf('Sort "%s" is not available.', $sort)); + } + $url = $this->generateUrl( 'tag_feed', [ @@ -102,7 +115,8 @@ class FeedController extends Controller $entriesByTag = $this->get('wallabag_core.entry_repository')->findAllByTagId( $user->getId(), - $tag->getId() + $tag->getId(), + $sorts[$sort] ); $pagerAdapter = new ArrayAdapter($entriesByTag); @@ -137,11 +151,28 @@ class FeedController extends Controller 'domainName' => $this->getParameter('domain_name'), 'version' => $this->getParameter('wallabag_core.version'), 'tag' => $tag->getSlug(), + 'updated' => $this->prepareFeedUpdatedDate($entries, $sort), ], new Response('', 200, ['Content-Type' => 'application/atom+xml']) ); } + private function prepareFeedUpdatedDate(Pagerfanta $entries, $sort = 'created') + { + $currentPageResults = $entries->getCurrentPageResults(); + + if (isset($currentPageResults[0])) { + $firstEntry = $currentPageResults[0]; + if ('created' === $sort) { + return $firstEntry->getCreatedAt(); + } + + return $firstEntry->getUpdatedAt(); + } + + return null; + } + /** * Global method to retrieve entries depending on the given type * It returns the response to be send. @@ -202,6 +233,7 @@ class FeedController extends Controller 'user' => $user->getUsername(), 'domainName' => $this->getParameter('domain_name'), 'version' => $this->getParameter('wallabag_core.version'), + 'updated' => $this->prepareFeedUpdatedDate($entries), ], new Response('', 200, ['Content-Type' => 'application/atom+xml']) ); diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php index 36eedf205..14a38d329 100644 --- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php +++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php @@ -343,9 +343,9 @@ class EntryRepository extends EntityRepository * * @return array */ - public function findAllByTagId($userId, $tagId) + public function findAllByTagId($userId, $tagId, $sort = 'createdAt') { - return $this->getSortedQueryBuilderByUser($userId) + return $this->getSortedQueryBuilderByUser($userId, $sort) ->innerJoin('e.tags', 't') ->andWhere('t.id = :tagId')->setParameter('tagId', $tagId) ->getQuery() diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig index ee6ff6397..4e87942fd 100644 --- a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig +++ b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig @@ -11,8 +11,8 @@ wallabag — {{type}} {{ tag }} feed Atom feed for entries tagged with {{ tag }} {% endif %} - {% if entries | length > 0 %} - {{ (entries | first).createdAt | date('c') }} {# Indicates the last time the feed was modified in a significant way. #} + {% if updated %} + {{ updated | date('c') }} {# Indicates the last time the feed was modified in a significant way. #} {% endif %} {% if entries.hasPreviousPage %} diff --git a/tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php b/tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php index 0bd2a6206..e35a636e3 100644 --- a/tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php +++ b/tests/Wallabag/CoreBundle/Controller/FeedControllerTest.php @@ -213,15 +213,62 @@ class FeedControllerTest extends WallabagCoreTestCase $config->setFeedToken('SUPERTOKEN'); $config->setFeedLimit(null); $em->persist($config); + + $entry1 = $em + ->getRepository('WallabagCoreBundle:Entry') + ->find(1) + ; + + $entry4 = $em + ->getRepository('WallabagCoreBundle:Entry') + ->find(4) + ; + + $now = new \DateTimeImmutable('now'); + + $day1 = $now->modify('-8 days'); + $day2 = $now->modify('-6 days'); + $day3 = $now->modify('-4 days'); + $day4 = $now->modify('-2 days'); + + $entry1->setCreatedAt($day1); + $entry4->setCreatedAt($day2); + + $property = (new \ReflectionObject($entry1))->getProperty('updatedAt'); + $property->setAccessible(true); + $property->setValue($entry1, $day4); + + $property = (new \ReflectionObject($entry4))->getProperty('updatedAt'); + $property->setAccessible(true); + $property->setValue($entry4, $day3); + $em->flush(); $client = $this->getClient(); - $client->request('GET', '/feed/admin/SUPERTOKEN/tags/foo'); + // tag foo - without sort + $crawler = $client->request('GET', '/feed/admin/SUPERTOKEN/tags/foo'); $this->assertSame(200, $client->getResponse()->getStatusCode()); + $this->assertSame('test title entry4', $crawler->filterXPath('//feed/entry[1]/title')->text()); + $this->assertSame('test title entry1', $crawler->filterXPath('//feed/entry[2]/title')->text()); - $this->validateDom($client->getResponse()->getContent(), 'tag', 2, 'foo'); + // tag foo - with sort created + $crawler = $client->request('GET', '/feed/admin/SUPERTOKEN/tags/foo?sort=created'); + $this->assertSame(200, $client->getResponse()->getStatusCode()); + $this->assertSame('test title entry4', $crawler->filterXPath('//feed/entry[1]/title')->text()); + $this->assertSame('test title entry1', $crawler->filterXPath('//feed/entry[2]/title')->text()); + // tag foo - with sort updated + $crawler = $client->request('GET', '/feed/admin/SUPERTOKEN/tags/foo?sort=updated'); + $this->assertSame(200, $client->getResponse()->getStatusCode()); + $this->assertSame('test title entry1', $crawler->filterXPath('//feed/entry[1]/title')->text()); + $this->assertSame('test title entry4', $crawler->filterXPath('//feed/entry[2]/title')->text()); + + // tag foo - with invalid sort + $client->request('GET', '/feed/admin/SUPERTOKEN/tags/foo?sort=invalid'); + $this->assertSame(400, $client->getResponse()->getStatusCode()); + + // tag foo/3000 $client->request('GET', '/feed/admin/SUPERTOKEN/tags/foo/3000'); $this->assertSame(302, $client->getResponse()->getStatusCode()); }