]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #3207 from wallabag/tag-rss
authorJérémy Benoist <j0k3r@users.noreply.github.com>
Wed, 21 Jun 2017 12:51:46 +0000 (14:51 +0200)
committerGitHub <noreply@github.com>
Wed, 21 Jun 2017 12:51:46 +0000 (14:51 +0200)
Add RSS for tags

31 files changed:
app/config/security.yml
src/Wallabag/CoreBundle/Command/CleanDuplicatesCommand.php
src/Wallabag/CoreBundle/Command/ExportCommand.php
src/Wallabag/CoreBundle/Command/ShowUserCommand.php
src/Wallabag/CoreBundle/Command/TagAllCommand.php
src/Wallabag/CoreBundle/Controller/ConfigController.php
src/Wallabag/CoreBundle/Controller/ExportController.php
src/Wallabag/CoreBundle/Controller/RssController.php
src/Wallabag/CoreBundle/Controller/TagController.php
src/Wallabag/CoreBundle/Helper/PreparePagerForEntries.php
src/Wallabag/CoreBundle/Resources/translations/messages.da.yml
src/Wallabag/CoreBundle/Resources/translations/messages.de.yml
src/Wallabag/CoreBundle/Resources/translations/messages.en.yml
src/Wallabag/CoreBundle/Resources/translations/messages.es.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml
src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml
src/Wallabag/CoreBundle/Resources/translations/messages.it.yml
src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml
src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml
src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Config/index.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Entry/entries.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_rss_link.html.twig [new file with mode: 0644]
src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/entries.xml.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Config/index.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Entry/entries.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/tags.html.twig
tests/Wallabag/CoreBundle/Controller/RssControllerTest.php

index ffb1d356fd29d8b081a78a088c47afc04176ba49..e14a0bd19b1924ea34d6f85e787b2c6c7c290948 100644 (file)
@@ -61,6 +61,7 @@ security:
         - { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: /(unread|starred|archive).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
+        - { path: /tags/(.*).xml$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/share, roles: IS_AUTHENTICATED_ANONYMOUSLY }
         - { path: ^/settings, roles: ROLE_SUPER_ADMIN }
         - { path: ^/annotations, roles: ROLE_USER }
index 65f35d8e6f9099418282dfda5c4e3a4f118260b4..74da1e5f5292fe388eab92c8f701b990de018019 100644 (file)
@@ -46,7 +46,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
                 return 1;
             }
         } else {
-            $users = $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findAll();
+            $users = $this->getContainer()->get('wallabag_user.user_repository')->findAll();
 
             $output->writeln(sprintf('Cleaning through %d user accounts', count($users)));
 
@@ -66,7 +66,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
     private function cleanDuplicates(User $user)
     {
         $em = $this->getContainer()->get('doctrine.orm.entity_manager');
-        $repo = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry');
+        $repo = $this->getContainer()->get('wallabag_core.entry_repository');
 
         $entries = $repo->getAllEntriesIdAndUrl($user->getId());
 
@@ -109,7 +109,7 @@ class CleanDuplicatesCommand extends ContainerAwareCommand
      */
     private function getUser($username)
     {
-        return $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($username);
+        return $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($username);
     }
 
     private function getDoctrine()
index e3d3b399506ff4e3986a84b044f032c882732783..ebb2b4cff7124eb81ddc3c70ebdc869aa357fbb2 100644 (file)
@@ -32,15 +32,14 @@ class ExportCommand extends ContainerAwareCommand
     protected function execute(InputInterface $input, OutputInterface $output)
     {
         try {
-            $user = $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($input->getArgument('username'));
+            $user = $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($input->getArgument('username'));
         } catch (NoResultException $e) {
             $output->writeln(sprintf('<error>User "%s" not found.</error>', $input->getArgument('username')));
 
             return 1;
         }
 
-        $entries = $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
+        $entries = $this->getContainer()->get('wallabag_core.entry_repository')
             ->getBuilderForAllByUser($user->getId())
             ->getQuery()
             ->getResult();
index 0eeaabc443867b8a085a9a0df41930cfb5665f12..eef04988fb80206d67bdf8c8a242299e188001b0 100644 (file)
@@ -67,7 +67,7 @@ class ShowUserCommand extends ContainerAwareCommand
      */
     private function getUser($username)
     {
-        return $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($username);
+        return $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($username);
     }
 
     private function getDoctrine()
index 3f9bb04d9f29b72a53ee0391711013094c6c8003..9843674e23980173e46f41b30f6d158c8c75fc00 100644 (file)
@@ -59,7 +59,7 @@ class TagAllCommand extends ContainerAwareCommand
      */
     private function getUser($username)
     {
-        return $this->getDoctrine()->getRepository('WallabagUserBundle:User')->findOneByUserName($username);
+        return $this->getContainer()->get('wallabag_user.user_repository')->findOneByUserName($username);
     }
 
     private function getDoctrine()
index 89d27425c65b822bcfbf201450189f7d95b25a25..d4170d398e58dd77c1de3f7c287f0ae9b8f8af27 100644 (file)
@@ -152,8 +152,7 @@ class ConfigController extends Controller
             ],
             'twofactor_auth' => $this->getParameter('twofactor_auth'),
             'wallabag_url' => $this->getParameter('domain_name'),
-            'enabled_users' => $this->getDoctrine()
-                ->getRepository('WallabagUserBundle:User')
+            'enabled_users' => $this->get('wallabag_user.user_repository')
                 ->getSumEnabledUsers(),
         ]);
     }
@@ -257,9 +256,7 @@ class ConfigController extends Controller
                 // manually remove tags to avoid orphan tag
                 $this->removeAllTagsByUserId($this->getUser()->getId());
 
-                $this->getDoctrine()
-                    ->getRepository('WallabagCoreBundle:Entry')
-                    ->removeAllByUserId($this->getUser()->getId());
+                $this->get('wallabag_core.entry_repository')->removeAllByUserId($this->getUser()->getId());
                 break;
             case 'archived':
                 if ($this->get('doctrine')->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) {
@@ -269,9 +266,7 @@ class ConfigController extends Controller
                 // manually remove tags to avoid orphan tag
                 $this->removeTagsForArchivedByUserId($this->getUser()->getId());
 
-                $this->getDoctrine()
-                    ->getRepository('WallabagCoreBundle:Entry')
-                    ->removeArchivedByUserId($this->getUser()->getId());
+                $this->get('wallabag_core.entry_repository')->removeArchivedByUserId($this->getUser()->getId());
                 break;
         }
 
@@ -295,8 +290,7 @@ class ConfigController extends Controller
             return;
         }
 
-        $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
+        $this->get('wallabag_core.entry_repository')
             ->removeTags($userId, $tags);
 
         // cleanup orphan tags
@@ -318,7 +312,7 @@ class ConfigController extends Controller
      */
     private function removeAllTagsByUserId($userId)
     {
-        $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($userId);
+        $tags = $this->get('wallabag_core.tag_repository')->findAllTags($userId);
         $this->removeAllTagsByStatusAndUserId($tags, $userId);
     }
 
@@ -329,7 +323,7 @@ class ConfigController extends Controller
      */
     private function removeTagsForArchivedByUserId($userId)
     {
-        $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findForArchivedArticlesByUser($userId);
+        $tags = $this->get('wallabag_core.tag_repository')->findForArchivedArticlesByUser($userId);
         $this->removeAllTagsByStatusAndUserId($tags, $userId);
     }
 
@@ -393,8 +387,7 @@ class ConfigController extends Controller
      */
     public function deleteAccountAction(Request $request)
     {
-        $enabledUsers = $this->getDoctrine()
-            ->getRepository('WallabagUserBundle:User')
+        $enabledUsers = $this->get('wallabag_user.user_repository')
             ->getSumEnabledUsers();
 
         if ($enabledUsers <= 1) {
index abc3336a412b06b4ddcf942184776a24021f90fe..fda04cfbc82e7f9bf343868bd9a377a6bc0eea40 100644 (file)
@@ -7,7 +7,6 @@ use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 use Wallabag\CoreBundle\Entity\Entry;
-use Wallabag\CoreBundle\Entity\Tag;
 
 /**
  * The try/catch can be removed once all formats will be implemented.
@@ -57,16 +56,17 @@ class ExportController extends Controller
     {
         $method = ucfirst($category);
         $methodBuilder = 'getBuilderFor'.$method.'ByUser';
+        $repository = $this->get('wallabag_core.entry_repository');
 
         if ($category == 'tag_entries') {
-            $tag = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findOneBySlug($request->query->get('tag'));
+            $tag = $this->get('wallabag_core.tag_repository')->findOneBySlug($request->query->get('tag'));
 
-            $entries = $this->getDoctrine()
-                ->getRepository('WallabagCoreBundle:Entry')
-                ->findAllByTagId($this->getUser()->getId(), $tag->getId());
+            $entries = $repository->findAllByTagId(
+                $this->getUser()->getId(),
+                $tag->getId()
+            );
         } else {
-            $entries = $this->getDoctrine()
-                ->getRepository('WallabagCoreBundle:Entry')
+            $entries = $repository
                 ->$methodBuilder($this->getUser()->getId())
                 ->getQuery()
                 ->getResult();
index 92f187075e02e90a3421394d82b748813909fea0..e87dd9a1f1063bc8c6aed1a0c59e1d4fbd6fc1fa 100644 (file)
@@ -3,13 +3,16 @@
 namespace Wallabag\CoreBundle\Controller;
 
 use Pagerfanta\Adapter\DoctrineORMAdapter;
+use Pagerfanta\Adapter\ArrayAdapter;
 use Pagerfanta\Exception\OutOfRangeCurrentPageException;
 use Pagerfanta\Pagerfanta;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
 use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
 use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
 use Symfony\Bundle\FrameworkBundle\Controller\Controller;
 use Wallabag\CoreBundle\Entity\Entry;
+use Wallabag\CoreBundle\Entity\Tag;
 use Wallabag\UserBundle\Entity\User;
 use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
 
@@ -23,7 +26,7 @@ class RssController extends Controller
      *
      * @return \Symfony\Component\HttpFoundation\Response
      */
-    public function showUnreadAction(Request $request, User $user)
+    public function showUnreadRSSAction(Request $request, User $user)
     {
         return $this->showEntries('unread', $user, $request->query->get('page', 1));
     }
@@ -31,12 +34,12 @@ class RssController extends Controller
     /**
      * Shows read entries for current user.
      *
-     * @Route("/{username}/{token}/archive.xml", name="archive_rss")
+     * @Route("/{username}/{token}/archive.xml", name="archive_rss", defaults={"_format"="xml"})
      * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_rsstoken_converter")
      *
      * @return \Symfony\Component\HttpFoundation\Response
      */
-    public function showArchiveAction(Request $request, User $user)
+    public function showArchiveRSSAction(Request $request, User $user)
     {
         return $this->showEntries('archive', $user, $request->query->get('page', 1));
     }
@@ -44,16 +47,88 @@ class RssController extends Controller
     /**
      * Shows starred entries for current user.
      *
-     * @Route("/{username}/{token}/starred.xml", name="starred_rss")
+     * @Route("/{username}/{token}/starred.xml", name="starred_rss", defaults={"_format"="xml"})
      * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_rsstoken_converter")
      *
      * @return \Symfony\Component\HttpFoundation\Response
      */
-    public function showStarredAction(Request $request, User $user)
+    public function showStarredRSSAction(Request $request, User $user)
     {
         return $this->showEntries('starred', $user, $request->query->get('page', 1));
     }
 
+    /**
+     * Shows all entries for current user.
+     *
+     * @Route("/{username}/{token}/all.xml", name="all_rss", defaults={"_format"="xml"})
+     * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_rsstoken_converter")
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function showAllRSSAction(Request $request, User $user)
+    {
+        return $this->showEntries('all', $user, $request->query->get('page', 1));
+    }
+
+    /**
+     * Shows entries associated to a tag for current user.
+     *
+     * @Route("/{username}/{token}/tags/{slug}.xml", name="tag_rss", defaults={"_format"="xml"})
+     * @ParamConverter("user", class="WallabagUserBundle:User", converter="username_rsstoken_converter")
+     * @ParamConverter("tag", options={"mapping": {"slug": "slug"}})
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function showTagsAction(Request $request, User $user, Tag $tag)
+    {
+        $page = $request->query->get('page', 1);
+
+        $url = $this->generateUrl(
+            'tag_rss',
+            [
+                'username' => $user->getUsername(),
+                'token' => $user->getConfig()->getRssToken(),
+                'slug' => $tag->getSlug(),
+            ],
+            UrlGeneratorInterface::ABSOLUTE_URL
+        );
+
+        $entriesByTag = $this->get('wallabag_core.entry_repository')->findAllByTagId(
+            $user->getId(),
+            $tag->getId()
+        );
+
+        $pagerAdapter = new ArrayAdapter($entriesByTag);
+
+        $entries = $this->get('wallabag_core.helper.prepare_pager_for_entries')->prepare(
+            $pagerAdapter,
+            $user
+        );
+
+        if (null === $entries) {
+            throw $this->createNotFoundException('No entries found?');
+        }
+
+        try {
+            $entries->setCurrentPage($page);
+        } catch (OutOfRangeCurrentPageException $e) {
+            if ($page > 1) {
+                return $this->redirect($url.'?page='.$entries->getNbPages(), 302);
+            }
+        }
+
+        return $this->render(
+            '@WallabagCore/themes/common/Entry/entries.xml.twig',
+            [
+                'url_html' => $this->generateUrl('tag_entries', ['slug' => $tag->getSlug()], UrlGeneratorInterface::ABSOLUTE_URL),
+                'type' => 'tag ('.$tag->getLabel().')',
+                'url' => $url,
+                'entries' => $entries,
+            ],
+            new Response('', 200, ['Content-Type' => 'application/rss+xml'])
+        );
+    }
+
     /**
      * Global method to retrieve entries depending on the given type
      * It returns the response to be send.
@@ -66,7 +141,7 @@ class RssController extends Controller
      */
     private function showEntries($type, User $user, $page = 1)
     {
-        $repository = $this->getDoctrine()->getRepository('WallabagCoreBundle:Entry');
+        $repository = $this->get('wallabag_core.entry_repository');
 
         switch ($type) {
             case 'starred':
@@ -81,6 +156,10 @@ class RssController extends Controller
                 $qb = $repository->getBuilderForUnreadByUser($user->getId());
                 break;
 
+            case 'all':
+                $qb = $repository->getBuilderForAllByUser($user->getId());
+                break;
+
             default:
                 throw new \InvalidArgumentException(sprintf('Type "%s" is not implemented.', $type));
         }
@@ -108,10 +187,15 @@ class RssController extends Controller
             }
         }
 
-        return $this->render('@WallabagCore/themes/common/Entry/entries.xml.twig', [
-            'type' => $type,
-            'url' => $url,
-            'entries' => $entries,
-        ]);
+        return $this->render(
+            '@WallabagCore/themes/common/Entry/entries.xml.twig',
+            [
+                'url_html' => $this->generateUrl($type, [], UrlGeneratorInterface::ABSOLUTE_URL),
+                'type' => $type,
+                'url' => $url,
+                'entries' => $entries,
+            ],
+            new Response('', 200, ['Content-Type' => 'application/rss+xml'])
+        );
     }
 }
index 9422bae43644b1796518d14ec5680661e4547fcd..a8b1eaddb9a045008fb12adcce30695528c21fc0 100644 (file)
@@ -84,16 +84,17 @@ class TagController extends Controller
      */
     public function showTagAction()
     {
-        $tags = $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Tag')
+        $repository = $this->get('wallabag_core.entry_repository');
+        $tags = $this->get('wallabag_core.tag_repository')
             ->findAllTags($this->getUser()->getId());
 
         $flatTags = [];
 
         foreach ($tags as $tag) {
-            $nbEntries = $this->getDoctrine()
-                ->getRepository('WallabagCoreBundle:Entry')
-                ->countAllEntriesByUserIdAndTagId($this->getUser()->getId(), $tag->getId());
+            $nbEntries = $repository->countAllEntriesByUserIdAndTagId(
+                $this->getUser()->getId(),
+                $tag->getId()
+            );
 
             $flatTags[] = [
                 'id' => $tag->getId(),
@@ -119,9 +120,10 @@ class TagController extends Controller
      */
     public function showEntriesForTagAction(Tag $tag, $page, Request $request)
     {
-        $entriesByTag = $this->getDoctrine()
-            ->getRepository('WallabagCoreBundle:Entry')
-            ->findAllByTagId($this->getUser()->getId(), $tag->getId());
+        $entriesByTag = $this->get('wallabag_core.entry_repository')->findAllByTagId(
+            $this->getUser()->getId(),
+            $tag->getId()
+        );
 
         $pagerAdapter = new ArrayAdapter($entriesByTag);
 
@@ -142,7 +144,7 @@ class TagController extends Controller
             'form' => null,
             'entries' => $entries,
             'currentPage' => $page,
-            'tag' => $tag->getSlug(),
+            'tag' => $tag,
         ]);
     }
 }
index df579ebdc1fe260205528dfbd194d1a18462ed1e..231a0b5243a9b268399ac9637ce1e2510c564160 100644 (file)
@@ -4,6 +4,7 @@ namespace Wallabag\CoreBundle\Helper;
 
 use Pagerfanta\Adapter\AdapterInterface;
 use Pagerfanta\Pagerfanta;
+use Wallabag\UserBundle\Entity\User;
 use Symfony\Component\Routing\Router;
 use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
 
@@ -20,12 +21,15 @@ class PreparePagerForEntries
 
     /**
      * @param AdapterInterface $adapter
+     * @param User             $user    If user isn't logged in, we can force it (like for rss)
      *
      * @return null|Pagerfanta
      */
-    public function prepare(AdapterInterface $adapter)
+    public function prepare(AdapterInterface $adapter, User $user = null)
     {
-        $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
+        if (null === $user) {
+            $user = $this->tokenStorage->getToken() ? $this->tokenStorage->getToken()->getUser() : null;
+        }
 
         if (null === $user || !is_object($user)) {
             return;
index a91a0ce4e225e2c552c1504d5a6122dbc2c0fea6..52904d2572db520e6a13bdc66d703894994cf30b 100644 (file)
@@ -90,9 +90,10 @@ config:
         token_reset: 'Nulstil token'
         rss_links: 'RSS-Links'
         rss_link:
-            unread: 'ulæst'
-            starred: 'favoritter'
-            archive: 'arkiv'
+            unread: 'Ulæst'
+            starred: 'Favoritter'
+            archive: 'Arkiv'
+            # all: 'All'
         # rss_limit: 'Number of items in the feed'
     form_user:
         # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion"
index e77cdca30fc4d3d900da1aaae8e1ab47e750a1d7..481b5d0544ab7c8eac11badb3d094c8654ad46fb 100644 (file)
@@ -93,6 +93,7 @@ config:
             unread: 'Ungelesene'
             starred: 'Favoriten'
             archive: 'Archivierte'
+            # all: 'All'
         rss_limit: 'Anzahl der Einträge pro Feed'
     form_user:
         two_factor_description: "Wenn du die Zwei-Faktor-Authentifizierung aktivierst, erhältst du eine E-Mail mit einem Code bei jeder nicht vertrauenswürdigen Verbindung"
index 50edab3a0b349683eb7c093d974238ee39632675..98888d0573a90f06f2d0a8845528d5eb337cc011 100644 (file)
@@ -90,9 +90,10 @@ config:
         token_reset: 'Regenerate your token'
         rss_links: 'RSS links'
         rss_link:
-            unread: 'unread'
-            starred: 'starred'
-            archive: 'archived'
+            unread: 'Unread'
+            starred: 'Starred'
+            archive: 'Archived'
+            all: 'All'
         rss_limit: 'Number of items in the feed'
     form_user:
         two_factor_description: "Enabling two factor authentication means you'll receive an email with a code on every new untrusted connection."
index 6fbf00eb4937a62115e470d02ea7af312ed10454..310a00deb942c28e8086300dc366c8a59fbf14b2 100644 (file)
@@ -93,6 +93,7 @@ config:
             unread: 'sin leer'
             starred: 'favoritos'
             archive: 'archivados'
+            # all: 'All'
         rss_limit: 'Límite de artículos en feed RSS'
     form_user:
         two_factor_description: "Con la autenticación en dos pasos recibirá código por e-mail en cada nueva conexión que no sea de confianza."
index ad7d6cd98a8cce49a71bedcbd1db8002f0c2fb2c..d5247fc36573036fcc4fe8047dee39c29bf44e22 100644 (file)
@@ -93,6 +93,7 @@ config:
             unread: 'خوانده‌نشده'
             starred: 'برگزیده'
             archive: 'بایگانی'
+            # all: 'All'
         rss_limit: 'محدودیت آر-اس-اس'
     form_user:
         two_factor_description: "با فعال‌کردن تأیید ۲مرحله‌ای هر بار که اتصال تأییدنشده‌ای برقرار شد، به شما یک کد از راه ایمیل فرستاده می‌شود"
index c4b029c3c3b7fbdc8b96d49db546c414779d4ee7..b338eba4ad614386adcd0ac891fd083c821f251b 100644 (file)
@@ -88,11 +88,12 @@ config:
         no_token: "Aucun jeton généré"
         token_create: "Créez votre jeton"
         token_reset: "Réinitialisez votre jeton"
-        rss_links: "Adresse de vos flux RSS"
+        rss_links: "Adresses de vos flux RSS"
         rss_link:
-            unread: "non lus"
-            starred: "favoris"
-            archive: "lus"
+            unread: "Non lus"
+            starred: "Favoris"
+            archive: "Lus"
+            all: "Tous"
         rss_limit: "Nombre d’articles dans le flux"
     form_user:
         two_factor_description: "Activer l’authentification double-facteur veut dire que vous allez recevoir un code par courriel à chaque nouvelle connexion non approuvée."
index 4bd04aadb81f0bd50bbf6fb7ba8bf808a0080bfc..a3ff5495b1b502715fec0b24907e40b9b7db5bad 100644 (file)
@@ -90,9 +90,10 @@ config:
         token_reset: 'Rigenera il tuo token'
         rss_links: 'Collegamenti RSS'
         rss_link:
-            unread: 'non letti'
-            starred: 'preferiti'
-            archive: 'archiviati'
+            unread: 'Non letti'
+            starred: 'Preferiti'
+            archive: 'Archiviati'
+            # all: 'All'
         rss_limit: 'Numero di elementi nel feed'
     form_user:
         two_factor_description: "Abilitando l'\autenticazione a due fattori riceverai una e-mail con un codice per ogni nuova connesione non verificata"
index a6dd4dcd0361593a0cd44f391990fe35084f3527..a6566a12df18706bb92b35248ce86bbf36e54ae8 100644 (file)
@@ -88,11 +88,12 @@ config:
         no_token: 'Pas cap de geton generat'
         token_create: 'Creatz vòstre geton'
         token_reset: 'Reïnicializatz vòstre geton'
-        rss_links: 'URL de vòstres fluxes RSS'
+        rss_links: 'URLs de vòstres fluxes RSS'
         rss_link:
-            unread: 'pas legits'
-            starred: 'favorits'
-            archive: 'legits'
+            unread: 'Pas legits'
+            starred: 'Favorits'
+            archive: 'Legits'
+            # all: 'All'
         rss_limit: "Nombre d'articles dins un flux RSS"
     form_user:
         two_factor_description: "Activar l'autentificacion doble-factor vòl dire que recebretz un còdi per corrièl per cada novèla connexion pas aprovada."
index 7312abd79b0d7829b3645bad1cbcfc24e3e10fa2..8e1276d9c101c9fb7c1d1d9a55067586f413fcca 100644 (file)
@@ -90,9 +90,10 @@ config:
         token_reset: 'Zresetuj swojego tokena'
         rss_links: 'RSS links'
         rss_link:
-            unread: 'nieprzeczytane'
-            starred: 'oznaczone gwiazdką'
-            archive: 'archiwum'
+            unread: 'Nieprzeczytane'
+            starred: 'Oznaczone gwiazdką'
+            archive: 'Archiwum'
+            # all: 'All'
         rss_limit: 'Link do RSS'
     form_user:
         two_factor_description: "Włączenie autoryzacji dwuetapowej oznacza, że będziesz otrzymywał maile z kodem przy każdym nowym, niezaufanym połączeniu"
index 18090352db832430f0a63e192bd9acacf3c0da47..953c86bb015ac46b5254e587612e38985de9b360 100644 (file)
@@ -90,9 +90,10 @@ config:
         token_reset: 'Gerar novamente seu token'
         rss_links: 'Links RSS'
         rss_link:
-            unread: 'não lido'
-            starred: 'destacado'
-            archive: 'arquivado'
+            unread: 'Não lido'
+            starred: 'Destacado'
+            archive: 'Arquivado'
+            # all: 'All'
         rss_limit: 'Número de itens no feed'
     form_user:
         two_factor_description: 'Habilitar autenticação de dois passos significa que você receberá um e-mail com um código a cada nova conexão desconhecida.'
index f8866fdc1f174ced119dce9b2831c5b41ef2a7dc..51dbbcafcbc7c05cea949a7c9ef45ef704fad9d8 100644 (file)
@@ -90,9 +90,10 @@ config:
         token_reset: 'Resetează-ți token-ul'
         rss_links: 'Link-uri RSS'
         rss_link:
-            unread: 'unread'
-            starred: 'starred'
-            archive: 'archived'
+            unread: 'Unread'
+            starred: 'Starred'
+            archive: 'Archived'
+            # all: 'All'
         rss_limit: 'Limită RSS'
     form_user:
         # two_factor_description: "Enabling two factor authentication means you'll receive an email with a code on every new untrusted connexion"
index 4d01e7f75e460cd5c104aed9a92c7a12ea1933ba..ff19e9d91a710946290efb9bf4d38d9d11245a57 100644 (file)
@@ -90,9 +90,10 @@ config:
         token_reset: 'Belirteci (token) sıfırla'
         rss_links: 'RSS akış bağlantıları'
         rss_link:
-            unread: 'okunmayan'
-            starred: 'favoriler'
-            archive: 'arşiv'
+            unread: 'Okunmayan'
+            starred: 'Favoriler'
+            archive: 'Arşiv'
+            # all: 'All'
         rss_limit: 'RSS içeriğinden talep edilecek makale limiti'
     form_user:
         two_factor_description: "İki adımlı doğrulamayı aktifleştirdiğinizde, her yeni güvenilmeyen bağlantılarda size e-posta ile bir kod alacaksınız."
index 01f63a7b2b46b6c0c5509483ca3d781c43dc3995..2bf64cd6a237ec46bb606673f8c0e4f01ce54774 100644 (file)
@@ -82,7 +82,7 @@
         <fieldset class="w500p inline">
             <div class="row">
                 <h3>{{ 'config.form_settings.android_configuration'|trans }}</h3>
-                <a href="wallabag://{{ app.user.username }}@{{ wallabag_url }}" >Touch here to prefill your Android application</a>
+                <a href="wallabag://{{ app.user.username }}@{{ wallabag_url }}">Touch here to prefill your Android application</a>
                 <br/>
                 <img id="androidQrcode" />
                 <script>
 
         <fieldset class="w500p inline">
             <div class="row">
-                <label>Rss token</label>
+                <label>{{ 'config.form_rss.token_label'|trans }}</label>
                 {% if rss.token %}
                     {{ rss.token }}
                 {% else %}
             <div class="row">
                 <label>{{ 'config.form_rss.rss_links'|trans }}</label>
                 <ul>
-                    <li><a href="{{ path('unread_rss', {'username': rss.username, 'token': rss.token}) }}">unread</a></li>
-                    <li><a href="{{ path('starred_rss', {'username': rss.username, 'token': rss.token}) }}">fav</a></li>
-                    <li><a href="{{ path('archive_rss', {'username': rss.username, 'token': rss.token}) }}">archives</a></li>
+                    <li><a href="{{ path('unread_rss', {'username': rss.username, 'token': rss.token}) }}">{{ 'config.form_rss.rss_link.unread'|trans }}</a></li>
+                    <li><a href="{{ path('starred_rss', {'username': rss.username, 'token': rss.token}) }}">{{ 'config.form_rss.rss_link.starred'|trans }}</a></li>
+                    <li><a href="{{ path('archive_rss', {'username': rss.username, 'token': rss.token}) }}">{{ 'config.form_rss.rss_link.archive'|trans }}</a></li>
+                    <li><a href="{{ path('all_rss', {'username': rss.username, 'token': rss.token}) }}">{{ 'config.form_rss.rss_link.all'|trans }}</a></li>
                 </ul>
             </div>
         </fieldset>
index 6c26d5bf4f716861408a0abd29677bf5f753ffec..6424df8d3ba710f064bb94f00612f0fc6ae36c94 100644 (file)
@@ -1,5 +1,12 @@
 {% extends "WallabagCoreBundle::layout.html.twig" %}
 
+{% block head %}
+    {{ parent() }}
+    {% if tag is defined and app.user.config.rssToken %}
+        <link rel="alternate" type="application/rss+xml" href="{{ path('tag_rss', {'username': app.user.username, 'token': app.user.config.rssToken, 'slug': tag.slug}) }}" />
+    {% endif %}
+{% endblock %}
+
 {% block title %}
     {% set filter = '' %}
     {% if tag is defined %}
 {% endblock %}
 
 {% block content %}
-
+    {% set currentRoute = app.request.attributes.get('_route') %}
     {% set listMode = app.user.config.listMode %}
     <div class="results">
         <div class="nb-results">{{ 'entry.list.number_on_the_page'|transchoice(entries.count) }}</div>
         <div class="pagination">
             <a href="{{ path('switch_view_mode') }}"><i class="listMode-btn material-icons md-24">{% if listMode == 0 %}list{% else %}view_module{% endif %}</i></a>
+            {% if app.user.config.rssToken %}
+                {% include "@WallabagCore/themes/common/Entry/_rss_link.html.twig" %}
+            {% endif %}
             <i class="btn-clickable download-btn material-icons md-24 js-export-action">file_download</i>
             <i class="btn-clickable filter-btn material-icons md-24 js-filters-action">filter_list</i>
             {% if entries.getNbPages > 1 %}
@@ -76,7 +86,6 @@
 
     <!-- Export -->
     <aside id="download-form">
-    {% set currentRoute = app.request.attributes.get('_route') %}
     {% set currentTag = '' %}
     {% if tag is defined %}
         {% set currentTag = tag %}
index 7509918ede38c31fc8fa62845326494100b0e0b2..070d5629a4474a9a4afcc69e4de383eabe495b18 100644 (file)
@@ -9,7 +9,12 @@
 
     <ul>
     {% for tag in tags %}
-        <li id="tag-{{ tag.id|e }}"><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.nbEntries }})</a></li>
+        <li id="tag-{{ tag.id|e }}">
+            <a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.nbEntries }})</a>
+            <a rel="alternate" type="application/rss+xml" href="{{ path('tag_rss', {'username': app.user.username, 'token': app.user.config.rssToken, 'slug': tag.slug}) }}" class="right">
+                <i class="material-icons md-24">rss_feed</i>
+            </a>
+        </li>
     {% endfor %}
     </ul>
 
diff --git a/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_rss_link.html.twig b/src/Wallabag/CoreBundle/Resources/views/themes/common/Entry/_rss_link.html.twig
new file mode 100644 (file)
index 0000000..2bf9b2b
--- /dev/null
@@ -0,0 +1,6 @@
+{% if tag is defined %}
+    <a rel="alternate" type="application/rss+xml" href="{{ path('tag_rss', {'username': app.user.username, 'token': app.user.config.rssToken, 'slug': tag.slug}) }}" class="right"><i class="material-icons md-24">rss_feed</i></a>
+{% elseif currentRoute in ['unread', 'starred', 'archive', 'all'] %}
+    <a rel="alternate" type="application/rss+xml" href="{{ path(currentRoute ~ '_rss', {'username': app.user.username, 'token': app.user.config.rssToken}) }}" class="right"><i class="material-icons">rss_feed</i></a>
+{% endif %}
+
index 12e8c79fd73c0d8a7555f313275a03e2a5705a10..d70aa5dc9c99e58fa043d47183ae5e936e0a164f 100644 (file)
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8"?>
 <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
     <channel>
-        <title>wallabag — {{type}} feed</title>
-        <link>{{ url(type) }}</link>
+        <title>wallabag - {{ type }} feed</title>
+        <link>{{ url_html }}</link>
         <link rel="self" href="{{ app.request.uri }}"/>
         {% if entries.hasPreviousPage -%}
             <link rel="previous" href="{{ url }}?page={{ entries.previousPage }}"/>
@@ -13,7 +13,7 @@
         <link rel="last" href="{{ url }}?page={{ entries.nbPages }}"/>
         <pubDate>{{ "now"|date('D, d M Y H:i:s') }}</pubDate>
         <generator>wallabag</generator>
-        <description>wallabag {{type}} elements</description>
+        <description>wallabag {{ type }} elements</description>
 
         {% for entry in entries %}
 
index 1e10bf38abc5bf160c7833f207ad2d19850b5ba8..f290cb49c971169c14eb2729663591b23d293f25 100644 (file)
                                         <li><a href="{{ path('unread_rss', {'username': rss.username, 'token': rss.token}) }}">{{ 'config.form_rss.rss_link.unread'|trans }}</a></li>
                                         <li><a href="{{ path('starred_rss', {'username': rss.username, 'token': rss.token}) }}">{{ 'config.form_rss.rss_link.starred'|trans }}</a></li>
                                         <li><a href="{{ path('archive_rss', {'username': rss.username, 'token': rss.token}) }}">{{ 'config.form_rss.rss_link.archive'|trans }}</a></li>
+                                        <li><a href="{{ path('all_rss', {'username': rss.username, 'token': rss.token}) }}">{{ 'config.form_rss.rss_link.all'|trans }}</a></li>
                                     </ul>
                                 </div>
                             </div>
index 5ba420575a759d46325420ca2cdd8fe8e7c7565c..0c4dc80b6333491cc6b79adf75120a9b28e49b49 100644 (file)
@@ -1,9 +1,16 @@
 {% extends "WallabagCoreBundle::layout.html.twig" %}
 
+{% block head %}
+    {{ parent() }}
+    {% if tag is defined and app.user.config.rssToken %}
+        <link rel="alternate" type="application/rss+xml" href="{{ path('tag_rss', {'username': app.user.username, 'token': app.user.config.rssToken, 'slug': tag.slug}) }}" />
+    {% endif %}
+{% endblock %}
+
 {% block title %}
     {% set filter = '' %}
     {% if tag is defined %}
-        {% set filter = tag %}
+        {% set filter = tag.slug %}
     {% endif %}
     {% if searchTerm is defined and searchTerm is not empty %}
         {% set filter = searchTerm %}
 
 {% block content %}
     {% set listMode = app.user.config.listMode %}
+    {% set currentRoute = app.request.attributes.get('_route') %}
     <div class="results clearfix">
         <div class="nb-results left">
             {{ 'entry.list.number_on_the_page'|transchoice(entries.count) }}
             <a href="{{ path('switch_view_mode') }}"><i class="material-icons">{% if listMode == 0 %}view_list{% else %}view_module{% endif %}</i></a>
+            {% if app.user.config.rssToken %}
+                {% include "@WallabagCore/themes/common/Entry/_rss_link.html.twig" %}
+            {% endif %}
         </div>
         {% if entries.getNbPages > 1 %}
             {{ pagerfanta(entries, 'twitter_bootstrap_translated', {'proximity': 1}) }}
 
     <!-- Export -->
     <div id="export" class="side-nav right-aligned">
-    {% set currentRoute = app.request.attributes.get('_route') %}
     {% set currentTag = '' %}
     {% if tag is defined %}
-        {% set currentTag = tag %}
+        {% set currentTag = tag.slug %}
     {% endif %}
     {% if currentRoute == 'homepage' %}
         {% set currentRoute = 'unread' %}
index c83543acaaf4e38d7a72556be1cf28572b0810ac..97ddedc9fc84d31d19f5ce04246c085f7e6c7b88 100644 (file)
@@ -14,6 +14,9 @@
             {% for tag in tags %}
                 <li title="{{tag.label}} ({{ tag.nbEntries }})" id="tag-{{ tag.id }}" class="col l2 m2 s5">
                     <a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.nbEntries }})</a>
+                    {% if app.user.config.rssToken %}
+                        <a rel="alternate" type="application/rss+xml" href="{{ path('tag_rss', {'username': app.user.username, 'token': app.user.config.rssToken, 'slug': tag.slug}) }}" class="right"><i class="material-icons">rss_feed</i></a>
+                    {% endif %}
                 </li>
             {% endfor %}
         </ul>
index 5a59654d3601c644c1ed611d5e24354c13a5dbc0..530c8bbfb016afe4a731da2e14b27e38b55eb3f9 100644 (file)
@@ -6,7 +6,7 @@ use Tests\Wallabag\CoreBundle\WallabagCoreTestCase;
 
 class RssControllerTest extends WallabagCoreTestCase
 {
-    public function validateDom($xml, $type, $nb = null)
+    public function validateDom($xml, $type, $urlPagination, $nb = null)
     {
         $doc = new \DOMDocument();
         $doc->loadXML($xml);
@@ -23,7 +23,7 @@ class RssControllerTest extends WallabagCoreTestCase
         $this->assertEquals(1, $xpath->query('/rss/channel')->length);
 
         $this->assertEquals(1, $xpath->query('/rss/channel/title')->length);
-        $this->assertEquals('wallabag  '.$type.' feed', $xpath->query('/rss/channel/title')->item(0)->nodeValue);
+        $this->assertEquals('wallabag - '.$type.' feed', $xpath->query('/rss/channel/title')->item(0)->nodeValue);
 
         $this->assertEquals(1, $xpath->query('/rss/channel/pubDate')->length);
 
@@ -34,10 +34,10 @@ class RssControllerTest extends WallabagCoreTestCase
         $this->assertEquals('wallabag '.$type.' elements', $xpath->query('/rss/channel/description')->item(0)->nodeValue);
 
         $this->assertEquals(1, $xpath->query('/rss/channel/link[@rel="self"]')->length);
-        $this->assertContains($type.'.xml', $xpath->query('/rss/channel/link[@rel="self"]')->item(0)->getAttribute('href'));
+        $this->assertContains($urlPagination.'.xml', $xpath->query('/rss/channel/link[@rel="self"]')->item(0)->getAttribute('href'));
 
         $this->assertEquals(1, $xpath->query('/rss/channel/link[@rel="last"]')->length);
-        $this->assertContains($type.'.xml?page=', $xpath->query('/rss/channel/link[@rel="last"]')->item(0)->getAttribute('href'));
+        $this->assertContains($urlPagination.'.xml?page=', $xpath->query('/rss/channel/link[@rel="last"]')->item(0)->getAttribute('href'));
 
         foreach ($xpath->query('//item') as $item) {
             $this->assertEquals(1, $xpath->query('title', $item)->length);
@@ -94,7 +94,7 @@ class RssControllerTest extends WallabagCoreTestCase
 
         $this->assertEquals(200, $client->getResponse()->getStatusCode());
 
-        $this->validateDom($client->getResponse()->getContent(), 'unread', 2);
+        $this->validateDom($client->getResponse()->getContent(), 'unread', 'unread', 2);
     }
 
     public function testStarred()
@@ -116,7 +116,7 @@ class RssControllerTest extends WallabagCoreTestCase
 
         $this->assertEquals(200, $client->getResponse()->getStatusCode(), 1);
 
-        $this->validateDom($client->getResponse()->getContent(), 'starred');
+        $this->validateDom($client->getResponse()->getContent(), 'starred', 'starred');
     }
 
     public function testArchives()
@@ -138,7 +138,7 @@ class RssControllerTest extends WallabagCoreTestCase
 
         $this->assertEquals(200, $client->getResponse()->getStatusCode());
 
-        $this->validateDom($client->getResponse()->getContent(), 'archive');
+        $this->validateDom($client->getResponse()->getContent(), 'archive', 'archive');
     }
 
     public function testPagination()
@@ -159,13 +159,38 @@ class RssControllerTest extends WallabagCoreTestCase
 
         $client->request('GET', '/admin/SUPERTOKEN/unread.xml');
         $this->assertEquals(200, $client->getResponse()->getStatusCode());
-        $this->validateDom($client->getResponse()->getContent(), 'unread');
+        $this->validateDom($client->getResponse()->getContent(), 'unread', 'unread');
 
         $client->request('GET', '/admin/SUPERTOKEN/unread.xml?page=2');
         $this->assertEquals(200, $client->getResponse()->getStatusCode());
-        $this->validateDom($client->getResponse()->getContent(), 'unread');
+        $this->validateDom($client->getResponse()->getContent(), 'unread', 'unread');
 
         $client->request('GET', '/admin/SUPERTOKEN/unread.xml?page=3000');
         $this->assertEquals(302, $client->getResponse()->getStatusCode());
     }
+
+    public function testTags()
+    {
+        $client = $this->getClient();
+        $em = $client->getContainer()->get('doctrine.orm.entity_manager');
+        $user = $em
+            ->getRepository('WallabagUserBundle:User')
+            ->findOneByUsername('admin');
+
+        $config = $user->getConfig();
+        $config->setRssToken('SUPERTOKEN');
+        $config->setRssLimit(null);
+        $em->persist($config);
+        $em->flush();
+
+        $client = $this->getClient();
+        $client->request('GET', '/admin/SUPERTOKEN/tags/foo-bar.xml');
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+
+        $this->validateDom($client->getResponse()->getContent(), 'tag (foo bar)', 'tags/foo-bar');
+
+        $client->request('GET', '/admin/SUPERTOKEN/tags/foo-bar.xml?page=3000');
+        $this->assertEquals(302, $client->getResponse()->getStatusCode());
+    }
 }