aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/Wallabag
diff options
context:
space:
mode:
authorJeremy Benoist <jeremy.benoist@gmail.com>2016-10-01 14:01:13 +0200
committerJeremy Benoist <jeremy.benoist@gmail.com>2016-10-22 13:13:07 +0200
commit191564b7f71d01fb4c597c9b9641e23db564278d (patch)
tree1cf81a2474d064f11663c70bd77121fc3c4c69a1 /src/Wallabag
parent98efffc2a62820bad347a0f93840c48fa57f8cc3 (diff)
downloadwallabag-191564b7f71d01fb4c597c9b9641e23db564278d.tar.gz
wallabag-191564b7f71d01fb4c597c9b9641e23db564278d.tar.zst
wallabag-191564b7f71d01fb4c597c9b9641e23db564278d.zip
Add custom doctrine subscriber for SQLite
Since SQLite doesn’t handle cascade remove by default, we need to handle it manually. Also some refacto
Diffstat (limited to 'src/Wallabag')
-rw-r--r--src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php13
-rw-r--r--src/Wallabag/CoreBundle/Controller/ConfigController.php41
-rw-r--r--src/Wallabag/CoreBundle/Repository/EntryRepository.php13
-rw-r--r--src/Wallabag/CoreBundle/Resources/config/services.yml18
-rw-r--r--src/Wallabag/CoreBundle/Subscriber/SQLiteCascadeDeleteSubscriber.php70
5 files changed, 144 insertions, 11 deletions
diff --git a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php
index 5f7da70e..d999dc0f 100644
--- a/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php
+++ b/src/Wallabag/AnnotationBundle/Repository/AnnotationRepository.php
@@ -106,4 +106,17 @@ class AnnotationRepository extends EntityRepository
106 ->getQuery() 106 ->getQuery()
107 ->getSingleResult(); 107 ->getSingleResult();
108 } 108 }
109
110 /**
111 * Remove all annotations for a user id.
112 * Used when a user want to reset all informations
113 *
114 * @param int $userId
115 */
116 public function removeAllByUserId($userId)
117 {
118 $this->getEntityManager()
119 ->createQuery('DELETE FROM Wallabag\AnnotationBundle\Entity\Annotation a WHERE a.user = '.$userId)
120 ->execute();
121 }
109} 122}
diff --git a/src/Wallabag/CoreBundle/Controller/ConfigController.php b/src/Wallabag/CoreBundle/Controller/ConfigController.php
index ccbf550a..faa85d16 100644
--- a/src/Wallabag/CoreBundle/Controller/ConfigController.php
+++ b/src/Wallabag/CoreBundle/Controller/ConfigController.php
@@ -237,25 +237,26 @@ class ConfigController extends Controller
237 237
238 switch ($type) { 238 switch ($type) {
239 case 'annotations': 239 case 'annotations':
240 $em->createQuery('DELETE FROM Wallabag\AnnotationBundle\Entity\Annotation a WHERE a.user = '.$this->getUser()->getId()) 240 $this->getDoctrine()
241 ->execute(); 241 ->getRepository('WallabagAnnotationBundle:Annotation')
242 ->removeAllByUserId($this->getUser()->getId());
242 break; 243 break;
243 244
244 case 'tags': 245 case 'tags':
245 $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($this->getUser()->getId()); 246 $this->removeAllTagsByUserId($this->getUser()->getId());
247 break;
246 248
247 if (empty($tags)) { 249 case 'entries':
248 break; 250 // SQLite doesn't care about cascading remove, so we need to manually remove associated stuf
251 // otherwise they won't be removed ...
252 if ($this->get('doctrine')->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver) {
253 $this->getDoctrine()->getRepository('WallabagAnnotationBundle:Annotation')->removeAllByUserId($this->getUser()->getId());
254 $this->removeAllTagsByUserId($this->getUser()->getId());
249 } 255 }
250 256
251 $this->getDoctrine() 257 $this->getDoctrine()
252 ->getRepository('WallabagCoreBundle:Entry') 258 ->getRepository('WallabagCoreBundle:Entry')
253 ->removeTags($this->getUser()->getId(), $tags); 259 ->removeAllByUserId($this->getUser()->getId());
254 break;
255
256 case 'entries':
257 $em->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = '.$this->getUser()->getId())
258 ->execute();
259 } 260 }
260 261
261 $this->get('session')->getFlashBag()->add( 262 $this->get('session')->getFlashBag()->add(
@@ -267,6 +268,24 @@ class ConfigController extends Controller
267 } 268 }
268 269
269 /** 270 /**
271 * Remove all tags for a given user.
272 *
273 * @param int $userId
274 */
275 private function removeAllTagsByUserId($userId)
276 {
277 $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($userId);
278
279 if (empty($tags)) {
280 return;
281 }
282
283 $this->getDoctrine()
284 ->getRepository('WallabagCoreBundle:Entry')
285 ->removeTags($userId, $tags);
286 }
287
288 /**
270 * Validate that a rule can be edited/deleted by the current user. 289 * Validate that a rule can be edited/deleted by the current user.
271 * 290 *
272 * @param TaggingRule $rule 291 * @param TaggingRule $rule
diff --git a/src/Wallabag/CoreBundle/Repository/EntryRepository.php b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
index cd2b47b9..8704a2a6 100644
--- a/src/Wallabag/CoreBundle/Repository/EntryRepository.php
+++ b/src/Wallabag/CoreBundle/Repository/EntryRepository.php
@@ -329,4 +329,17 @@ class EntryRepository extends EntityRepository
329 329
330 return $qb->getQuery()->getSingleScalarResult(); 330 return $qb->getQuery()->getSingleScalarResult();
331 } 331 }
332
333 /**
334 * Remove all entries for a user id.
335 * Used when a user want to reset all informations
336 *
337 * @param int $userId
338 */
339 public function removeAllByUserId($userId)
340 {
341 $this->getEntityManager()
342 ->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = '.$userId)
343 ->execute();
344 }
332} 345}
diff --git a/src/Wallabag/CoreBundle/Resources/config/services.yml b/src/Wallabag/CoreBundle/Resources/config/services.yml
index a4b727f4..540d21f1 100644
--- a/src/Wallabag/CoreBundle/Resources/config/services.yml
+++ b/src/Wallabag/CoreBundle/Resources/config/services.yml
@@ -88,6 +88,17 @@ services:
88 arguments: 88 arguments:
89 - WallabagCoreBundle:Tag 89 - WallabagCoreBundle:Tag
90 90
91 wallabag_core.listener.registration_confirmed:
92 class: Wallabag\CoreBundle\EventListener\RegistrationConfirmedListener
93 arguments:
94 - "@doctrine.orm.entity_manager"
95 - "%wallabag_core.theme%"
96 - "%wallabag_core.items_on_page%"
97 - "%wallabag_core.rss_limit%"
98 - "%wallabag_core.language%"
99 tags:
100 - { name: kernel.event_subscriber }
101
91 wallabag_core.helper.entries_export: 102 wallabag_core.helper.entries_export:
92 class: Wallabag\CoreBundle\Helper\EntriesExport 103 class: Wallabag\CoreBundle\Helper\EntriesExport
93 arguments: 104 arguments:
@@ -129,3 +140,10 @@ services:
129 arguments: 140 arguments:
130 - '@twig' 141 - '@twig'
131 - '%kernel.debug%' 142 - '%kernel.debug%'
143
144 wallabag_core.subscriber.sqlite_cascade_delete:
145 class: Wallabag\CoreBundle\Subscriber\SQLiteCascadeDeleteSubscriber
146 arguments:
147 - "@doctrine"
148 tags:
149 - { name: doctrine.event_subscriber }
diff --git a/src/Wallabag/CoreBundle/Subscriber/SQLiteCascadeDeleteSubscriber.php b/src/Wallabag/CoreBundle/Subscriber/SQLiteCascadeDeleteSubscriber.php
new file mode 100644
index 00000000..d5180577
--- /dev/null
+++ b/src/Wallabag/CoreBundle/Subscriber/SQLiteCascadeDeleteSubscriber.php
@@ -0,0 +1,70 @@
1<?php
2namespace Wallabag\CoreBundle\Subscriber;
3
4use Doctrine\Common\EventSubscriber;
5use Doctrine\ORM\EntityManager;
6use Doctrine\ORM\Event\LifecycleEventArgs;
7use Wallabag\CoreBundle\Entity\Entry;
8use Doctrine\Bundle\DoctrineBundle\Registry;
9
10/**
11 * SQLite doesn't care about cascading remove, so we need to manually remove associated stuf for an Entry.
12 * Foreign Key Support can be enabled by running `PRAGMA foreign_keys = ON;` at runtime (AT RUNTIME !).
13 * But it needs a compilation flag that not all SQLite instance has ...
14 *
15 * @see https://www.sqlite.org/foreignkeys.html#fk_enable
16 */
17class SQLiteCascadeDeleteSubscriber implements EventSubscriber
18{
19 private $doctrine;
20
21 /**
22 * @param \Doctrine\Bundle\DoctrineBundle\Registry $doctrine
23 */
24 public function __construct(Registry $doctrine)
25 {
26 $this->doctrine = $doctrine;
27 }
28
29 /**
30 * @return array
31 */
32 public function getSubscribedEvents()
33 {
34 return [
35 'preRemove',
36 ];
37 }
38
39 /**
40 * We removed everything related to the upcoming removed entry because SQLite can't handle it on it own.
41 * We do it in the preRemove, because we can't retrieve tags in the postRemove (because the entry id is gone)
42 *
43 * @param LifecycleEventArgs $args
44 */
45 public function preRemove(LifecycleEventArgs $args)
46 {
47 $entity = $args->getEntity();
48
49 if (!$this->doctrine->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver ||
50 !$entity instanceof Entry) {
51 return;
52 }
53
54 $em = $this->doctrine->getManager();
55
56 if (null !== $entity->getTags()) {
57 foreach ($entity->getTags() as $tag) {
58 $entity->removeTag($tag);
59 }
60 }
61
62 if (null !== $entity->getAnnotations()) {
63 foreach ($entity->getAnnotations() as $annotation) {
64 $em->remove($annotation);
65 }
66 }
67
68 $em->flush();
69 }
70}