]> git.immae.eu Git - github/wallabag/wallabag.git/commitdiff
Merge pull request #2243 from wallabag/feature-untagged-entries
authorJeremy Benoist <j0k3r@users.noreply.github.com>
Sun, 28 Aug 2016 13:56:17 +0000 (15:56 +0200)
committerGitHub <noreply@github.com>
Sun, 28 Aug 2016 13:56:16 +0000 (15:56 +0200)
Add untagged entries

18 files changed:
src/Wallabag/CoreBundle/Controller/EntryController.php
src/Wallabag/CoreBundle/Controller/ExportController.php
src/Wallabag/CoreBundle/Repository/EntryRepository.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.ro.yml
src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml
src/Wallabag/CoreBundle/Resources/views/themes/_title.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/baggy/Tag/tags.html.twig
src/Wallabag/CoreBundle/Resources/views/themes/material/Tag/tags.html.twig
tests/Wallabag/CoreBundle/Controller/EntryControllerTest.php

index d71ba6cd5858df70dbe9afdf7e7a318274b7bc19..624576b5bee67a43be98418a72e5c4ce93831233 100644 (file)
@@ -226,6 +226,10 @@ class EntryController extends Controller
         $repository = $this->get('wallabag_core.entry_repository');
 
         switch ($type) {
+            case 'untagged':
+                $qb = $repository->getBuilderForUntaggedByUser($this->getUser()->getId());
+
+                break;
             case 'starred':
                 $qb = $repository->getBuilderForStarredByUser($this->getUser()->getId());
                 break;
@@ -523,4 +527,19 @@ class EntryController extends Controller
             ['entry' => $entry]
         );
     }
+
+    /**
+     * Shows untagged articles for current user.
+     *
+     * @param Request $request
+     * @param int     $page
+     *
+     * @Route("/untagged/list/{page}", name="untagged", defaults={"page" = "1"})
+     *
+     * @return \Symfony\Component\HttpFoundation\Response
+     */
+    public function showUntaggedEntriesAction(Request $request, $page)
+    {
+        return $this->showEntries('untagged', $request, $page);
+    }
 }
index 959b308d8bc0e5cff8bfce213b9e8f50c2970e19..6191d5d7973241f4582007b1db063766856e9f9b 100644 (file)
@@ -46,7 +46,7 @@ class ExportController extends Controller
      *
      * @Route("/export/{category}.{format}", name="export_entries", requirements={
      *     "format": "epub|mobi|pdf|json|xml|txt|csv",
-     *     "category": "all|unread|starred|archive|tag_entries"
+     *     "category": "all|unread|starred|archive|tag_entries|untagged"
      * })
      *
      * @return \Symfony\Component\HttpFoundation\Response
index fada40bbd4c5c8e24010c0b2140e23a6b03ecb35..e5c21679935a51035a9df97a88486a27a6864e0e 100644 (file)
@@ -84,6 +84,22 @@ class EntryRepository extends EntityRepository
         ;
     }
 
+    /**
+     * Retrieves untagged entries for a user.
+     *
+     * @param int $userId
+     *
+     * @return QueryBuilder
+     */
+    public function getBuilderForUntaggedByUser($userId)
+    {
+        return $this
+            ->getBuilderByUser($userId)
+            ->leftJoin('e.tags', 't')
+            ->groupBy('e.id')
+            ->having('count(t.id) = 0');
+    }
+
     /**
      * Find Entries.
      *
index f9b7bfacdac8c9a93aeb541527f77eaf1dbb5e94..3c98d4f4b0b86e49402734780d3145708c771b85 100644 (file)
@@ -140,6 +140,7 @@ entry:
         # archived: 'Archived entries'
         # filtered: 'Filtered entries'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
         reading_time: 'estimeret læsetid'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Tags'
     list:
         # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     # page_title: 'Import'
index 79d03286bdc7e989784168b8dc534fcd0b686cc8..b3f6719b6e0500b4e8da860223992883460f37df 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Archivierte Einträge'
         filtered: 'Gefilterte Einträge'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} Es gibt keine Einträge.|{1} Es gibt einen Eintrag.|]1,Inf[ Es gibt %count% Einträge.'
         reading_time: 'geschätzte Lesezeit'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Tags'
     list:
         number_on_the_page: '{0} Es gibt keine Tags.|{1} Es gibt einen Tag.|]1,Inf[ Es gibt %count% Tags.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Importieren'
index d921b39f9579a9cac1123a45dc3f7d96fe8d71ef..220c4d9c39a0fb8b8b81e3997e0feaac6a5e3a9b 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Archived entries'
         filtered: 'Filtered entries'
         filtered_tags: 'Filtered by tags'
+        untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} There are no entries.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
         reading_time: 'estimated reading time'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Tags'
     list:
         number_on_the_page: '{0} There are no tags.|{1} There is one tag.|]1,Inf[ There are %count% tags.'
+        see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Import'
index c2ec4dbd77fae8227a168c2420cde87737d4ae70..cae07cf275bebadc759e6c5539217058f2f9a9a2 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Artículos archivados'
         filtered: 'Artículos filtrados'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} No hay artículos.|{1} Hay un artículo.|]1,Inf[ Hay %count% artículos.'
         reading_time: 'tiempo estimado de lectura'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Etiquetas'
     list:
         number_on_the_page: '{0} No hay ninguna etiqueta.|{1} Hay una etiqueta.|]1,Inf[ Hay %count% etiquetas.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Importar'
index 561ed907487675070e5677cbffc0e84780f85100..fa34c307f6c0e006a9f0470da1578d1af981cea4 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'مقاله‌های بایگانی‌شده'
         filtered: 'مقاله‌های فیلترشده'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} هیج مقاله‌ای نیست.|{1} یک مقاله هست.|]1,Inf[ %count% مقاله هست.'
         reading_time: 'زمان تخمینی برای خواندن'
@@ -312,6 +313,7 @@ tag:
     page_title: 'برچسب‌ها'
     list:
         number_on_the_page: '{0} هیچ برچسبی نیست.|{1} یک برچسب هست.|]1,Inf[ %count% برچسب هست.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
      page_title: 'درون‌ریزی'
index c0671883ab9432c86d85d8a396f7ab226eb1261f..b8547fef3f62c3912130d3f8341ef089948fa733 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Articles lus'
         filtered: 'Articles filtrés'
         filtered_tags: 'Articles filtrés par tags'
+        untagged: 'Article sans tag'
     list:
         number_on_the_page: "{0} Il n'y a pas d'articles.|{1} Il y a un article.|]1,Inf[ Il y a %count% articles."
         reading_time: 'durée de lecture'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Tags'
     list:
         number_on_the_page: "{0} Il n'y a pas de tag.|{1} Il y a un tag.|]1,Inf[ Il y a %count% tags."
+        see_untagged_entries: 'Voir les articles sans tag'
 
 import:
     page_title: 'Importer'
index 2e3dd08b0c82680b706badc54e1d7039367691d1..d3c9ca4b991cb52ca2bf1a08f67134e2deb2b85e 100644 (file)
@@ -139,6 +139,8 @@ entry:
         starred: 'Contenuti preferiti'
         archived: 'Contenuti archiviati'
         filtered: 'Contenuti filtrati'
+        # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: "{0} Non ci sono contenuti.|{1} C'è un contenuto.|]1,Inf[ Ci sono %count% contenuti."
         reading_time: 'tempo di lettura stimato'
@@ -310,6 +312,7 @@ tag:
     page_title: 'Tags'
     list:
         number_on_the_page: "{0} Non ci sono tag.|{1} C'è un tag.|]1,Inf[ ci sono %count% tag."
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Importa'
index 7b978a609eadf0abaccb477ea746e3ace0dc8922..c98b1220032569e4313bd2e5f8407fefd9e6e17a 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Articles legits'
         filtered: 'Articles filtrats'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: "{0} I a pas cap d'article.|{1} I a un article.|]1,Inf[ I a %count% articles."
         reading_time: 'durada de lectura'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Etiquetas'
     list:
         number_on_the_page: "{0} I a pas cap d'etiquetas.|{1} I a una etiqueta.|]1,Inf[ I a %count% etiquetas."
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Importar'
index da170e4d64cd50459bdadfebd43842d947a24407..af2ab24f83c01cc0cebb2d6f046987e2279cebbe 100644 (file)
@@ -140,6 +140,7 @@ entry:
         archived: 'Zarchiwizowane wpisy'
         filtered: 'Odfiltrowane wpisy'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} Nie ma wpisów.|{1} Jest jeden wpis.|]1,Inf[ Są %count% wpisy.'
         reading_time: 'szacunkowy czas czytania'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Tagi'
     list:
         number_on_the_page: '{0} Nie ma tagów.|{1} Jest jeden tag.|]1,Inf[ Są %count% tagi.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'Import'
index fa2d6468cd8b253c1e6031c5b83c99bbf008d3eb..d4ee5cbdd70a045165d2e48de9112f8175e494c8 100644 (file)
@@ -140,6 +140,7 @@ entry:
         # archived: 'Archived entries'
         # filtered: 'Filtered entries'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         # number_on_the_page: '{0} There is no entry.|{1} There is one entry.|]1,Inf[ There are %count% entries.'
         reading_time: 'timp estimat de citire'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Tag-uri'
     list:
         # number_on_the_page: '{0} There is no tag.|{1} There is one tag.|]1,Inf[ There are %count% tags.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     # page_title: 'Import'
index 05c31336fb8d8f204b7ec47e349c53a288cbfac1..78a72d861ac8cdb16eb9c18bdbc7a9f292168659 100644 (file)
@@ -140,6 +140,7 @@ entry:
         # archived: 'Archived entries'
         # filtered: 'Filtered entries'
         # filtered_tags: 'Filtered by tags'
+        # untagged: 'Untagged entries'
     list:
         number_on_the_page: '{0} Herhangi bir makale yok.|{1} Burada bir adet makale var.|]1,Inf[ Burada %count% adet makale var.'
         reading_time: 'tahmini okuma süresi'
@@ -312,6 +313,7 @@ tag:
     page_title: 'Etiketler'
     list:
         number_on_the_page: '{0} Herhangi bir etiket yok.|{1} Burada bir adet etiket var.|]1,Inf[ Burada %count% adet etiket var.'
+        # see_untagged_entries: 'See untagged entries'
 
 import:
     page_title: 'İçe Aktar'
index 525e2a204b0ecc783a58d1e003ad4b9480f03a63..d1c2f20379f19182b0a4a312604e07f37f1f1519 100644 (file)
@@ -8,6 +8,8 @@
     {{ 'entry.page_titles.filtered'|trans }}
 {% elseif currentRoute == 'tag_entries' %}
     {{ 'entry.page_titles.filtered_tags'|trans }}
+{% elseif currentRoute == 'untagged' %}
+    {{ 'entry.page_titles.untagged'|trans }}
 {% else %}
     {{ 'entry.page_titles.unread'|trans }}
 {% endif %}
index 739e14864e1ab79b06165e55858f5a8b3ceae45a..50043907a1ee54d5f86d615f3d848d931cc15e43 100644 (file)
@@ -12,4 +12,8 @@
         <li id="tag-{{ tag.id|e }}"><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.entries.getValues | length }})</a></li>
     {% endfor %}
     </ul>
+
+    <div>
+        <a href="{{ path('untagged') }}">{{ 'tag.list.see_untagged_entries'|trans }}</a>
+    </div>
 {% endblock %}
index 9495f5436d2f996f1ceee825fb75fd2f83d4fde4..1690633a531150656a2c388a5c2574899f35e6c2 100644 (file)
@@ -12,4 +12,7 @@
         <li id="tag-{{ tag.id|e }}" class="col l4 m6 s12"><a href="{{ path('tag_entries', {'slug': tag.slug}) }}">{{tag.label}} ({{ tag.entries.getValues | length }})</a></li>
     {% endfor %}
     </ul>
+    <div>
+        <a href="{{ path('untagged') }}">{{ 'tag.list.see_untagged_entries'|trans }}</a>
+    </div>
 {% endblock %}
index f9ac28c3ac3fc125bc324d8e189db3283ac1e7b5..a74c17d9549372324632edbf5910765c9d6a8087 100644 (file)
@@ -236,6 +236,16 @@ class EntryControllerTest extends WallabagCoreTestCase
         $this->assertEquals(200, $client->getResponse()->getStatusCode());
     }
 
+    public function testUntagged()
+    {
+        $this->logInAs('admin');
+        $client = $this->getClient();
+
+        $client->request('GET', '/untagged/list');
+
+        $this->assertEquals(200, $client->getResponse()->getStatusCode());
+    }
+
     public function testStarred()
     {
         $this->logInAs('admin');