mirror of
https://github.com/wallabag/wallabag.git
synced 2024-12-28 10:30:28 +00:00
Add custom doctrine subscriber for SQLite
Since SQLite doesn’t handle cascade remove by default, we need to handle it manually. Also some refacto
This commit is contained in:
parent
98efffc2a6
commit
191564b7f7
5 changed files with 144 additions and 11 deletions
|
@ -106,4 +106,17 @@ class AnnotationRepository extends EntityRepository
|
|||
->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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -237,25 +237,26 @@ class ConfigController extends Controller
|
|||
|
||||
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(
|
||||
|
@ -266,6 +267,24 @@ class ConfigController extends Controller
|
|||
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.
|
||||
*
|
||||
|
|
|
@ -329,4 +329,17 @@ class EntryRepository extends EntityRepository
|
|||
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -88,6 +88,17 @@ services:
|
|||
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:
|
||||
|
@ -129,3 +140,10 @@ services:
|
|||
arguments:
|
||||
- '@twig'
|
||||
- '%kernel.debug%'
|
||||
|
||||
wallabag_core.subscriber.sqlite_cascade_delete:
|
||||
class: Wallabag\CoreBundle\Subscriber\SQLiteCascadeDeleteSubscriber
|
||||
arguments:
|
||||
- "@doctrine"
|
||||
tags:
|
||||
- { name: doctrine.event_subscriber }
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
<?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();
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue