mirror of
https://github.com/wallabag/wallabag.git
synced 2024-11-14 21:11:06 +00:00
Merge pull request #3020 from wallabag/add-remove-archived-entries
Allow to remove all archived entries
This commit is contained in:
commit
19122cf660
19 changed files with 208 additions and 6 deletions
|
@ -122,4 +122,21 @@ class AnnotationRepository extends EntityRepository
|
|||
->setParameter('userId', $userId)
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find all annotations related to archived entries.
|
||||
*
|
||||
* @param $userId
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function findAllArchivedEntriesByUser($userId)
|
||||
{
|
||||
return $this->createQueryBuilder('a')
|
||||
->leftJoin('a.entry', 'e')
|
||||
->where('a.user = :userid')->setParameter(':userid', $userId)
|
||||
->andWhere('e.isArchived = true')
|
||||
->getQuery()
|
||||
->getResult();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -248,7 +248,7 @@ class ConfigController extends Controller
|
|||
break;
|
||||
|
||||
case 'entries':
|
||||
// SQLite doesn't care about cascading remove, so we need to manually remove associated stuf
|
||||
// SQLite doesn't care about cascading remove, so we need to manually remove associated stuff
|
||||
// otherwise they won't be removed ...
|
||||
if ($this->get('doctrine')->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
|
||||
$this->getDoctrine()->getRepository('WallabagAnnotationBundle:Annotation')->removeAllByUserId($this->getUser()->getId());
|
||||
|
@ -260,6 +260,19 @@ class ConfigController extends Controller
|
|||
$this->getDoctrine()
|
||||
->getRepository('WallabagCoreBundle:Entry')
|
||||
->removeAllByUserId($this->getUser()->getId());
|
||||
break;
|
||||
case 'archived':
|
||||
if ($this->get('doctrine')->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
|
||||
$this->removeAnnotationsForArchivedByUserId($this->getUser()->getId());
|
||||
}
|
||||
|
||||
// manually remove tags to avoid orphan tag
|
||||
$this->removeTagsForArchivedByUserId($this->getUser()->getId());
|
||||
|
||||
$this->getDoctrine()
|
||||
->getRepository('WallabagCoreBundle:Entry')
|
||||
->removeArchivedByUserId($this->getUser()->getId());
|
||||
break;
|
||||
}
|
||||
|
||||
$this->get('session')->getFlashBag()->add(
|
||||
|
@ -271,14 +284,13 @@ class ConfigController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* Remove all tags for a given user and cleanup orphan tags.
|
||||
* Remove all tags for given tags and a given user and cleanup orphan tags.
|
||||
*
|
||||
* @param int $userId
|
||||
* @param array $tags
|
||||
* @param int $userId
|
||||
*/
|
||||
private function removeAllTagsByUserId($userId)
|
||||
private function removeAllTagsByStatusAndUserId($tags, $userId)
|
||||
{
|
||||
$tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($userId);
|
||||
|
||||
if (empty($tags)) {
|
||||
return;
|
||||
}
|
||||
|
@ -299,6 +311,43 @@ class ConfigController extends Controller
|
|||
$em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all tags for a given user and cleanup orphan tags.
|
||||
*
|
||||
* @param int $userId
|
||||
*/
|
||||
private function removeAllTagsByUserId($userId)
|
||||
{
|
||||
$tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($userId);
|
||||
$this->removeAllTagsByStatusAndUserId($tags, $userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all tags for a given user and cleanup orphan tags.
|
||||
*
|
||||
* @param int $userId
|
||||
*/
|
||||
private function removeTagsForArchivedByUserId($userId)
|
||||
{
|
||||
$tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findForArchivedArticlesByUser($userId);
|
||||
$this->removeAllTagsByStatusAndUserId($tags, $userId);
|
||||
}
|
||||
|
||||
private function removeAnnotationsForArchivedByUserId($userId)
|
||||
{
|
||||
$em = $this->getDoctrine()->getManager();
|
||||
|
||||
$archivedEntriesAnnotations = $this->getDoctrine()
|
||||
->getRepository('WallabagAnnotationBundle:Annotation')
|
||||
->findAllArchivedEntriesByUser($userId);
|
||||
|
||||
foreach ($archivedEntriesAnnotations as $archivedEntriesAnnotation) {
|
||||
$em->remove($archivedEntriesAnnotation);
|
||||
}
|
||||
|
||||
$em->flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that a rule can be edited/deleted by the current user.
|
||||
*
|
||||
|
|
|
@ -371,4 +371,12 @@ class EntryRepository extends EntityRepository
|
|||
->setParameter('userId', $userId)
|
||||
->execute();
|
||||
}
|
||||
|
||||
public function removeArchivedByUserId($userId)
|
||||
{
|
||||
$this->getEntityManager()
|
||||
->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = :userId AND e.isArchived = TRUE')
|
||||
->setParameter('userId', $userId)
|
||||
->execute();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,4 +76,24 @@ class TagRepository extends EntityRepository
|
|||
->getQuery()
|
||||
->getSingleResult();
|
||||
}
|
||||
|
||||
public function findForArchivedArticlesByUser($userId)
|
||||
{
|
||||
$ids = $this->createQueryBuilder('t')
|
||||
->select('t.id')
|
||||
->leftJoin('t.entries', 'e')
|
||||
->where('e.user = :userId')->setParameter('userId', $userId)
|
||||
->andWhere('e.isArchived = true')
|
||||
->groupBy('t.id')
|
||||
->orderBy('t.slug')
|
||||
->getQuery()
|
||||
->getArrayResult();
|
||||
|
||||
$tags = [];
|
||||
foreach ($ids as $id) {
|
||||
$tags[] = $this->find($id);
|
||||
}
|
||||
|
||||
return $tags;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
# annotations: Remove ALL annotations
|
||||
# tags: Remove ALL tags
|
||||
# entries: Remove ALL entries
|
||||
# archived: Remove ALL archived entries
|
||||
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
|
||||
form_password:
|
||||
# description: "You can change your password here. Your new password should by at least 8 characters long."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
# annotations_reset: Annotations reset
|
||||
# tags_reset: Tags reset
|
||||
# entries_reset: Entries reset
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
# entry_already_saved: 'Entry already saved on %date%'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
annotations: Entferne ALLE Annotationen
|
||||
tags: Entferne ALLE Tags
|
||||
entries: Entferne ALLE Einträge
|
||||
# archived: Remove ALL archived entries
|
||||
confirm: Bist du wirklich sicher? (DIES KANN NICHT RÜCKGÄNGIG GEMACHT WERDEN)
|
||||
form_password:
|
||||
description: "Hier kannst du dein Kennwort ändern. Dieses sollte mindestens acht Zeichen enthalten."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
annotations_reset: Anmerkungen zurücksetzen
|
||||
tags_reset: Tags zurücksetzen
|
||||
entries_reset: Einträge zurücksetzen
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'Eintrag bereits am %date% gespeichert'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
annotations: Remove ALL annotations
|
||||
tags: Remove ALL tags
|
||||
entries: Remove ALL entries
|
||||
archived: Remove ALL archived entries
|
||||
confirm: Are you really sure? (THIS CAN'T BE UNDONE)
|
||||
form_password:
|
||||
description: "You can change your password here. Your new password should by at least 8 characters long."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
annotations_reset: Annotations reset
|
||||
tags_reset: Tags reset
|
||||
entries_reset: Entries reset
|
||||
archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'Entry already saved on %date%'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
annotations: Eliminar TODAS las anotaciones
|
||||
tags: Eliminar TODAS las etiquetas
|
||||
entries: Eliminar TODOS los artículos
|
||||
# archived: Remove ALL archived entries
|
||||
confirm: ¿Estás completamente seguro? (NO SE PUEDE DESHACER)
|
||||
form_password:
|
||||
description: "Puedes cambiar la contraseña aquí. Tu nueva contraseña debe tener al menos 8 caracteres."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
annotations_reset: Anotaciones reiniciadas
|
||||
tags_reset: Etiquetas reiniciadas
|
||||
entries_reset: Artículos reiniciados
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'Artículo ya guardado el %fecha%'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
# annotations: Remove ALL annotations
|
||||
# tags: Remove ALL tags
|
||||
# entries: Remove ALL entries
|
||||
# archived: Remove ALL archived entries
|
||||
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
|
||||
form_password:
|
||||
# description: "You can change your password here. Your new password should by at least 8 characters long."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
# annotations_reset: Annotations reset
|
||||
# tags_reset: Tags reset
|
||||
# entries_reset: Entries reset
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'این مقاله در تاریخ %date% ذخیره شده بود'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
annotations: Supprimer TOUTES les annotations
|
||||
tags: Supprimer TOUS les tags
|
||||
entries: Supprimer TOUS les articles
|
||||
archived: Supprimer TOUS les articles archivés
|
||||
confirm: Êtes-vous vraiment vraiment sûr ? (C'EST IRRÉVERSIBLE)
|
||||
form_password:
|
||||
description: "Vous pouvez changer ici votre mot de passe. Le mot de passe doit contenir au moins 8 caractères."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
annotations_reset: Annotations supprimées
|
||||
tags_reset: Tags supprimés
|
||||
entries_reset: Articles supprimés
|
||||
archived_reset: Articles archivés supprimés
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: "Article déjà sauvegardé le %date%"
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
# annotations: Remove ALL annotations
|
||||
# tags: Remove ALL tags
|
||||
# entries: Remove ALL entries
|
||||
# archived: Remove ALL archived entries
|
||||
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
|
||||
form_password:
|
||||
# description: "You can change your password here. Your new password should by at least 8 characters long."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
# annotations_reset: Annotations reset
|
||||
# tags_reset: Tags reset
|
||||
# entries_reset: Entries reset
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'Contenuto già salvato in data %date%'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
annotations: Levar TOTAS las anotacions
|
||||
tags: Levar TOTAS las etiquetas
|
||||
entries: Levar TOTES los articles
|
||||
# archived: Remove ALL archived entries
|
||||
confirm: Sètz vertadièrament segur ? (ES IRREVERSIBLE)
|
||||
form_password:
|
||||
description: "Podètz cambiar vòstre senhal aquí. Vòstre senhal deu èsser long d'almens 8 caractèrs."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
annotations_reset: Anotacions levadas
|
||||
tags_reset: Etiquetas levadas
|
||||
entries_reset: Articles levats
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'Article ja salvargardat lo %date%'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
annotations: Usuń WSZYSTKIE adnotacje
|
||||
tags: Usuń WSZYSTKIE tagi
|
||||
entries: usuń WSZYTSTKIE wpisy
|
||||
# archived: Remove ALL archived entries
|
||||
confirm: Jesteś pewien? (tej operacji NIE MOŻNA cofnąć)
|
||||
form_password:
|
||||
description: "Tutaj możesz zmienić swoje hasło. Twoje nowe hasło powinno mieć conajmniej 8 znaków."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
annotations_reset: Zresetuj adnotacje
|
||||
tags_reset: Zresetuj tagi
|
||||
entries_reset: Zresetuj wpisy
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'Wpis już został dodany %date%'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
# annotations: Remove ALL annotations
|
||||
# tags: Remove ALL tags
|
||||
# entries: Remove ALL entries
|
||||
# archived: Remove ALL archived entries
|
||||
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
|
||||
form_password:
|
||||
# description: "You can change your password here. Your new password should by at least 8 characters long."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
# annotations_reset: Annotations reset
|
||||
# tags_reset: Tags reset
|
||||
# entries_reset: Entries reset
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'Entrada já foi salva em %date%'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
# annotations: Remove ALL annotations
|
||||
# tags: Remove ALL tags
|
||||
# entries: Remove ALL entries
|
||||
# archived: Remove ALL archived entries
|
||||
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
|
||||
form_password:
|
||||
# description: "You can change your password here. Your new password should by at least 8 characters long."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
# annotations_reset: Annotations reset
|
||||
# tags_reset: Tags reset
|
||||
# entries_reset: Entries reset
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
# entry_already_saved: 'Entry already saved on %date%'
|
||||
|
|
|
@ -110,6 +110,7 @@ config:
|
|||
# annotations: Remove ALL annotations
|
||||
# tags: Remove ALL tags
|
||||
# entries: Remove ALL entries
|
||||
# archived: Remove ALL archived entries
|
||||
# confirm: Are you really really sure? (THIS CAN'T BE UNDONE)
|
||||
form_password:
|
||||
# description: "You can change your password here. Your new password should by at least 8 characters long."
|
||||
|
@ -528,6 +529,7 @@ flashes:
|
|||
# annotations_reset: Annotations reset
|
||||
# tags_reset: Tags reset
|
||||
# entries_reset: Entries reset
|
||||
# archived_reset: Archived entries deleted
|
||||
entry:
|
||||
notice:
|
||||
entry_already_saved: 'Entry already saved on %date%'
|
||||
|
|
|
@ -199,6 +199,11 @@
|
|||
{{ 'config.reset.tags'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('config_reset', { type: 'archived'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
|
||||
{{ 'config.reset.archived'|trans }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="{{ path('config_reset', { type: 'entries'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
|
||||
{{ 'config.reset.entries'|trans }}
|
||||
|
|
|
@ -229,6 +229,9 @@
|
|||
<a href="{{ path('config_reset', { type: 'tags'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
|
||||
{{ 'config.reset.tags'|trans }}
|
||||
</a>
|
||||
<a href="{{ path('config_reset', { type: 'archived'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
|
||||
{{ 'config.reset.archived'|trans }}
|
||||
</a>
|
||||
<a href="{{ path('config_reset', { type: 'entries'}) }}" onclick="return confirm('{{ 'config.reset.confirm'|trans|escape('js') }}')" class="waves-effect waves-light btn red">
|
||||
{{ 'config.reset.entries'|trans }}
|
||||
</a>
|
||||
|
|
|
@ -803,6 +803,82 @@ class ConfigControllerTest extends WallabagCoreTestCase
|
|||
$this->assertEquals(0, $entryReset, 'Entries were reset');
|
||||
}
|
||||
|
||||
public function testResetArchivedEntries()
|
||||
{
|
||||
$this->logInAs('empty');
|
||||
$client = $this->getClient();
|
||||
|
||||
$em = $client->getContainer()->get('doctrine.orm.entity_manager');
|
||||
|
||||
$user = static::$kernel->getContainer()->get('security.token_storage')->getToken()->getUser();
|
||||
|
||||
$tag = new Tag();
|
||||
$tag->setLabel('super');
|
||||
$em->persist($tag);
|
||||
|
||||
$entry = new Entry($user);
|
||||
$entry->setUrl('http://www.lemonde.fr/europe/article/2016/10/01/pour-le-psoe-chaque-election-s-est-transformee-en-une-agonie_5006476_3214.html');
|
||||
$entry->setContent('Youhou');
|
||||
$entry->setTitle('Youhou');
|
||||
$entry->addTag($tag);
|
||||
$em->persist($entry);
|
||||
|
||||
$annotation = new Annotation($user);
|
||||
$annotation->setText('annotated');
|
||||
$annotation->setQuote('annotated');
|
||||
$annotation->setRanges([]);
|
||||
$annotation->setEntry($entry);
|
||||
$em->persist($annotation);
|
||||
|
||||
$tagArchived = new Tag();
|
||||
$tagArchived->setLabel('super');
|
||||
$em->persist($tagArchived);
|
||||
|
||||
$entryArchived = new Entry($user);
|
||||
$entryArchived->setUrl('http://www.lemonde.fr/europe/article/2016/10/01/pour-le-psoe-chaque-election-s-est-transformee-en-une-agonie_5006476_3214.html');
|
||||
$entryArchived->setContent('Youhou');
|
||||
$entryArchived->setTitle('Youhou');
|
||||
$entryArchived->addTag($tagArchived);
|
||||
$entryArchived->setArchived(true);
|
||||
$em->persist($entryArchived);
|
||||
|
||||
$annotationArchived = new Annotation($user);
|
||||
$annotationArchived->setText('annotated');
|
||||
$annotationArchived->setQuote('annotated');
|
||||
$annotationArchived->setRanges([]);
|
||||
$annotationArchived->setEntry($entryArchived);
|
||||
$em->persist($annotationArchived);
|
||||
|
||||
$em->flush();
|
||||
|
||||
$crawler = $client->request('GET', '/config#set3');
|
||||
|
||||
$this->assertEquals(200, $client->getResponse()->getStatusCode());
|
||||
|
||||
$crawler = $client->click($crawler->selectLink('config.reset.archived')->link());
|
||||
|
||||
$this->assertEquals(302, $client->getResponse()->getStatusCode());
|
||||
$this->assertContains('flashes.config.notice.archived_reset', $client->getContainer()->get('session')->getFlashBag()->get('notice')[0]);
|
||||
|
||||
$entryReset = $em
|
||||
->getRepository('WallabagCoreBundle:Entry')
|
||||
->countAllEntriesByUser($user->getId());
|
||||
|
||||
$this->assertEquals(1, $entryReset, 'Entries were reset');
|
||||
|
||||
$tagReset = $em
|
||||
->getRepository('WallabagCoreBundle:Tag')
|
||||
->countAllTags($user->getId());
|
||||
|
||||
$this->assertEquals(1, $tagReset, 'Tags were reset');
|
||||
|
||||
$annotationsReset = $em
|
||||
->getRepository('WallabagAnnotationBundle:Annotation')
|
||||
->findAnnotationsByPageId($annotationArchived->getId(), $user->getId());
|
||||
|
||||
$this->assertEmpty($annotationsReset, 'Annotations were reset');
|
||||
}
|
||||
|
||||
public function testResetEntriesCascade()
|
||||
{
|
||||
$this->logInAs('empty');
|
||||
|
|
Loading…
Reference in a new issue