Since SQLite doesn’t handle cascade remove by default, we need to handle it manually.
Also some refacto
->getQuery()
->getSingleResult();
}
+
+ /**
+ * Remove all annotations for a user id.
+ * Used when a user want to reset all informations
+ *
+ * @param int $userId
+ */
+ public function removeAllByUserId($userId)
+ {
+ $this->getEntityManager()
+ ->createQuery('DELETE FROM Wallabag\AnnotationBundle\Entity\Annotation a WHERE a.user = '.$userId)
+ ->execute();
+ }
}
switch ($type) {
case 'annotations':
- $em->createQuery('DELETE FROM Wallabag\AnnotationBundle\Entity\Annotation a WHERE a.user = '.$this->getUser()->getId())
- ->execute();
+ $this->getDoctrine()
+ ->getRepository('WallabagAnnotationBundle:Annotation')
+ ->removeAllByUserId($this->getUser()->getId());
break;
case 'tags':
- $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($this->getUser()->getId());
+ $this->removeAllTagsByUserId($this->getUser()->getId());
+ break;
- if (empty($tags)) {
- break;
+ case 'entries':
+ // SQLite doesn't care about cascading remove, so we need to manually remove associated stuf
+ // 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());
+ $this->removeAllTagsByUserId($this->getUser()->getId());
}
$this->getDoctrine()
->getRepository('WallabagCoreBundle:Entry')
- ->removeTags($this->getUser()->getId(), $tags);
- break;
-
- case 'entries':
- $em->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = '.$this->getUser()->getId())
- ->execute();
+ ->removeAllByUserId($this->getUser()->getId());
}
$this->get('session')->getFlashBag()->add(
return $this->redirect($this->generateUrl('config').'#set3');
}
+ /**
+ * Remove all tags for a given user.
+ *
+ * @param int $userId
+ */
+ private function removeAllTagsByUserId($userId)
+ {
+ $tags = $this->getDoctrine()->getRepository('WallabagCoreBundle:Tag')->findAllTags($userId);
+
+ if (empty($tags)) {
+ return;
+ }
+
+ $this->getDoctrine()
+ ->getRepository('WallabagCoreBundle:Entry')
+ ->removeTags($userId, $tags);
+ }
+
/**
* Validate that a rule can be edited/deleted by the current user.
*
return $qb->getQuery()->getSingleScalarResult();
}
+
+ /**
+ * Remove all entries for a user id.
+ * Used when a user want to reset all informations
+ *
+ * @param int $userId
+ */
+ public function removeAllByUserId($userId)
+ {
+ $this->getEntityManager()
+ ->createQuery('DELETE FROM Wallabag\CoreBundle\Entity\Entry e WHERE e.user = '.$userId)
+ ->execute();
+ }
}
arguments:
- WallabagCoreBundle:Tag
+ wallabag_core.listener.registration_confirmed:
+ class: Wallabag\CoreBundle\EventListener\RegistrationConfirmedListener
+ arguments:
+ - "@doctrine.orm.entity_manager"
+ - "%wallabag_core.theme%"
+ - "%wallabag_core.items_on_page%"
+ - "%wallabag_core.rss_limit%"
+ - "%wallabag_core.language%"
+ tags:
+ - { name: kernel.event_subscriber }
+
wallabag_core.helper.entries_export:
class: Wallabag\CoreBundle\Helper\EntriesExport
arguments:
arguments:
- '@twig'
- '%kernel.debug%'
+
+ wallabag_core.subscriber.sqlite_cascade_delete:
+ class: Wallabag\CoreBundle\Subscriber\SQLiteCascadeDeleteSubscriber
+ arguments:
+ - "@doctrine"
+ tags:
+ - { name: doctrine.event_subscriber }
--- /dev/null
+<?php
+namespace Wallabag\CoreBundle\Subscriber;
+
+use Doctrine\Common\EventSubscriber;
+use Doctrine\ORM\EntityManager;
+use Doctrine\ORM\Event\LifecycleEventArgs;
+use Wallabag\CoreBundle\Entity\Entry;
+use Doctrine\Bundle\DoctrineBundle\Registry;
+
+/**
+ * SQLite doesn't care about cascading remove, so we need to manually remove associated stuf for an Entry.
+ * Foreign Key Support can be enabled by running `PRAGMA foreign_keys = ON;` at runtime (AT RUNTIME !).
+ * But it needs a compilation flag that not all SQLite instance has ...
+ *
+ * @see https://www.sqlite.org/foreignkeys.html#fk_enable
+ */
+class SQLiteCascadeDeleteSubscriber implements EventSubscriber
+{
+ private $doctrine;
+
+ /**
+ * @param \Doctrine\Bundle\DoctrineBundle\Registry $doctrine
+ */
+ public function __construct(Registry $doctrine)
+ {
+ $this->doctrine = $doctrine;
+ }
+
+ /**
+ * @return array
+ */
+ public function getSubscribedEvents()
+ {
+ return [
+ 'preRemove',
+ ];
+ }
+
+ /**
+ * We removed everything related to the upcoming removed entry because SQLite can't handle it on it own.
+ * We do it in the preRemove, because we can't retrieve tags in the postRemove (because the entry id is gone)
+ *
+ * @param LifecycleEventArgs $args
+ */
+ public function preRemove(LifecycleEventArgs $args)
+ {
+ $entity = $args->getEntity();
+
+ if (!$this->doctrine->getConnection()->getDriver() instanceof \Doctrine\DBAL\Driver\PDOSqlite\Driver ||
+ !$entity instanceof Entry) {
+ return;
+ }
+
+ $em = $this->doctrine->getManager();
+
+ if (null !== $entity->getTags()) {
+ foreach ($entity->getTags() as $tag) {
+ $entity->removeTag($tag);
+ }
+ }
+
+ if (null !== $entity->getAnnotations()) {
+ foreach ($entity->getAnnotations() as $annotation) {
+ $em->remove($annotation);
+ }
+ }
+
+ $em->flush();
+ }
+}