use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\CoreBundle\Entity\Tag;
use Wallabag\AnnotationBundle\Entity\Annotation;
+use Wallabag\CoreBundle\Event\EntrySavedEvent;
+use Wallabag\CoreBundle\Event\EntryDeletedEvent;
class WallabagRestController extends FOSRestController
{
$em = $this->getDoctrine()->getManager();
$em->persist($entry);
-
$em->flush();
+ // entry saved, dispatch event about it!
+ $this->get('event_dispatcher')->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
+
$json = $this->get('serializer')->serialize($entry, 'json');
return (new JsonResponse())->setJson($json);
$this->validateAuthentication();
$this->validateUserAccess($entry->getUser()->getId());
+ // entry deleted, dispatch event about it!
+ $this->get('event_dispatcher')->dispatch(EntryDeletedEvent::NAME, new EntryDeletedEvent($entry));
+
$em = $this->getDoctrine()->getManager();
$em->remove($entry);
$em->flush();
use Wallabag\CoreBundle\Entity\Tag;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Wallabag\CoreBundle\Event\EntrySavedEvent;
abstract class AbstractConsumer
{
protected $import;
protected $logger;
- public function __construct(EntityManager $em, UserRepository $userRepository, AbstractImport $import, LoggerInterface $logger = null)
+ public function __construct(EntityManager $em, UserRepository $userRepository, AbstractImport $import, EventDispatcherInterface $eventDispatcher, LoggerInterface $logger = null)
{
$this->em = $em;
$this->userRepository = $userRepository;
$this->import = $import;
+ $this->eventDispatcher = $eventDispatcher;
$this->logger = $logger ?: new NullLogger();
}
try {
$this->em->flush();
+ // entry saved, dispatch event about it!
+ $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
+
// clear only affected entities
$this->em->clear(Entry::class);
$this->em->clear(Tag::class);
use Wallabag\CoreBundle\Entity\Tag;
use Wallabag\UserBundle\Entity\User;
use OldSound\RabbitMqBundle\RabbitMq\ProducerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Wallabag\CoreBundle\Event\EntrySavedEvent;
abstract class AbstractImport implements ImportInterface
{
protected $em;
protected $logger;
protected $contentProxy;
+ protected $eventDispatcher;
protected $producer;
protected $user;
protected $markAsRead;
protected $importedEntries = 0;
protected $queuedEntries = 0;
- public function __construct(EntityManager $em, ContentProxy $contentProxy)
+ public function __construct(EntityManager $em, ContentProxy $contentProxy, EventDispatcherInterface $eventDispatcher)
{
$this->em = $em;
$this->logger = new NullLogger();
$this->contentProxy = $contentProxy;
+ $this->eventDispatcher = $eventDispatcher;
}
public function setLogger(LoggerInterface $logger)
protected function parseEntries($entries)
{
$i = 1;
+ $entryToBeFlushed = [];
foreach ($entries as $importedEntry) {
if ($this->markAsRead) {
continue;
}
+ // store each entry to be flushed so we can trigger the entry.saved event for each of them
+ // entry.saved needs the entry to be persisted in db because it needs it id to generate
+ // images (at least)
+ $entryToBeFlushed[] = $entry;
+
// flush every 20 entries
if (($i % 20) === 0) {
$this->em->flush();
+ foreach ($entryToBeFlushed as $entry) {
+ $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
+ }
+
+ $entryToBeFlushed = [];
+
// clear only affected entities
$this->em->clear(Entry::class);
$this->em->clear(Tag::class);
}
$this->em->flush();
+
+ if (!empty($entryToBeFlushed)) {
+ foreach ($entryToBeFlushed as $entry) {
+ $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
+ }
+ }
}
/**
use Wallabag\CoreBundle\Entity\Entry;
use Wallabag\UserBundle\Entity\User;
use Wallabag\CoreBundle\Helper\ContentProxy;
+use Wallabag\CoreBundle\Event\EntrySavedEvent;
abstract class BrowserImport extends AbstractImport
{
protected function parseEntries($entries)
{
$i = 1;
+ $entryToBeFlushed = [];
foreach ($entries as $importedEntry) {
if ((array) $importedEntry !== $importedEntry) {
continue;
}
+ // @see AbstractImport
+ $entryToBeFlushed[] = $entry;
+
// flush every 20 entries
if (($i % 20) === 0) {
$this->em->flush();
+
+ foreach ($entryToBeFlushed as $entry) {
+ $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
+ }
+
+ $entryToBeFlushed = [];
}
++$i;
}
$this->em->flush();
+
+ if (!empty($entryToBeFlushed)) {
+ foreach ($entryToBeFlushed as $entry) {
+ $this->eventDispatcher->dispatch(EntrySavedEvent::NAME, new EntrySavedEvent($entry));
+ }
+ }
}
/**
const NB_ELEMENTS = 5000;
- public function __construct(EntityManager $em, ContentProxy $contentProxy)
- {
- $this->em = $em;
- $this->contentProxy = $contentProxy;
- $this->logger = new NullLogger();
- }
-
/**
* Only used for test purpose.
*
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.pocket.import"
+ - "@event_dispatcher"
- "@logger"
wallabag_import.consumer.amqp.readability:
class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.readability.import"
+ - "@event_dispatcher"
- "@logger"
wallabag_import.consumer.amqp.instapaper:
class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.instapaper.import"
+ - "@event_dispatcher"
- "@logger"
wallabag_import.consumer.amqp.wallabag_v1:
class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.wallabag_v1.import"
+ - "@event_dispatcher"
- "@logger"
wallabag_import.consumer.amqp.wallabag_v2:
class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.wallabag_v2.import"
+ - "@event_dispatcher"
- "@logger"
wallabag_import.consumer.amqp.firefox:
class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.firefox.import"
+ - "@event_dispatcher"
- "@logger"
wallabag_import.consumer.amqp.chrome:
class: Wallabag\ImportBundle\Consumer\AMQPEntryConsumer
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.chrome.import"
+ - "@event_dispatcher"
- "@logger"
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.readability.import"
+ - "@event_dispatcher"
- "@logger"
# instapaper
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.instapaper.import"
+ - "@event_dispatcher"
- "@logger"
# pocket
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.pocket.import"
+ - "@event_dispatcher"
- "@logger"
# wallabag v1
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.wallabag_v1.import"
+ - "@event_dispatcher"
- "@logger"
# wallabag v2
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.wallabag_v2.import"
+ - "@event_dispatcher"
- "@logger"
# firefox
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.firefox.import"
+ - "@event_dispatcher"
- "@logger"
# chrome
- "@doctrine.orm.entity_manager"
- "@wallabag_user.user_repository"
- "@wallabag_import.chrome.import"
+ - "@event_dispatcher"
- "@logger"
arguments:
- "@doctrine.orm.entity_manager"
- "@wallabag_core.content_proxy"
+ - "@event_dispatcher"
calls:
- [ setClient, [ "@wallabag_import.pocket.client" ] ]
- [ setLogger, [ "@logger" ]]
arguments:
- "@doctrine.orm.entity_manager"
- "@wallabag_core.content_proxy"
+ - "@event_dispatcher"
calls:
- [ setLogger, [ "@logger" ]]
tags:
arguments:
- "@doctrine.orm.entity_manager"
- "@wallabag_core.content_proxy"
+ - "@event_dispatcher"
calls:
- [ setLogger, [ "@logger" ]]
tags:
arguments:
- "@doctrine.orm.entity_manager"
- "@wallabag_core.content_proxy"
+ - "@event_dispatcher"
calls:
- [ setLogger, [ "@logger" ]]
tags:
arguments:
- "@doctrine.orm.entity_manager"
- "@wallabag_core.content_proxy"
+ - "@event_dispatcher"
calls:
- [ setLogger, [ "@logger" ]]
tags:
arguments:
- "@doctrine.orm.entity_manager"
- "@wallabag_core.content_proxy"
+ - "@event_dispatcher"
calls:
- [ setLogger, [ "@logger" ]]
tags:
arguments:
- "@doctrine.orm.entity_manager"
- "@wallabag_core.content_proxy"
+ - "@event_dispatcher"
calls:
- [ setLogger, [ "@logger" ]]
tags:
->with(json_decode($body, true))
->willReturn($entry);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->once())
+ ->method('dispatch');
+
$consumer = new AMQPEntryConsumer(
$em,
$userRepository,
- $import
+ $import,
+ $dispatcher
);
$message = new AMQPMessage($body);
->disableOriginalConstructor()
->getMock();
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->never())
+ ->method('dispatch');
+
$consumer = new AMQPEntryConsumer(
$em,
$userRepository,
- $import
+ $import,
+ $dispatcher
);
$message = new AMQPMessage($body);
->with(json_decode($body, true))
->willReturn(null);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->never())
+ ->method('dispatch');
+
$consumer = new AMQPEntryConsumer(
$em,
$userRepository,
- $import
+ $import,
+ $dispatcher
);
$message = new AMQPMessage($body);
->with(json_decode($body, true))
->willReturn($entry);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->once())
+ ->method('dispatch');
+
$consumer = new RedisEntryConsumer(
$em,
$userRepository,
- $import
+ $import,
+ $dispatcher
);
$res = $consumer->manage($body);
->disableOriginalConstructor()
->getMock();
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->never())
+ ->method('dispatch');
+
$consumer = new RedisEntryConsumer(
$em,
$userRepository,
- $import
+ $import,
+ $dispatcher
);
$res = $consumer->manage($body);
->with(json_decode($body, true))
->willReturn(null);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->never())
+ ->method('dispatch');
+
$consumer = new RedisEntryConsumer(
$em,
$userRepository,
- $import
+ $import,
+ $dispatcher
);
$res = $consumer->manage($body);
protected $logHandler;
protected $contentProxy;
- private function getChromeImport($unsetUser = false)
+ private function getChromeImport($unsetUser = false, $dispatched = 0)
{
$this->user = new User();
->disableOriginalConstructor()
->getMock();
- $wallabag = new ChromeImport($this->em, $this->contentProxy);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->exactly($dispatched))
+ ->method('dispatch');
+
+ $wallabag = new ChromeImport($this->em, $this->contentProxy, $dispatcher);
$this->logHandler = new TestHandler();
$logger = new Logger('test', [$this->logHandler]);
public function testImport()
{
- $chromeImport = $this->getChromeImport();
+ $chromeImport = $this->getChromeImport(false, 1);
$chromeImport->setFilepath(__DIR__.'/../fixtures/chrome-bookmarks');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
public function testImportAndMarkAllAsRead()
{
- $chromeImport = $this->getChromeImport();
+ $chromeImport = $this->getChromeImport(false, 1);
$chromeImport->setFilepath(__DIR__.'/../fixtures/chrome-bookmarks');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
protected $logHandler;
protected $contentProxy;
- private function getFirefoxImport($unsetUser = false)
+ private function getFirefoxImport($unsetUser = false, $dispatched = 0)
{
$this->user = new User();
->disableOriginalConstructor()
->getMock();
- $wallabag = new FirefoxImport($this->em, $this->contentProxy);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->exactly($dispatched))
+ ->method('dispatch');
+
+ $wallabag = new FirefoxImport($this->em, $this->contentProxy, $dispatcher);
$this->logHandler = new TestHandler();
$logger = new Logger('test', [$this->logHandler]);
public function testImport()
{
- $firefoxImport = $this->getFirefoxImport();
+ $firefoxImport = $this->getFirefoxImport(false, 2);
$firefoxImport->setFilepath(__DIR__.'/../fixtures/firefox-bookmarks.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
public function testImportAndMarkAllAsRead()
{
- $firefoxImport = $this->getFirefoxImport();
+ $firefoxImport = $this->getFirefoxImport(false, 1);
$firefoxImport->setFilepath(__DIR__.'/../fixtures/firefox-bookmarks.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
protected $logHandler;
protected $contentProxy;
- private function getInstapaperImport($unsetUser = false)
+ private function getInstapaperImport($unsetUser = false, $dispatched = 0)
{
$this->user = new User();
->disableOriginalConstructor()
->getMock();
- $import = new InstapaperImport($this->em, $this->contentProxy);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->exactly($dispatched))
+ ->method('dispatch');
+
+ $import = new InstapaperImport($this->em, $this->contentProxy, $dispatcher);
$this->logHandler = new TestHandler();
$logger = new Logger('test', [$this->logHandler]);
public function testImport()
{
- $instapaperImport = $this->getInstapaperImport();
+ $instapaperImport = $this->getInstapaperImport(false, 3);
$instapaperImport->setFilepath(__DIR__.'/../fixtures/instapaper-export.csv');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
public function testImportAndMarkAllAsRead()
{
- $instapaperImport = $this->getInstapaperImport();
+ $instapaperImport = $this->getInstapaperImport(false, 1);
$instapaperImport->setFilepath(__DIR__.'/../fixtures/instapaper-export.csv');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
protected $contentProxy;
protected $logHandler;
- private function getPocketImport($consumerKey = 'ConsumerKey')
+ private function getPocketImport($consumerKey = 'ConsumerKey', $dispatched = 0)
{
$this->user = new User();
->method('getScheduledEntityInsertions')
->willReturn([]);
- $pocket = new PocketImport(
- $this->em,
- $this->contentProxy
- );
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->exactly($dispatched))
+ ->method('dispatch');
+
+ $pocket = new PocketImport($this->em, $this->contentProxy, $dispatcher);
$pocket->setUser($this->user);
$this->logHandler = new TestHandler();
$client->getEmitter()->attach($mock);
- $pocketImport = $this->getPocketImport();
+ $pocketImport = $this->getPocketImport('ConsumerKey', 1);
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
->disableOriginalConstructor()
$client->getEmitter()->attach($mock);
- $pocketImport = $this->getPocketImport();
+ $pocketImport = $this->getPocketImport('ConsumerKey', 2);
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
->disableOriginalConstructor()
$client->getEmitter()->attach($mock);
- $pocketImport = $this->getPocketImport();
+ $pocketImport = $this->getPocketImport('ConsumerKey', 1);
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
->disableOriginalConstructor()
protected $logHandler;
protected $contentProxy;
- private function getReadabilityImport($unsetUser = false)
+ private function getReadabilityImport($unsetUser = false, $dispatched = 0)
{
$this->user = new User();
->disableOriginalConstructor()
->getMock();
- $wallabag = new ReadabilityImport($this->em, $this->contentProxy);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->exactly($dispatched))
+ ->method('dispatch');
+
+ $wallabag = new ReadabilityImport($this->em, $this->contentProxy, $dispatcher);
$this->logHandler = new TestHandler();
$logger = new Logger('test', [$this->logHandler]);
public function testImport()
{
- $readabilityImport = $this->getReadabilityImport();
+ $readabilityImport = $this->getReadabilityImport(false, 24);
$readabilityImport->setFilepath(__DIR__.'/../fixtures/readability.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
public function testImportAndMarkAllAsRead()
{
- $readabilityImport = $this->getReadabilityImport();
+ $readabilityImport = $this->getReadabilityImport(false, 1);
$readabilityImport->setFilepath(__DIR__.'/../fixtures/readability-read.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
protected $logHandler;
protected $contentProxy;
- private function getWallabagV1Import($unsetUser = false)
+ private function getWallabagV1Import($unsetUser = false, $dispatched = 0)
{
$this->user = new User();
->disableOriginalConstructor()
->getMock();
- $wallabag = new WallabagV1Import($this->em, $this->contentProxy);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->exactly($dispatched))
+ ->method('dispatch');
+
+ $wallabag = new WallabagV1Import($this->em, $this->contentProxy, $dispatcher);
$this->logHandler = new TestHandler();
$logger = new Logger('test', [$this->logHandler]);
public function testImport()
{
- $wallabagV1Import = $this->getWallabagV1Import();
+ $wallabagV1Import = $this->getWallabagV1Import(false, 3);
$wallabagV1Import->setFilepath(__DIR__.'/../fixtures/wallabag-v1.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
public function testImportAndMarkAllAsRead()
{
- $wallabagV1Import = $this->getWallabagV1Import();
+ $wallabagV1Import = $this->getWallabagV1Import(false, 3);
$wallabagV1Import->setFilepath(__DIR__.'/../fixtures/wallabag-v1-read.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
protected $logHandler;
protected $contentProxy;
- private function getWallabagV2Import($unsetUser = false)
+ private function getWallabagV2Import($unsetUser = false, $dispatched = 0)
{
$this->user = new User();
->disableOriginalConstructor()
->getMock();
- $wallabag = new WallabagV2Import($this->em, $this->contentProxy);
+ $dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcher')
+ ->disableOriginalConstructor()
+ ->getMock();
+
+ $dispatcher
+ ->expects($this->exactly($dispatched))
+ ->method('dispatch');
+
+ $wallabag = new WallabagV2Import($this->em, $this->contentProxy, $dispatcher);
$this->logHandler = new TestHandler();
$logger = new Logger('test', [$this->logHandler]);
public function testImport()
{
- $wallabagV2Import = $this->getWallabagV2Import();
+ $wallabagV2Import = $this->getWallabagV2Import(false, 2);
$wallabagV2Import->setFilepath(__DIR__.'/../fixtures/wallabag-v2.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
public function testImportAndMarkAllAsRead()
{
- $wallabagV2Import = $this->getWallabagV2Import();
+ $wallabagV2Import = $this->getWallabagV2Import(false, 2);
$wallabagV2Import->setFilepath(__DIR__.'/../fixtures/wallabag-v2-read.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')
public function testImportWithExceptionFromGraby()
{
- $wallabagV2Import = $this->getWallabagV2Import();
+ $wallabagV2Import = $this->getWallabagV2Import(false, 2);
$wallabagV2Import->setFilepath(__DIR__.'/../fixtures/wallabag-v2.json');
$entryRepo = $this->getMockBuilder('Wallabag\CoreBundle\Repository\EntryRepository')